You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
В своем приложении для автоматизации мне нужно получать объект TransactionReply ответа на транзакцию выставления нового стоп ордера, с ее статусом, и id только что выставленного ордера.
Сейчас я делаю это через вот такую странную конструкцию, потому что способа лучше пока не нашел:
Подписываюсь на событие OnTransReply и складываю в конкарент очередь все приходящие ответы на транзакцию:
Дальше, при создании ордера, в цикле с таймаутом жду, пока в этой очереди появится реплай с нужным id транзакции. Именно сам реплай мне нужен, чтобы проверять у него статус и сообщение, по которым можно понять, что ордер, например, не выставился, потому что был превышен лимит на кредитование и т.п.:
var createOrderRes = _quik.StopOrders.CreateStopOrder(order).Result;
//await for transaction response
var transId = Math.Abs(createOrderRes);
var getTransRespTimeoutMs = 400;
var getTransRespIterations = 40;
TransactionReply transResp = null;
for (var i = 0; i < getTransRespIterations; ++i)
{
if (_transResponses.ContainsKey(transId))
{
_transResponses.TryRemove(transId, out TransactionReply res);
transResp = res;
break;
}
Thread.Sleep(getTransRespTimeoutMs);
}
Тут встречается первая проблема:
Как видно, таймаут и число попыток достаточно больше, но все равно, в редких случаях я встречаю ситуации, когда transResp остается нулевым - а это значит что, похоже, до этого в очередь в коллбэке события не положили ответ на транзакцию с id == Math.Abs(createOrderRes)
Вторая проблема более странная и встречается тоже внезапно, и тоже раз в пару дней (по ощущениям - когда выставляешь несколько ордеров последовательно, с небольшим таймаутом между ними): в получаемом по transId ордере неверный secCode инструмента!
Как я это обнаруживаю:
Если transactionResponse пришел с хорошим кодом и без ошибок, я дальше получаю по нему ордер таким образом:
var newOrder = this.GetNewStopOrderByTransactionId(transId).Result;
Где:
private async Task<QuikSharp.DataStructures.StopOrder> GetNewStopOrderByTransactionId(long transId)
{
var attemptsCount = 20;
Thread.Sleep(100);
var stopOrder = await GetStopOrderByTransactionId(transId);
if (stopOrder != null)
return stopOrder;
//if stop order wasn't found
for (var i = 2; i <= attemptsCount; ++i)
{
Thread.Sleep(500);
Log($"Attempt {i}/{attemptsCount} to retrieve new stop order for transaction {transId}...");
stopOrder = await GetStopOrderByTransactionId(transId);
if (stopOrder != null)
return stopOrder;
}
return null;
}
И, соответственно:
private async Task<QuikSharp.DataStructures.StopOrder> GetStopOrderByTransactionId(long transId)
{
var stopOrders = await _quik.StopOrders.GetStopOrders();
if (stopOrders != null)
{
var stopOrder = stopOrders.FirstOrDefault(x => x.TransId == transId);
if (stopOrder != null)
return stopOrder;
}
return null;
}
И вот тут начинается проблема: я начал ловить ситуации, когда SecCode инструмента в ордере, объект которого я отправил на выставление в метод _quik.StopOrders.CreateStopOrder(order).Result; либы не совпадает с secCode ордера, который я получил по this.GetNewStopOrderByTransactionId(transId) (!!!)
То есть периодически выполняется return в этой проверке:
if (newOrder.SecCode != newStopOrder.Ticker)
{
var msg = $"Placed order secCode {newOrder.SecCode} is not equal to requested ticker {newStopOrder.Ticker}. Check by transaction ids: awaited to createdOrderRes {createOrderRes} transaction id {transId} but obtained new order with trans id {newOrder.TransId}";
Log($"ERROR! {msg}");
return new PlaceNewOrderResult
{
IsError = true,
State = PlaceNewOrderResult.ResultState.GeneralError,
Message = msg
};
}
Как будто бы, если последовательно выставляются несколько ордеров по разным инструментам, то транзакции по ним могут перепутаться. Проверяя свой код, я пока не нашел в нем ошибку, которая могла бы приводить к такому поведению.
Хотел бы услышать, сталкивался ли кто-то еще с таким поведением? И буду благодарен, если сможете подсказать более простой и надежный способ получать выставленный ордер и данные TransactionReply по id транзакции.
The text was updated successfully, but these errors were encountered:
MrJimm
changed the title
Надежный способ получать id выставленного ордера по id транзакции
Надежный способ получать объект TransactionReply и id выставленного ордера по id транзакции
Jul 22, 2021
В своем приложении для автоматизации мне нужно получать объект TransactionReply ответа на транзакцию выставления нового стоп ордера, с ее статусом, и id только что выставленного ордера.
Сейчас я делаю это через вот такую странную конструкцию, потому что способа лучше пока не нашел:
Подписываюсь на событие OnTransReply и складываю в конкарент очередь все приходящие ответы на транзакцию:
Дальше, при создании ордера, в цикле с таймаутом жду, пока в этой очереди появится реплай с нужным id транзакции. Именно сам реплай мне нужен, чтобы проверять у него статус и сообщение, по которым можно понять, что ордер, например, не выставился, потому что был превышен лимит на кредитование и т.п.:
Тут встречается первая проблема:
Как видно, таймаут и число попыток достаточно больше, но все равно, в редких случаях я встречаю ситуации, когда transResp остается нулевым - а это значит что, похоже, до этого в очередь в коллбэке события не положили ответ на транзакцию с id == Math.Abs(createOrderRes)
Вторая проблема более странная и встречается тоже внезапно, и тоже раз в пару дней (по ощущениям - когда выставляешь несколько ордеров последовательно, с небольшим таймаутом между ними): в получаемом по transId ордере неверный secCode инструмента!
Как я это обнаруживаю:
Если transactionResponse пришел с хорошим кодом и без ошибок, я дальше получаю по нему ордер таким образом:
Где:
И, соответственно:
И вот тут начинается проблема: я начал ловить ситуации, когда SecCode инструмента в ордере, объект которого я отправил на выставление в метод _quik.StopOrders.CreateStopOrder(order).Result; либы не совпадает с secCode ордера, который я получил по this.GetNewStopOrderByTransactionId(transId) (!!!)
То есть периодически выполняется return в этой проверке:
Как будто бы, если последовательно выставляются несколько ордеров по разным инструментам, то транзакции по ним могут перепутаться. Проверяя свой код, я пока не нашел в нем ошибку, которая могла бы приводить к такому поведению.
Хотел бы услышать, сталкивался ли кто-то еще с таким поведением? И буду благодарен, если сможете подсказать более простой и надежный способ получать выставленный ордер и данные TransactionReply по id транзакции.
The text was updated successfully, but these errors were encountered: