OnTransReply возвращает order_num = nil

Страницы: 1
RSS
OnTransReply возвращает order_num = nil
 

Здравствуйте. Только начал знакомится со скриптами Lua в Quik. Возникла проблема. Если вкратце, отправляю заявку sendTransaction с необходимыми параметрами. В терминале вижу, что заявка принята и отображается как активная, OnTransReply возвращает status = 3, trans_id ровно тот что и присваивал при отправке заявки. Все прекрасно ровно до тех пор, пока мне не понадобится, например, снять заявку. Начинаются чудеса какие-то. Параметр order_num = nil, но в терминале то в таблице заявок я прекрасно вижу эти номера. Почитав документацию, там некоторые параметры, помеченные звездочкой,

* – параметр может иметь значение nil

НО! Интересует, при каких же условиях они будут возвращаться как nil? Ни слова об этом в документации.
Опять же таки, как поступить если нужен order_num?
1. Обрабатывать OnTransReply только на status?
2. Обрабатывать коллбэк OnOrder? Опять же таки я не нашел в документации ни слова о том при каком условии он вызывается? Только при условии что trans_reply.status = 3 или вообще при любой попытке отправить заявку, даже неудачной? В первом случае получив и обработав OnOrder можно не запариваться с OnTransReply и его статусом по идее, разве что для информации. Во втором случае в коллбэке OnOrder обязательно нужно проверить trans_reply.status. И опять же появляется другой вопрос, в какой последовательности оба этих коллбэка идут??? Если OnOrder может прийти раньше OnTransReply, то получается полнейшая ерунда, order_num в OnTransReply я получить не могу, а OnOrder не могу обработать, т.к. понятия не имею о статусе заявки...

 
Код
function OnTransReply(reply) -- Функция вызывается терминалом QUIK при получении ответа на транзакцию пользователя
   ***
   if reply.status == 3 then -- Транзакция выполнена
      --------------------------------------------------------------------------------------------
      OpCl[n] = rts(n, reply.price)
      Num[n] = reply.order_num
      --------------------------------------------------------------------------------------------
   elseif reply.status == 2 or reply.status > 3 then -- Произошла ошибка
   ***

Вот так получаю цену и номер заявки - вопросов не возникало
 
Принципиально у меня тоже самое, насчет price не проверял, но order_num = nil это точно.  
 
Алексей,  если коротко - придет позже еще один OnTransReply уже с номером заявки.

Если чуть длиннее, общая проблема состоит в том, что все рассматривают транзакцию как метод класса заявки, и OnTransReply как асинхронный колбек завершения этого метода, то есть примерно так
Код
class Order
{
    void SendTransaction(...);
    virtual void OnTransReply(...);
    virtual void OnOrder(...);
};
, в то время как транзакция является самостоятельным классом и OnTransReply это событие изменения чего-то в этом классе, т.е. примерно так
Код
class Order
{
    virtual void OnOrder(...);
};

class Transaction
{
    SendTransaction(...);
    virtual void OnTransReply(...);
};
При первом подоходе вы, естественно, ждете однократного события завершения транзакции со всеми полями. При втором нет ничего странного в том, что состояние транзакции меняется в несколько подходов. Когда оно изменится настолько, что дальнейшая судьба транзакции вам станет неинтересна (в вашем случае, когда придет номер заявки), вы можете этот объект удалить и игнорировать дальнейшие его изменения.

OnOrder может приходить раньше OnTransReply, но с учетом вышесказанного вас это не будет беспокоить, поскольку состояния классов меняются независимо (хотя как результат изменения состояния транзакции вы будете, скорее всего, и как-то менять состояние ордера).
 
Цитата
Алексей написал:
OnTransReply
Вот здесь есть картики как работает trans_reply and order
Q
 
Anton, спасибо за пояснение. В принципе нечто подобное я себе и представлял. Но остается открытым вопрос, что же делать то? Но из вашего пояснения получается, что OnTransReply может вызываться на каждую заявку неоднократно? Если это так, достаточно ли фильтровать те, что пришли с order_num = nil и тупо ждать коллбэк с заполненным этим полем, он обязательно появится?
QApplication, спасибо, обязательно гляну.
 
