Извечный вопрос: повторные вызовы OnTrade

Страницы: 1
RSS
Извечный вопрос: повторные вызовы OnTrade, Даже при заявке на одну акцию
 
Создаю заявку из lua-скрипта на покупку ровно одной акции. Т.е. никаких финтов с частичным исполнением не может быть. При исполнении происходят два вызова функции OnTrade. Сделал полную распечатку всей таблицы от обоих вызовов. Отличие только в трёх полях: uid, on_behalf_of_uid, trans_id. При первом вызове все три нулевые, при втором все три - ненулевые.

Вопросы следующие:
1. Гарантируется ли, что вызов OnTrade, в котором эти поля нулевые, является не последним, т.е. я могу его игнорировать, т.к. после него будет следующий?
2. Гарантируется ли, что вызов, в котором эти поля ненулевые, является последним?
3. Являются ли эти три поля синхронными всегда? (Т.е. либо все три равны 0, либо все три не равны 0?) Т.е. можно ли проверять только одно из них, а не все три вместе?
 
Цитата
User12501 написал:
Гарантируется ли, что вызов OnTrade, в котором эти поля нулевые, является не последним
Нет.
trans_id и uid в некоторых ситуациях могут иметь и нулевые значения.
 
Цитата
User12501 написал:
Являются ли эти три поля синхронными всегда? (Т.е. либо все три равны 0, либо все три не равны 0?)
Нет
 
Цитата
User12501 написал:
Создаю заявку из lua-скрипта на покупку ровно одной акции. Т.е. никаких финтов с частичным исполнением не может быть. При исполнении происходят два вызова функции OnTrade. Сделал полную распечатку всей таблицы от обоих вызовов. Отличие только в трёх полях: uid, on_behalf_of_uid, trans_id. При первом вызове все три нулевые, при втором все три - ненулевые.

Вопросы следующие:
1. Гарантируется ли, что вызов OnTrade, в котором эти поля нулевые, является не последним, т.е. я могу его игнорировать, т.к. после него будет следующий?
2. Гарантируется ли, что вызов, в котором эти поля ненулевые, является последним?
3. Являются ли эти три поля синхронными всегда? (Т.е. либо все три равны 0, либо все три не равны 0?) Т.е. можно ли проверять только одно из них, а не все три вместе?
Если заявка, по которой пройдет сделка выставлена не скриптом Lua, то trans_id будет нулевой .
-------------------------------------------
Должны быть не нулевые , так как определяют клиента на сервере брокера.
-----------------------------
Полагаю , что первый раз приходит с биржи, второй - с сервера брокера.
 
 
 
Два других должны быть не нулевые , так как определяют клиента на сервере брокера.
 
Опять отловил два повторных OnTrade, на этот раз совпадали все поля кроме broker_comission и broker_comission_currency (в первом они были 0 и пусто, во втором правильные). Можно ли как-то конкретно определить полный набор полей, которые я должен проверить, чтобы уверенно знать, что данный вызов OnTrade является последним по данной заявке?
Речь только про заявки из скрипта qlua, строго на один лот.  
 
Цитата
User12501 написал:
Опять отловил два повторных OnTrade, на этот раз совпадали все поля кроме broker_comission и broker_comission_currency (в первом они были 0 и пусто, во втором правильные). Можно ли как-то конкретно определить полный набор полей, которые я должен проверить, чтобы уверенно знать, что данный вызов OnTrade является последним по данной заявке?
Речь только про заявки из скрипта qlua, строго на один лот.  
Нельзя ответить на этот вопрос. Например, если поля broker_comission и broker_comission_currency не важны, то этот второй вызов бесполезен, а если важны, то уже нет. Хотя, если говорить о комиссиях брокера, то они их может не транслировать вовсе и можно ждать вечно.

Т.е. все зависит от того, что необходимо. Явно поля количества и суммы важны, и, наверно, brokerref. Остальное уже решать Вам.

В системах с повторяющимися сигналами принято обновлять ранее поступившие данные. Пришли первоначальные данные - записали их с неким ключом. Пришли повторно обновили их и вызвали метод обновления зависимых данных. Т.е. если строить систему на простейшем принципе однократного учета, то будут проблемы. А если обновлять и пересчитывать, то уже нет. Хотя, конечно, обновление данных - это более сложная реализация. Иногда настолько, что проще не делать.
 
Цитата
Nikolay написал:
Например, если поля broker_comission и broker_comission_currency не важны, то этот второй вызов бесполезен, а если важны, то уже нет.

