Что-то не получается у меня пояснить, видимо. Вот реальный пример. Вот такой код:
voidOnTradeTransaction(constMqlTradeTransaction& trans,
constMqlTradeRequest& request,
constMqlTradeResult& result)
{
Count++;
Print("Ontrade_test = ",Count);
}
Обработчик стоит в двух советниках, при совершении 1 сделки он отрабатывается множество раз в двух советниках. Код выдает:
18:31:06.495 ontrade_trans_functions (MXI-12.17,H1) Ontrade_test = 118:31:06.495 ontrade_trans_functions2 (MXI-12.17,H1) Ontrade_test = 118:31:06.497 ontrade_trans_functions (MXI-12.17,H1) Ontrade_test = 218:31:06.497 ontrade_trans_functions2 (MXI-12.17,M5) Ontrade_test = 218:31:06.498 ontrade_trans_functions (MXI-12.17,M5) Ontrade_test = 318:31:06.498 ontrade_trans_functions2 (MXI-12.17,H1) Ontrade_test = 318:31:06.500 ontrade_trans_functions (MXI-12.17,M5) Ontrade_test = 418:31:06.500 ontrade_trans_functions2 (MXI-12.17,H1) Ontrade_test = 4 ...
и так далее.
Видно, что время отработки OnTradeTransaction в двух советниках совпадает до миллисекунд. Вот и возник вопрос, событие "сделка" приходит вначале в один OnTradeTransaction в одном советнике, затем в следующий в другом советнике или каким-то образом параллельно сразу во все обработчики во всех советниках поступает? Ну типа параллельная многопоточная работа или как это называется в программировании. Я уверен, что все происходит последовательно, просто отрабатыается быстро в одну миллисекунду, но на всякий случай спросил.
voidOnTradeTransaction(constMqlTradeTransaction& trans,
constMqlTradeRequest& request,
constMqlTradeResult& result)
{
// Здесь надо поставить фильтр по типу транзакции// По символу и магику// и только если всё совпало, тогда
Count++; Print("Ontrade_test = ",Count);
}
Видно, что время отработки OnTradeTransaction в двух советниках совпадает до миллисекунд. Вот и возник вопрос, событие "сделка" приходит вначале в один OnTradeTransaction в одном советнике, затем в следующий в другом советнике или каким-то образом параллельно сразу во все обработчики во всех советниках поступает? Ну типа параллельная многопоточная работа или как это называется в программировании. Я уверен, что все происходит последовательно, просто отрабатыается быстро в одну миллисекунду, но на всякий случай спросил.
Обработчик OnTradeTransaction для ОДНОГО символа (m_symbol.Name()) и одного magic'a (m_magic).
Отлавливаем сначала транзакцию
TRADE_TRANSACTION_DEAL_ADD
Добавление сделки в историю. Осуществляется в результате исполнения ордера или проведения операций с балансом счета.
затем смотрим, чтобы это была сделка
DEAL_ENTRY_OUT
Выход из рынка
//+------------------------------------------------------------------+//| TradeTransaction function |//+------------------------------------------------------------------+voidOnTradeTransaction(constMqlTradeTransaction &trans,
constMqlTradeRequest &request,
constMqlTradeResult &result)
{
//--- get transaction type as enumeration value ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in historyif(type==TRADE_TRANSACTION_DEAL_ADD)
{
long deal_ticket =0;
long deal_order =0;
long deal_time =0;
long deal_time_msc =0;
long deal_type =-1;
long deal_entry =-1;
long deal_magic =0;
long deal_reason =-1;
long deal_position_id =0;
double deal_volume =0.0;
double deal_price =0.0;
double deal_commission =0.0;
double deal_swap =0.0;
double deal_profit =0.0;
string deal_symbol ="";
string deal_comment ="";
string deal_external_id ="";
if(HistoryDealSelect(trans.deal))
{
deal_ticket =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
deal_order =HistoryDealGetInteger(trans.deal,DEAL_ORDER);
deal_time =HistoryDealGetInteger(trans.deal,DEAL_TIME);
deal_time_msc =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);
deal_type =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
deal_entry =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
deal_magic =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
deal_reason =HistoryDealGetInteger(trans.deal,DEAL_REASON);
deal_position_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
deal_volume =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
deal_price =HistoryDealGetDouble(trans.deal,DEAL_PRICE);
deal_commission =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);
deal_swap =HistoryDealGetDouble(trans.deal,DEAL_SWAP);
deal_profit =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
deal_symbol =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
deal_comment =HistoryDealGetString(trans.deal,DEAL_COMMENT);
deal_external_id =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);
}
elsereturn;
if(deal_reason!=-1)
DebugBreak();
if(deal_symbol==m_symbol.Name() && deal_magic==m_magic)
if(deal_entry==DEAL_ENTRY_OUT)
{
}
}
}
Обработчик OnTradeTransaction для ОДНОГО символа (m_symbol.Name()) и одного magic'a (m_magic).
Отлавливаем сначала транзакцию
TRADE_TRANSACTION_DEAL_ADD
Добавление сделки в историю. Осуществляется в результате исполнения ордера или проведения операций с балансом счета.
затем смотрим, чтобы это была сделка
DEAL_ENTRY_OUT
Выход из рынка
Здравствуйте, коллеги.
Столкнулся с ситуацией, когда событие TRADE_TRANSACTION_DEAL_ADD для одной и той же сделки "отлавливается" несколько раз. Не всегда, но регулярно.
Написал все проверки, но сделка определённо одна и та же. Работает вот такой код
//+------------------------------------------------------------------+//| TradeTransaction function |//+------------------------------------------------------------------+voidOnTradeTransaction(constMqlTradeTransaction &trans,
constMqlTradeRequest &request,
constMqlTradeResult &result) {
//--- get transaction type as enumeration valueENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in historyif(type==TRADE_TRANSACTION_DEAL_ADD) {
printf("%s: deal: %I64u order: %I64u volume: %.6f", __FUNCTION__, trans.deal, trans.order, trans.volume);
if(HistoryDealSelect(trans.deal))
m_deal.Ticket(trans.deal);
elsereturn;
printf("%s: Deal Select ticket_limit_up: %I64u ticket_limit_down: %I64u", __FUNCTION__, gl_ticket_limit_up, gl_ticket_limit_down);
printf("%s: Deal Entry: %s Deal Type: %s", __FUNCTION__, EnumToString(m_deal.Entry()), EnumToString(trans.deal_type));
if(trans.order==gl_ticket_limit_up) {
double volume_position=m_deal.Volume();
for(int i=0; i<3; i++)
if(NormalizeDouble(symbol_data_up[i].volume, 2)>0.0) {
printf("%s: up %d symbol: %s symbol_volume: %.6f volume_position: %.6f", __FUNCTION__, i, symbol_data_up[i].symbol, symbol_data_up[i].volume, volume_position);
Fn_position_open(symbol_data_up[i].symbol, symbol_data_up[i].is_buy, symbol_data_up[i].volume*volume_position);
}
}
if(trans.order==gl_ticket_limit_down) {
double volume_position=m_deal.Volume();
for(int i=0; i<3; i++)
if(NormalizeDouble(symbol_data_down[i].volume, 2)>0.0) {
printf("%s: down %d symbol: %s symbol_volume: %.6f volume_position: %.6f", __FUNCTION__, i, symbol_data_down[i].symbol, symbol_data_down[i].volume, volume_position);
Fn_position_open(symbol_data_down[i].symbol, symbol_data_down[i].is_buy, symbol_data_down[i].volume*volume_position);
}
}
}
}
Для понимания, та же ли это ловится сделка, проверяю её тикет и свойства. Это отложенный лимитный ордер срабатывает по частям, брокер Открытие. Логи получаю следующие
Выделил, где несколько раз ловилась одна и та же сделка. Там ещё сделки 17157068 и 17157069 несколько раз ловилась, не стал уж выделять. По таймингу это происходит практически мгновенно.
У меня вопрос, разве не должна функция только один раз отлавливать событие? Или ещё какую то проверку нужно сделать?
Столкнулся с ситуацией, когда событие TRADE_TRANSACTION_DEAL_ADD для одной и той же сделки "отлавливается" несколько раз. Не всегда, но регулярно.
Написал все проверки, но сделка определённо одна и та же. Работает вот такой код
Для понимания, та же ли это ловится сделка, проверяю её тикет и свойства. Это отложенный лимитный ордер срабатывает по частям, брокер Открытие. Логи получаю следующие
Выделил, где несколько раз ловилась одна и та же сделка. Там ещё сделки 17157068 и 17157069 несколько раз ловилась, не стал уж выделять. По таймингу это происходит практически мгновенно.
У меня вопрос, разве не должна функция только один раз отлавливать событие? Или ещё какую то проверку нужно сделать?
Я тоже не замечал ранее такого поведения функции OnTradeTransaction. Но в этом советнике требуется открыть позиции по другим инструментам объёмом, пропорционально сработавшему объёму отложенному ордеру. И косяк сразу всплыл. По другим инструментам пошли бОльшие объёмы, чем требовалось.
Вы можете повторить частичное исполнение ордера? Попробуйте поставить в режиме отладки поставив точку останова на строке
и потом пройдите пошагово наблюдая тип транзакции, тикет сделки и всё что можно посмотреть…
У меня ни разу не получалось неоднократное выполнение OnTradeTransaction() с типом TRADE_TRANSACTION_DEAL_ADD
Конечно если в ордере 3 лота, а выполняется 3 раза по 1 лоту, то и выполнение TRADE_TRANSACTION_DEAL_ADD должно быть трижды. Но никак не больше.
Конечно, если речь про ордер то трижды. Я пишу про сделку. По каждой сделке должно быть одно срабатывание. А там несколько, и это видно в логах (номер сделки один, это тоже видно). Отложенный ордер там был № 823878027 (14 лотов), и это не все логи его открытия. Там 7 лотов уходило на закрытие BUY (они и отражены в логах) и остальные 7 на открытие SELL, переворот был. Со сделки № 17157069 началось открытие SELL. Можно несложно посчитать, учитывая задублированные срабатывания по сделкам, что 7 (первая сделка 3 лота, остальные по 1) лотов закрыли BUY, и далее пошло открытие.
Но в логах ясно видно, что срабатывание функции OnTradeTransaction по типу TRADE_TRANSACTION_DEAL_ADD происходит для одной сделки несколько раз. Мне не к чему в режиме отладки смотреть, я и так всё вижу по результату и по логам.
Я тоже не замечал ранее такого поведения функции OnTradeTransaction. Но в этом советнике требуется открыть позиции по другим инструментам объёмом, пропорционально сработавшему объёму отложенному ордеру. И косяк сразу всплыл. По другим инструментам пошли бОльшие объёмы, чем требовалось.
Конечно, если речь про ордер то трижды. Я пишу про сделку. По каждой сделке должно быть одно срабатывание. А там несколько, и это видно в логах (номер сделки один, это тоже видно). Отложенный ордер там был № 823878027 (14 лотов), и это не все логи его открытия. Там 7 лотов уходило на закрытие BUY (они и отражены в логах) и остальные 7 на открытие SELL, переворот был. Со сделки № 17157069 началось открытие SELL. Можно несложно посчитать, учитывая задублированные срабатывания по сделкам, что 7 (первая сделка 3 лота, остальные по 1) лотов закрыли BUY, и далее пошло открытие.
Но в логах ясно видно, что срабатывание функции OnTradeTransaction по типу TRADE_TRANSACTION_DEAL_ADD происходит для одной сделки несколько раз. Мне не к чему в режиме отладки смотреть, я и так всё вижу по результату и по логам.
Вот даже как… Оказывается не просто 14 лотов, а ещё и закрытие… Так и отсеивайте по DEAL_ENTRY_IN или DEAL_ENTRY_OUT, а потом можно выбрать все ордера и сделки по ID позиции и проверить и количество и объёмы и всё что нужно. В распечатке только последняя сделка DEAL_ENTRY_IN, а все предыдущие DEAL_ENTRY_OUT. Вот их и надо посчитать сколько лотов набралось…
Я не сталкивался с частичным исполнением, с уверенностью не знаю может-ли быть тикет сделки один… Тут все карты в ваших руках… Только многократными проверками можно всё понять…
Что-то не получается у меня пояснить, видимо. Вот реальный пример. Вот такой код:
и так далее.
Видно, что время отработки OnTradeTransaction в двух советниках совпадает до миллисекунд. Вот и возник вопрос, событие "сделка" приходит вначале в один OnTradeTransaction в одном советнике, затем в следующий в другом советнике или каким-то образом параллельно сразу во все обработчики во всех советниках поступает? Ну типа параллельная многопоточная работа или как это называется в программировании. Я уверен, что все происходит последовательно, просто отрабатыается быстро в одну миллисекунду, но на всякий случай спросил.
Что-то не получается у меня пояснить, видимо. Вот реальный пример. Вот такой код:
void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
Count++;
Print("Ontrade_test = ",Count);
}
Обработчик стоит в двух советниках, при совершении 1 сделки он отрабатывается множество раз в двух советниках. Код выдает:
18:31:06.495 ontrade_trans_functions (MXI-12.17,H1) Ontrade_test = 1
18:31:06.495 ontrade_trans_functions2 (MXI-12.17,H1) Ontrade_test = 1
18:31:06.497 ontrade_trans_functions (MXI-12.17,H1) Ontrade_test = 2
18:31:06.497 ontrade_trans_functions2 (MXI-12.17,M5) Ontrade_test = 2
18:31:06.498 ontrade_trans_functions (MXI-12.17,M5) Ontrade_test = 3
18:31:06.498 ontrade_trans_functions2 (MXI-12.17,H1) Ontrade_test = 3
18:31:06.500 ontrade_trans_functions (MXI-12.17,M5) Ontrade_test = 4
18:31:06.500 ontrade_trans_functions2 (MXI-12.17,H1) Ontrade_test = 4 ...
и так далее.
Видно, что время отработки OnTradeTransaction в двух советниках совпадает до миллисекунд. Вот и возник вопрос, событие "сделка" приходит вначале в один OnTradeTransaction в одном советнике, затем в следующий в другом советнике или каким-то образом параллельно сразу во все обработчики во всех советниках поступает? Ну типа параллельная многопоточная работа или как это называется в программировании. Я уверен, что все происходит последовательно, просто отрабатыается быстро в одну миллисекунду, но на всякий случай спросил.
Обработчик OnTradeTransaction для ОДНОГО символа (m_symbol.Name()) и одного magic'a (m_magic).
Отлавливаем сначала транзакцию
TRADE_TRANSACTION_DEAL_ADD
Добавление сделки в историю. Осуществляется в результате исполнения ордера или проведения операций с балансом счета.
затем смотрим, чтобы это была сделка
DEAL_ENTRY_OUT
Выход из рынка
Событие OnTradeTransaction - широковещательное, туда "валятся" все действия, которые совершаются Вашим терминалом.
Просто каждый советник должен фильтровать свои действия.
далее в каждом типе мы фильтруем по тикету, если ассинхронная отправка ордера, то
сначала по request ID получаем тикет, а затем по тикету фильтруем.
Событие TRADE_TRANSACTION_REQUEST всегда приходит первым, остальные "как захотят"
Добавлено
Всё это уже много раз обсуждалось
Поищите в разделе "Биржевой трейдинг"
Спасибо, вроде, получается "записывать" нужные сделки.
Обработчик OnTradeTransaction для ОДНОГО символа (m_symbol.Name()) и одного magic'a (m_magic).
Отлавливаем сначала транзакцию
TRADE_TRANSACTION_DEAL_ADD
Добавление сделки в историю. Осуществляется в результате исполнения ордера или проведения операций с балансом счета.
затем смотрим, чтобы это была сделка
DEAL_ENTRY_OUT
Выход из рынка
Здравствуйте, коллеги.
Столкнулся с ситуацией, когда событие TRADE_TRANSACTION_DEAL_ADD для одной и той же сделки "отлавливается" несколько раз. Не всегда, но регулярно.
Написал все проверки, но сделка определённо одна и та же. Работает вот такой код
Для понимания, та же ли это ловится сделка, проверяю её тикет и свойства. Это отложенный лимитный ордер срабатывает по частям, брокер Открытие. Логи получаю следующие
Выделил, где несколько раз ловилась одна и та же сделка. Там ещё сделки 17157068 и 17157069 несколько раз ловилась, не стал уж выделять. По таймингу это происходит практически мгновенно.
У меня вопрос, разве не должна функция только один раз отлавливать событие? Или ещё какую то проверку нужно сделать?
Здравствуйте, коллеги.
Столкнулся с ситуацией, когда событие TRADE_TRANSACTION_DEAL_ADD для одной и той же сделки "отлавливается" несколько раз. Не всегда, но регулярно.
Написал все проверки, но сделка определённо одна и та же. Работает вот такой код
Для понимания, та же ли это ловится сделка, проверяю её тикет и свойства. Это отложенный лимитный ордер срабатывает по частям, брокер Открытие. Логи получаю следующие
Выделил, где несколько раз ловилась одна и та же сделка. Там ещё сделки 17157068 и 17157069 несколько раз ловилась, не стал уж выделять. По таймингу это происходит практически мгновенно.
У меня вопрос, разве не должна функция только один раз отлавливать событие? Или ещё какую то проверку нужно сделать?
Не знаю, но я вижу три функции печати
И три записи одновременно
Если это условие выполнено, то выполняются следующие две функции печати…
Все правильно вы пишите. Только суть не уловили. А она в том, что функция OnTradeTransaction по условию (событию)
Вы можете повторить частичное исполнение ордера? Попробуйте поставить в режиме отладки поставив точку останова на строке
и потом пройдите пошагово наблюдая тип транзакции, тикет сделки и всё что можно посмотреть…
У меня ни разу не получалось неоднократное выполнение OnTradeTransaction() с типом TRADE_TRANSACTION_DEAL_ADD
Конечно если в ордере 3 лота, а выполняется 3 раза по 1 лоту, то и выполнение TRADE_TRANSACTION_DEAL_ADD должно быть трижды. Но никак не больше.
Я тоже не замечал ранее такого поведения функции OnTradeTransaction. Но в этом советнике требуется открыть позиции по другим инструментам объёмом, пропорционально сработавшему объёму отложенному ордеру. И косяк сразу всплыл. По другим инструментам пошли бОльшие объёмы, чем требовалось.
Вы можете повторить частичное исполнение ордера? Попробуйте поставить в режиме отладки поставив точку останова на строке
и потом пройдите пошагово наблюдая тип транзакции, тикет сделки и всё что можно посмотреть…
У меня ни разу не получалось неоднократное выполнение OnTradeTransaction() с типом TRADE_TRANSACTION_DEAL_ADD
Конечно если в ордере 3 лота, а выполняется 3 раза по 1 лоту, то и выполнение TRADE_TRANSACTION_DEAL_ADD должно быть трижды. Но никак не больше.
Конечно, если речь про ордер то трижды. Я пишу про сделку. По каждой сделке должно быть одно срабатывание. А там несколько, и это видно в логах (номер сделки один, это тоже видно). Отложенный ордер там был № 823878027 (14 лотов), и это не все логи его открытия. Там 7 лотов уходило на закрытие BUY (они и отражены в логах) и остальные 7 на открытие SELL, переворот был. Со сделки № 17157069 началось открытие SELL. Можно несложно посчитать, учитывая задублированные срабатывания по сделкам, что 7 (первая сделка 3 лота, остальные по 1) лотов закрыли BUY, и далее пошло открытие.
Но в логах ясно видно, что срабатывание функции OnTradeTransaction по типу TRADE_TRANSACTION_DEAL_ADD происходит для одной сделки несколько раз. Мне не к чему в режиме отладки смотреть, я и так всё вижу по результату и по логам.
Я тоже не замечал ранее такого поведения функции OnTradeTransaction. Но в этом советнике требуется открыть позиции по другим инструментам объёмом, пропорционально сработавшему объёму отложенному ордеру. И косяк сразу всплыл. По другим инструментам пошли бОльшие объёмы, чем требовалось.
Конечно, если речь про ордер то трижды. Я пишу про сделку. По каждой сделке должно быть одно срабатывание. А там несколько, и это видно в логах (номер сделки один, это тоже видно). Отложенный ордер там был № 823878027 (14 лотов), и это не все логи его открытия. Там 7 лотов уходило на закрытие BUY (они и отражены в логах) и остальные 7 на открытие SELL, переворот был. Со сделки № 17157069 началось открытие SELL. Можно несложно посчитать, учитывая задублированные срабатывания по сделкам, что 7 (первая сделка 3 лота, остальные по 1) лотов закрыли BUY, и далее пошло открытие.
Но в логах ясно видно, что срабатывание функции OnTradeTransaction по типу TRADE_TRANSACTION_DEAL_ADD происходит для одной сделки несколько раз. Мне не к чему в режиме отладки смотреть, я и так всё вижу по результату и по логам.
Вот даже как… Оказывается не просто 14 лотов, а ещё и закрытие… Так и отсеивайте по DEAL_ENTRY_IN или DEAL_ENTRY_OUT, а потом можно выбрать все ордера и сделки по ID позиции и проверить и количество и объёмы и всё что нужно. В распечатке только последняя сделка DEAL_ENTRY_IN, а все предыдущие DEAL_ENTRY_OUT. Вот их и надо посчитать сколько лотов набралось…
Я не сталкивался с частичным исполнением, с уверенностью не знаю может-ли быть тикет сделки один… Тут все карты в ваших руках… Только многократными проверками можно всё понять…