Цитата
Алексей написал:
он обязательно появится?
Он может и совсем не появиться. Выше QApplication дал ссылку, там он как раз разбирался с тем, что не приходит. Или если соединение потеряно непосредственно после отправки транзакции. Спасение в том, чтобы не закладывать никакой порядок колбеков и даже факт их появления. Вы хотите создать заявку - создаете объект заявки со статусом "ожидает отправки", затем создаете объект транзакции со ссылкой на объект заявки и отправляете, меняя статус заявки на "отправлена", затем колбеки как-то меняют состояние транзакции и заявки, при этом в колбеке транзакции вы также меняете состояние заявки (а ссылка на заявку у вас в транзакции есть). В какой-то момент состояние заявки становится "выставлена", или даже сразу "исполнена", или "снята", или "отвергнута", или "соединение потеряно, фикзнает что с ней", тут вам транзакция больше не нужна, вы ее удаляете, не глядя, что там с ней случилось.
 
Алексей, Что делать? Видимо, то же, что и я: почти сразу выбросил OnOrder вообще, не разбираясь в нюансах, как ПОТЕНЦИАЛЬНО глючный, оставил только OnTrade как минимально необходимый. Проблем с order_num ни разу не испытывал.
 
Цитата
Алексей написал:
обязательно гляну
про состояние trans_reply - у меня не приходят колбеки со статусом 0 и 1 (на этот вопрос ни кто из разработчиков не ответил),
Здесь сомопроизвольно колбек дергается без направления транзакции и разработчики не знают что это такое
Q
 
Цитата
Anton написал:
Спасение в том, чтобы не закладывать никакой порядок колбеков и даже факт их появления.
Но ведь колбэки именно под это и заточены.
Цитата
Владимир написал:
оставил только OnTrade
Только этот колбэк не катит, ибо он приходить только после факта сделки. А у меня логика другая, заявка может сниматься еще до факта сделки, но чтобы убить заявку до сделки, нужен order_num, а кроме как из OnOrder или OnTransReply я больше не знаю способов как его получить. Разве что кроме как прямо из таблицы заявок TABLE order NUMBER indx getOrderByNumber(STRING class_code, NUMBER order_id), Но опять же надо знать order_id, а получить его можно только из OnOrder или OnTransReply еще до факта сделки. Правда order_id я не проверял...
 
Колбеки хороши, но их не гарантированность - убивает идею.

У Вас доступны методы прямого перебора таблиц: перед подачей транзакции запоминаете число строк в таблице ордеров, после просто проверяете, что появились новые записи в таблице, проверяя каждую, что это необходимая. Правда если номер транзакции сначала не будет заполнен, то уже возникают сложности. Поэтому можно использовать второй вариант - функция SearchItems. Запоминаете номер транзакции и далее ищете в таблице, когда там появится запись.

Далее, что важно в таком сценарии, вы легко запоминаете индекс в  таблице, а значит всегда можете обновить информацию по ордеру, без  всякого колбека.
 
Цитата
Алексей написал:
Но опять же надо знать order_id, а получить его можно только из OnOrder или OnTransReply еще до факта сделк
испльзуйте trans_id (вы его сами задаете) и ищите через него Ордер в таблице ордеров
Q
 
Алексей, Только этот колбэк и катит!  :smile: Именно, что он приходит только после факта сделки. Даже если эта сделка "левая" - скрипт заявку не подавал, а сам юзер вручную, через стаканы что-то там купил или продал. У меня заявка ТОЖЕ может сниматься ещё до факта сделки (либо частично исполненная). Да, "чтобы убить заявку до сделки, нужен order_num", и я его получаю как раз "прямо из таблицы заявок"... чо-то я не понял... что там order_num, а что order_id? Нужен номер заявки для снятия, и он получается либо по OnTrade, либо из таблицы "orders".
 
Цитата
Алексей написал:
Но ведь колбэки именно под это и заточены.
Ну так они и дернутся в каком-то неведомом порядке и количестве, свою задачу выполнят.

