При использовании EmulationTrader наблюдаются следующие проблемы (наблюдал на версия 4.1.7, но судя по сорцам проявиться и в 4.1.8)
Заявка отправляется в эмулятор.
Получает статус Active и после этого зависает (Не вызывает никаких событий, не исполняется и не отменяется).
При изучении логов наталкиваемся на сообщение
"Невозможно зарегистрировать заявку {0}: нет ни стаканов ни последней цены." Что выводит нас на код в MarketEmulator
Code
if (depth == null)
{
// без стакана маркетные(они всегда новые) и новые лимитные-в-рынок матчатся по посл. сделке
var last = si.LastTrade;
if (last != null && last.Price != 0)
{
EvaluateByLast(order, last);
//if (EvaluateByLast(order, last))
// return true;
}
else
{
// если нет никаких цен, то фэйл
ProcessError(order,action, new InvalidOperationException("Невозможно зарегистрировать заявку {0}: нет ни стаканов ни последней цены.".Put(order.TransactionId)));
si.Remove(newNode);
}
}
внутри функции: private void EvaluateNew(Order order, OrderTraceActions action) ( MarketEmulator.cs:1568 )
Здесь мы видим, что при наступлении некоторого условия, пытаемся сделать статус заявки Fail.
Далее смотрим кто вызывает эту функцию. Вызывается она в одном единственном месте. Там написано, что то типа:
Code
if (state.State != OrderStates.Active)
throw new InvalidOperationException("State!=Active");
EvaluateNew(state, action);
Что наталкивает нас на мысль, что при выполнении верхнего участка кода статус заявки ВСЕГДА будет Active. Что при выполнении ветки
Code
else
{
// если нет никаких цен, то фэйл
ProcessError(order,action, new InvalidOperationException("Невозможно зарегистрировать заявку {0}: нет ни стаканов ни последней цены.".Put(order.TransactionId)));
si.Remove(newNode);
}
Приведет к тому, что мы попытаемся Active заявку перевести в состояние Fail что противоречит логике работы объекта Order (и что выливается в ошибки при ее обработке объектом Strategy и т.п.)
Предлагаю правку:
Код MarketEmulator
Code
private void EvaluateNew(Order order, OrderTraceActions action)
{
var si = GetSecurityAuction(order.Security);
var newNode = si.PutInQueue(order); // запоминаем тк надо сделки потом сводить по этим заявкам
try
{
var depth = si.GetDepth(si);
if (EvaluateConditional(depth, order))
return/* true*/;
if (EvaluateByDepth(order, depth, true))
return/* true*/;
if (depth == null)
{
// без стакана маркетные(они всегда новые) и новые лимитные-в-рынок матчатся по посл. сделке
var last = si.LastTrade;
if (last != null && last.Price != 0)
{
EvaluateByLast(order, last);
//if (EvaluateByLast(order, last))
// return true;
}
else
{
// если нет никаких цен, то фэйл
ProcessError(order,action, new InvalidOperationException("Невозможно зарегистрировать заявку {0}: нет ни стаканов ни последней цены.".Put(order.TransactionId)));
si.Remove(newNode);
}
}
}
catch (Exception e)
{
ProcessDataError(e);
}
//return false;
}
заменить на
Code
private void EvaluateNew(Order order, OrderTraceActions action)
{
var si = GetSecurityAuction(order.Security);
var newNode = si.PutInQueue(order); // запоминаем тк надо сделки потом сводить по этим заявкам
try
{
var depth = si.GetDepth(si);
if (EvaluateConditional(depth, order))
return/* true*/;
if (EvaluateByDepth(order, depth, true))
return/* true*/;
if (depth == null)
{
// без стакана маркетные(они всегда новые) и новые лимитные-в-рынок матчатся по посл. сделке
var last = si.LastTrade;
if (last != null && last.Price != 0)
EvaluateByLast(order, last);
}
}
catch (Exception e)
{
ProcessDataError(e);
}
//return false;
}
Что дает стабильную работу, по крайней мере на моих тестах.