Корректная работа с событийной моделью на примере простого алгоритма
Доброго времени суток. Начал знакомиться с событийной моделью в S#.
Чтобы разобраться как все работает решил реализовать простой алгоритм, который выглядит следующим образом.
На вход дается два параметра CurrentMidPrice и Step.
Робот выставляет две заявки на куплю и на продажу (по цене CurrentPrice+Step и СurrentPrice-Step)
Далее если произошла сделка на покупку то оставшаяся заявка снимается, CurrentPrice-=Step и алгоритм повторяется. Если произошла сделка на продажу то CurrentPrice+=Step соответственно.
В моем понимании код стратегии выглядит примерно так:
Code
class Mesh:Strategy
{
public decimal Step;
public decimal CurrentMidPrice;
protected override void OnStarted()
{
Security.WhenMarketDepthChanged()
.Do(() => SetBidAskOrders(CurrentMidPrice))
.Once().Apply(this);
base.OnStarted();
}
public void SetBidAskOrders(decimal price)//выставляем спред шириной 2*Step вокруг цены price
{
var h = new SyncObject();
CancelActiveOrders();
var sellOrder = this.CreateOrder(OrderDirections.Sell, price + Step);
var buyOrder = this.CreateOrder(OrderDirections.Buy, price - Step);
sellOrder.WhenNewTrades()
.Sync(h)
.Do(t =>
{
CurrentMidPrice += Step;
SetBidAskOrders(CurrentMidPrice);
})
.Once().Apply(this);
buyOrder.WhenNewTrades()
.Sync(h)
.Do(t =>
{
CurrentMidPrice -= Step;
SetBidAskOrders(CurrentMidPrice);
})
.Once().Apply(this);
lock (h)
{
RegisterOrder(sellOrder);
RegisterOrder(buyOrder);
}
}
Теперь суть вопроса. В целом алгоритм работает как ему и положено но если выставить Step=минимальный шаг цены то из-за задержек. В какой-то момент он начинает множить заявки выставлять по 2-3 спреда и не отменять те заявки которые висят в терминале. Хотя CancelOrders ему полагается делать на каждую сделку.
Очевидно можно вводить флаги и останавливать работу всего алгоритма пока мы на каждый чих не получим возвратный чих от биржи, но я хотел бы в столь простом учебном примере обойтись без лишних костылей. вопрос какие вообще существуют пути решения проблемы транзакционости и синхронизации в такого рода роботах. Надо усложнять код или может я что-то проглядел в документации/подходах.
Спасибо.
(проверял на тестовом квике, есть плаза и это первое решение естественно но она не решает проблему устойчивости событийного алгоритма к задержкам)