Кстати говоря, еще раз перечитал первое сообщение и похоже, что вопрос-то немного о другом, нил приезжает в OnTransReply при снятии заявки? Это нормальное поведение тогда на некоторых классах. Опять же, в описанном мной варианте вас это не должно тревожить, у вас есть trans_id, по которому вы найдете объект транзакции, а из него получите ссылку на объект заявки, которую снимали. В любом случае предлагаю создавать свои объекты для заявок и транзакций, а не полагаться на "выдерну из таблицы", поскольку в таблице нет одной важной вещи - статуса (вашего, не квиковского), т.е. "что я с этим объектом сделал и чего от него жду".
 
Цитата
Anton написал:
нил приезжает в OnTransReply при снятии заявки? Это нормальное поведение тогда на некоторых классах.
В каких классах может быть nil ?
Надо делать так, как надо. А как не надо - делать не надо.
 
Старатель,  https://forum.quik.ru/messages/forum10/message50381/topic5978/#message50381
 
Цитата
Anton написал:
Старатель,   https://forum.quik.ru/messages/forum10/message50381/topic5978/#message50381
Так вы про 0 (ноль) (number)
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
про 0 (ноль)
Ага. Что, кстати говоря, косячок-с, по логике нил должен быть, номер-то не изменился у заявки, он просто уже недоступен.
 
Цитата
Алексей написал:
Но остается открытым вопрос, что же делать то? Но из вашего пояснения получается, что OnTransReply может вызываться на каждую заявку неоднократно? Если это так, достаточно ли фильтровать те, что пришли с order_num = nil и тупо ждать коллбэк с заполненным этим полем, он обязательно появится?
У себя проверял, при trans_reply.status==3 trans_reply.order_num всегда заполнен и равен номеру заявки (при выставлении - новой, при снятии - снимаемой)

Но если я правильно понимаю, то OnTransReply формируется сервером брокера, а не биржей, так что думаю от настроек брокера может зависеть заполненность полей и количество ответов.

Вам стоит проверить сколько и каких ответов придет для конкретно вашего случая
Код
function OnTransReply(trans_reply) -- Функция вызывается терминалом QUIK при получении ответа на транзакцию пользователя
  local str="OnTransReply:"
  for k,v in pairs(trans_reply) do
    str=str.."\n"..tostring(k).."="..tostring(v)
  end
  message(str)
end
И уже в зависимости от результата искать решение.
 
Цитата
Алексей написал:
Обрабатывать коллбэк OnOrder? Опять же таки я не нашел в документации ни слова о том при каком условии он вызывается? Только при условии что trans_reply.status = 3 или вообще при любой попытке отправить заявку, даже неудачной?
OnOrder вызывается при получении новой заявки или при изменении параметров существующей заявки и с OnTransReply никак не связан.
Ну то есть при trans_reply.status==3 по логике должен прийти OnOrder (и обычно приходит), но как бы прямой взаимосвязи нет.
Цитата
Алексей написал:
В первом случае получив и обработав OnOrder можно не запариваться с OnTransReply и его статусом по идее, разве что для информации. Во втором случае в коллбэке OnOrder обязательно нужно проверить trans_reply.status. И опять же появляется другой вопрос, в какой последовательности оба этих коллбэка идут??? Если OnOrder может прийти раньше OnTransReply, то получается полнейшая ерунда, order_num в OnTransReply я получить не могу, а OnOrder не могу обработать, т.к. понятия не имею о статусе заявки...
А тут все гораздо интереснее, и последовательность прихода этих коллбеков может быть любая, но это совершенно не проблема если мы используем очереди событий для указанных коллбеков.
Сначала ищем определенное время в очереди OnTransReply нужный ответ с order_num, либо отлуп.
После чего так же определенное время в очереди OnOrder ищем нужную нам заявку.
 
