При использовании EmulationTrader наблюдаются следующие проблемы (наблюдал на версия 4.1.7, но судя по сорцам проявиться и в 4.1.8)
Заявка отправляется в эмулятор. Получает статус Active и после этого зависает (Не вызывает никаких событий, не исполняется и не отменяется). При изучении логов наталкиваемся на сообщение "Невозможно зарегистрировать заявку {0}: нет ни стаканов ни последней цены." Что выводит нас на код в MarketEmulator
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.
Далее смотрим кто вызывает эту функцию. Вызывается она в одном единственном месте. Там написано, что то типа:
if (state.State != OrderStates.Active)
throw new InvalidOperationException("State!=Active");
EvaluateNew(state, action);
Что наталкивает нас на мысль, что при выполнении верхнего участка кода статус заявки ВСЕГДА будет Active. Что при выполнении ветки
else
{
// если нет никаких цен, то фэйл
ProcessError(order,action, new InvalidOperationException("Невозможно зарегистрировать заявку {0}: нет ни стаканов ни последней цены.".Put(order.TransactionId)));
si.Remove(newNode);
}
Приведет к тому, что мы попытаемся Active заявку перевести в состояние Fail что противоречит логике работы объекта Order (и что выливается в ошибки при ее обработке объектом Strategy и т.п.)
Предлагаю правку: Код MarketEmulator
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;
}
заменить на
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;
}
Что дает стабильную работу, по крайней мере на моих тестах.
Комментарии (2)
Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий
Посмотрите релиз 4.1.8 Там есть такая проблема?
Накатил 4.1.8 проблема пропала. Спасибо.