Речь о том, как проигнорировать бесполезный вызов и не посчитать дважды то, что нужно? Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают (спрашивал об этом вот здесь: https://forum.quik.ru/forum10/topic9409/ ). Значит нужно вводить отдельную переменную - количество акций, и при каждом OnTrade обновлять. Но тогда при повторном OnTrade происходит повторное обновление, и пожалуйста - ошибка.  
 
Цитата
User12501 написал:

Речь о том, как проигнорировать бесполезный вызов и не посчитать дважды то, что нужно? Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают (спрашивал об этом вот здесь:  https://forum.quik.ru/forum10/topic9409/  ). Значит нужно вводить отдельную переменную - количество акций, и при каждом OnTrade обновлять. Но тогда при повторном OnTrade происходит повторное обновление, и пожалуйста - ошибка.  
Ошибка т.к. обработка наивная:

pos = pos + sign*traded.qty

Естественно при таком подходе повторный вызов даст искажение данных. А если обработка более сложная, то не будет ошибки. Это уже вопрос реализации, зависящий от конкретной задачи.
 
Цитата
User12501 написал:
Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают
Вы подняли очень важный вопрос. Он касается широкого круга пользователей, и широко обсуждался на форуме и приводились различные боевые подходы. На Ваш вопрос выше, ответ нужно организовывать внутренний учет, не только количества но и других параметров зависящих от конкретной сделки сделки (допустим усреднялись). Вот пример подхода которым, часто пользуюсь на скоростных скриптах:
Код
function OnTrade(trade)

    if not WORKING_FLAG then return end

    local key = trade.trans_id
    local i = tonumber(sdelka[0]); 
    
  if working 
  and key and key>0
  and (i==0 and key~=sdelka.id) or (i>0 and sdelka[i][1]~=key)
  --and trade.sec_code==symbol --and trade.class_code==class 
  then
    
    i=i+1;  
    sdelka[0]=i;                         
    sdelka[i]={};                     
    sdelka[i][0]=sdelka[0];
    sdelka[i][1]=trade.trans_id;      
    sdelka[i][2]=get_date(trade.datetime)
    sdelka[i][3]=get_time(trade.datetime)
    
    sdelka[i][4]="B"; if bit.band(trade.flags,4)~=0 then sdelka[i][4]="S"; end;
    local dir = sdelka[i][4]=="B" and 1 or sdelka[i][4]=="S" and -1 or 0;
    sdelka[i][5]=trade.qty*dir;       
    sdelka[i][6]=trade.price;         
    ----- comission 
    sdelka[i][7]=trade.clearing_comission+trade.exchange_comission+trade.tech_center_comission;
    
    sdelka[i][8]=trade.order_num;    
    sdelka[i][9]=trade.trade_num;  
    sdelka[i][10]=trade.sec_code;     
                        
    sdelka.id=trade.trans_id;
    
    Log:info("OnTrade! sdelka "..i .."; "
                                  .."; trans_id="..sdelka[i][1] 
                                  .."; "..sdelka[i][2]
                                  .."; "..sdelka[i][3]
                                  .."; "..sdelka[i][4]
                                  .."; "..sdelka[i][5]
                                  .."; "..sdelka[i][6]
                                  .."; comission="..sdelka[i][7]
                                  .."; onum="..sdelka[i][8]
                                  .."; tnum="..sdelka[i][9]
                                  .."; "..sdelka[i][10]
                                  .."\n"
                                  );
    --local a,v; for a,v in pairs(sdelka[i) do Log:trace( 'OnTrade! sdelka['..i..']['..tostring(a)..'] = '.. tostring(v) ) end;
  end
end;
 
Цитата
VPM написал:
Цитата
User12501 написал:
Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают
Вы подняли очень важный вопрос. Он касается широкого круга пользователей, и широко обсуждался на форуме и приводились различные боевые подходы. На Ваш вопрос выше, ответ нужно организовывать внутренний учет, не только количества но и других параметров зависящих от конкретной сделки сделки (допустим усреднялись). Вот пример подхода которым, часто пользуюсь на скоростных скриптах:
Код
     

Спасибо. Принцип такого костыля понятен, но очень надеялся, что можно как-то проще. Видимо нельзя.  
 
User12501,  И это еще не вся проблематика, ведь нужно данные периодически синхронизировать с данными QUIK.  
 
Цитата
VPM написал:
Цитата
User12501 написал:
Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают
Вы подняли очень важный вопрос. Он касается широкого круга пользователей, и широко обсуждался на форуме и приводились различные боевые подходы. На Ваш вопрос выше, ответ нужно организовывать внутренний учет, не только количества но и других параметров зависящих от конкретной сделки сделки (допустим усреднялись). Вот пример подхода которым, часто пользуюсь на скоростных скриптах:
Код
   
     ----- comission  
    sdelka[i][ 7 ] = trade.clearing_comission + trade.exchange_comission + trade.tech_center_comission;
   
Кстати раз уж вы выложили код, есть вопрос по вот этой строке. Сейчас проверил в тех сделках, которые у себя отлавливал: там есть поле broker_comission, которое я воспринимал как итоговую сумму всех комиссий. И оно больше, чем написанная вами сумма. Например для одного лота MOEX:
tech_center_comission = 0
clearing_comission = 0.22
exchange_comission = 0.3
broker_comission = 1.57

Проверка по остатку на счёте показывает, что 1.57 - точное значение итоговой комиссии, т.е. уже включает в себя всё остальное (и ещё что-то).  
 
Привел Вам просто базовую свою заготовку, в качестве примера не более. Если вы пишите на луа 5.4, то нужно отказаться от bit.band в пользу продвинутого метода. Что там точно за комиссии, подсказать  тоже не могу так как на каждом рынке есть особенности. Для Фондового API QUIK предлагает предварительный расчет через стандартную функцию. Для оценки можно ее воспользоваться. На срочном есть зависимость от гарантийного обеспечения и курсов ... Что касается моего подхода, то я применяю подход  Ральфа Винса, а именно, торговый капитал делю изначально на две части: пассивный и активный. Так как в процессе торговле всегда присутствует пассивная часть, нет необходимости вести четкий учет комиссий, сверяю по клирингу. Здесь более важен учет количества и цены, так как на прямую влияют на управление позицией.  
Страницы: 1
Читают тему
Наверх