Не стал плодить темы, вобщем с order_num разобрался, спасибо. Пришел к выводу что надо брать из таблицы заявок еще и статус заявки, так как бы надежнее :) Сейчас разбираюсь с простым и по исполнению тэйк профитом и стоп лоссом. Вообще в голове сумбур полный, ибо они работают как на покупку так и на продажу. Хочу для начала разобраться с простым. Читаю документацию и вижу это
Код
Тэйк-профит и стоп-лимит Лукойл, покупка 1 лота, активация тэйк-профита при достижении цены 2000 с отступом в 5% и защитным спрэдом в 3%, стоп-цена 2222, цена лимитированной заявки 2255, время действия с 10:00:01 по 19:45:45
ACTION=NEW_STOP_ORDER; 
TRANS_ID=10055; 
CLASSCODE= TQBR; 
SECCODE=LKOH; 
ACCOUNT=L01-00000F00; 
CLIENT_CODE=Q7; 
OPERATION=B; 
QUANTITY=1; 
PRICE=2255; 
STOPPRICE=2000; 
STOP_ORDER_KIND=TAKE_PROFIT_AND_STOP_LIMIT_ORDER; OFFSET=5; 
OFFSET_UNITS=PERCENTS; 
SPREAD=3; 
SPREAD_UNITS=PERCENTS; 
MARKET_TAKE_PROFIT=NO; 
STOPPRICE2=2222; 
IS_ACTIVE_IN_TIME=YES; 
ACTIVE_FROM_TIME=100001; 
ACTIVE_TO_TIME=194545; 
MARKET_STOP_LIMIT=NO
В частности недопонимаю когда ее выставлять? Вижу, что операция продажа. Следовательно чтобы что то выставить на продажу надо сначала купить?
Как я понимаю здесь, при достижении цены 2000 на уже купленной акции активируется тейк профит? Или же я неверно понимаю логику тэйк профит, активируется когда цена достигнет 2000 + 5% и -3% защитного спреда? При этом условии акция будет продана?
Не понятно что такое стоп цена 2222?
Да и цена лимитированной заявки 2255 вообще не вписывается в логику.
 
В сети полно видео с объяснением значения полей при вводе стоп-профит заявок. При подаче транзакции - тот же смысл.
 
Вот только сколько ни смотрел, сколько не читал, все как один говорят/пишут вот тут надо эту цену поставить, тут цена должна быть чуть меньше/больше, а тут вот такая. Т.е. никакого понимания не дают.
 
Так это надо тогда сначала разобраться в логике работы стоп ордеров как таковых. Что такое стоп цена, что такое проскальзывание и зачем цена подачи исполняемой заявки должна быть другой и т.д.
 
С проскальзыванием понятно, вдруг не мне не хватило, будем продавать/покупать в рамках проскальзывания.
 
Добрый день,

для того, чтобы понять, как работают стоп-заявки и что означают поля при вводе заявки, был разработан специальный документ, с которым рекомендуем ознакомиться. Скачать можно по данной ссылке
 
Ну так у стопа две цены - цена активации и цена отправки транзакции в ядро биржи. Стоп ордера живут на сервере брокера, на бирже только лимитки.

Если есть профит, то есть цена активации профита, есть защитный спред (то же проскальзывние) и есть отступ. Вот отступ - это как бы скользящий стоп. Когда профит активировался, то риск модуль брокера начинает следить за ценой, если она опустится на величину отступа, то отправляем на биржу ордер. Если же растет дальше, то ничего не делаем. В теории это дает получить больший профит.
 
Daniil Pozdnyakov, спасибо, буду изучать. Правда там не все типы, но насколько я понимаю все, которых нет в файле, это комбинация основных?
 
Добрый день,

Могли бы уточнить, про какие типы Вы ведёте речь ?
 
Например
STOP_ORDER_KIND=ACTIVATED_BY_ORDER_TAKE_PROFIT_AND_STOP_LIMI­T_ORDER
 
Добрый день,

"ACTIVATED_BY_ORDER_TAKE_PROFIT_AND_STOP_LIMI­T_ORDER" - это "тейк-профит и стоп-лимит по исполнению заявки". О данном и похожих типах заявок написано в документации, которую мы       отправили, в пункте 10. Условная заявка "Стоп-заявка по исполнению" на странице 36.
Страницы: 1
Читают тему
Наверх