Извечный вопрос: повторные вызовы OnTrade, Даже при заявке на одну акцию
Пользователь
Сообщений: Регистрация: 26.11.2025
06.01.2026 22:52:46
Создаю заявку из lua-скрипта на покупку ровно одной акции. Т.е. никаких финтов с частичным исполнением не может быть. При исполнении происходят два вызова функции OnTrade. Сделал полную распечатку всей таблицы от обоих вызовов. Отличие только в трёх полях: uid, on_behalf_of_uid, trans_id. При первом вызове все три нулевые, при втором все три - ненулевые.
Вопросы следующие: 1. Гарантируется ли, что вызов OnTrade, в котором эти поля нулевые, является не последним, т.е. я могу его игнорировать, т.к. после него будет следующий? 2. Гарантируется ли, что вызов, в котором эти поля ненулевые, является последним? 3. Являются ли эти три поля синхронными всегда? (Т.е. либо все три равны 0, либо все три не равны 0?) Т.е. можно ли проверять только одно из них, а не все три вместе?
Пользователь
Сообщений: Регистрация: 02.01.2026
06.01.2026 23:45:30
Цитата
User12501 написал: Гарантируется ли, что вызов OnTrade, в котором эти поля нулевые, является не последним
Нет. trans_id и uid в некоторых ситуациях могут иметь и нулевые значения.
Пользователь
Сообщений: Регистрация: 02.01.2026
06.01.2026 23:46:33
Цитата
User12501 написал: Являются ли эти три поля синхронными всегда? (Т.е. либо все три равны 0, либо все три не равны 0?)
Нет
Пользователь
Сообщений: Регистрация: 30.01.2015
07.01.2026 06:33:14
Цитата
User12501 написал: Создаю заявку из lua-скрипта на покупку ровно одной акции. Т.е. никаких финтов с частичным исполнением не может быть. При исполнении происходят два вызова функции OnTrade. Сделал полную распечатку всей таблицы от обоих вызовов. Отличие только в трёх полях: uid, on_behalf_of_uid, trans_id. При первом вызове все три нулевые, при втором все три - ненулевые.
Вопросы следующие: 1. Гарантируется ли, что вызов OnTrade, в котором эти поля нулевые, является не последним, т.е. я могу его игнорировать, т.к. после него будет следующий? 2. Гарантируется ли, что вызов, в котором эти поля ненулевые, является последним? 3. Являются ли эти три поля синхронными всегда? (Т.е. либо все три равны 0, либо все три не равны 0?) Т.е. можно ли проверять только одно из них, а не все три вместе?
Если заявка, по которой пройдет сделка выставлена не скриптом Lua, то trans_id будет нулевой . ------------------------------------------- Должны быть не нулевые , так как определяют клиента на сервере брокера. ----------------------------- Полагаю , что первый раз приходит с биржи, второй - с сервера брокера.
Пользователь
Сообщений: Регистрация: 30.01.2015
07.01.2026 06:33:49
Два других должны быть не нулевые , так как определяют клиента на сервере брокера.
Пользователь
Сообщений: Регистрация: 26.11.2025
09.01.2026 12:24:50
Опять отловил два повторных OnTrade, на этот раз совпадали все поля кроме broker_comission и broker_comission_currency (в первом они были 0 и пусто, во втором правильные). Можно ли как-то конкретно определить полный набор полей, которые я должен проверить, чтобы уверенно знать, что данный вызов OnTrade является последним по данной заявке? Речь только про заявки из скрипта qlua, строго на один лот.
Пользователь
Сообщений: Регистрация: 27.01.2017
09.01.2026 12:37:49
Цитата
User12501 написал: Опять отловил два повторных OnTrade, на этот раз совпадали все поля кроме broker_comission и broker_comission_currency (в первом они были 0 и пусто, во втором правильные). Можно ли как-то конкретно определить полный набор полей, которые я должен проверить, чтобы уверенно знать, что данный вызов OnTrade является последним по данной заявке? Речь только про заявки из скрипта qlua, строго на один лот.
Нельзя ответить на этот вопрос. Например, если поля broker_comission и broker_comission_currency не важны, то этот второй вызов бесполезен, а если важны, то уже нет. Хотя, если говорить о комиссиях брокера, то они их может не транслировать вовсе и можно ждать вечно.
Т.е. все зависит от того, что необходимо. Явно поля количества и суммы важны, и, наверно, brokerref. Остальное уже решать Вам.
В системах с повторяющимися сигналами принято обновлять ранее поступившие данные. Пришли первоначальные данные - записали их с неким ключом. Пришли повторно обновили их и вызвали метод обновления зависимых данных. Т.е. если строить систему на простейшем принципе однократного учета, то будут проблемы. А если обновлять и пересчитывать, то уже нет. Хотя, конечно, обновление данных - это более сложная реализация. Иногда настолько, что проще не делать.
Пользователь
Сообщений: Регистрация: 26.11.2025
09.01.2026 13:21:00
Цитата
Nikolay написал: Например, если поля broker_comission и broker_comission_currency не важны, то этот второй вызов бесполезен, а если важны, то уже нет.
Речь о том, как проигнорировать бесполезный вызов и не посчитать дважды то, что нужно? Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают (спрашивал об этом вот здесь: ). Значит нужно вводить отдельную переменную - количество акций, и при каждом OnTrade обновлять. Но тогда при повторном OnTrade происходит повторное обновление, и пожалуйста - ошибка.
Речь о том, как проигнорировать бесполезный вызов и не посчитать дважды то, что нужно? Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают (спрашивал об этом вот здесь: ). Значит нужно вводить отдельную переменную - количество акций, и при каждом OnTrade обновлять. Но тогда при повторном OnTrade происходит повторное обновление, и пожалуйста - ошибка.
Ошибка т.к. обработка наивная:
pos = pos + sign*traded.qty
Естественно при таком подходе повторный вызов даст искажение данных. А если обработка более сложная, то не будет ошибки. Это уже вопрос реализации, зависящий от конкретной задачи.
Пользователь
Сообщений: Регистрация: 15.06.2023
09.01.2026 14:25:26
Цитата
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;
написал: Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают
Вы подняли очень важный вопрос. Он касается широкого круга пользователей, и широко обсуждался на форуме и приводились различные боевые подходы. На Ваш вопрос выше, ответ нужно организовывать внутренний учет, не только количества но и других параметров зависящих от конкретной сделки сделки (допустим усреднялись). Вот пример подхода которым, часто пользуюсь на скоростных скриптах:
Код
Спасибо. Принцип такого костыля понятен, но очень надеялся, что можно как-то проще. Видимо нельзя.
Пользователь
Сообщений: Регистрация: 15.06.2023
09.01.2026 15:29:03
User12501, И это еще не вся проблематика, ведь нужно данные периодически синхронизировать с данными QUIK.
написал: Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают
Вы подняли очень важный вопрос. Он касается широкого круга пользователей, и широко обсуждался на форуме и приводились различные боевые подходы. На Ваш вопрос выше, ответ нужно организовывать внутренний учет, не только количества но и других параметров зависящих от конкретной сделки сделки (допустим усреднялись). Вот пример подхода которым, часто пользуюсь на скоростных скриптах:
Кстати раз уж вы выложили код, есть вопрос по вот этой строке. Сейчас проверил в тех сделках, которые у себя отлавливал: там есть поле broker_comission, которое я воспринимал как итоговую сумму всех комиссий. И оно больше, чем написанная вами сумма. Например для одного лота MOEX: tech_center_comission = 0 clearing_comission = 0.22 exchange_comission = 0.3 broker_comission = 1.57
Проверка по остатку на счёте показывает, что 1.57 - точное значение итоговой комиссии, т.е. уже включает в себя всё остальное (и ещё что-то).
Пользователь
Сообщений: Регистрация: 15.06.2023
09.01.2026 15:55:59
Привел Вам просто базовую свою заготовку, в качестве примера не более. Если вы пишите на луа 5.4, то нужно отказаться от bit.band в пользу продвинутого метода. Что там точно за комиссии, подсказать тоже не могу так как на каждом рынке есть особенности. Для Фондового API QUIK предлагает предварительный расчет через стандартную функцию. Для оценки можно ее воспользоваться. На срочном есть зависимость от гарантийного обеспечения и курсов ... Что касается моего подхода, то я применяю подход Ральфа Винса, а именно, торговый капитал делю изначально на две части: пассивный и активный. Так как в процессе торговле всегда присутствует пассивная часть, нет необходимости вести четкий учет комиссий, сверяю по клирингу. Здесь более важен учет количества и цены, так как на прямую влияют на управление позицией.