Откройте демо счет ФОРТС (фьючерсы) в Открытии или БКС и посмотрите, как
нужно пользоваться функциями.
Добавлено
Если ничего не приходит в OnTradeTransaction (в коде этого нет)
То включается механизм проверки что случилось с ордером.
Если есть ордер, то ищем по ордеру, если нет ордера, то ищем по уникальному magic.
Принцип - каждому ордеру присваивается уникальный magic, по которому
идет проверка что произошло с ордером (в коде есть "ошметки" как это делается mem_time - для проверки интервала времени, mem_start_time - для
поиска ордера в узком отрезке времени,
magic_storage - для хранения текущего magic). Automagic.mqh позволяет генерить уникальный начальный magic для символа и советника,
Да хранение - не проблема. Это все есть. Проблема как раз в привязке (см. временную диаграмму выше).
Функция OrderSendAsync не возвращает ТИКЕТ в 70-80% случаев;
Функция OrderSendAsync гарантированно (я надеюсь) возвращает только request_id;
Транзакции торгового исполнения (первые 4-ре) можно привязать только по ТИКЕТУ;
А ТИКЕТ появляется в конце, когда уже торговое исполнение прошло...
На мой взгляд, как бы я реализовал требуемый функционал. 1. Для каждого источника сигнала создал бы свою структуру для
хранения данных по сделкам. 2. Для каждой заявки генерировал бы уникальный меджик и сохранял его в соответствующей сигналу
структуре. 3. Не ждал бы возврата от OrderSendAsync после отправки заявки. А искал бы тикет ордера в OnTradeTransaction
по уникальному меджику. 4. После получения тикета не проблема идентифицировать все сделки, связанные с данным ордером.
В качестве примера прилагаю лог реальных транзакций. Жирным зеленым цветом выделял для себя значимые данные, которые требуется
анализировать. Красным цветом выделены данные не несущие полезной информациии.
Вы не первый. Почитайте посты Михаила. Он много об
этом писал здесь несколько лет назад. Ему вроде попробовали отвечать разрабы, но поезд и ныне там. И он кстати тоже использует
асинхронную отправку заявок.
Василий, спасибо, почитал... Отрадно что не я один спотыкаюсь об это, но печально что движения нет со стороны разработчиков. Хотя я их понимаю.
Людей, которые обращаются к асинхронной модели - единицы...
Не испытывал совсем проблем с OrderSend. Возможно, по причине отсутствия MOEX.
Но если бы нужен был OrderSendAsync, то не использовал бы OnTradeTransaction, а воспользовался бы подобным
решением.
За месяц до этого трэда я тоже не испытывал... Но когда OrderSend стали зависать по минуте, а потом возвращаются еще и с ошибкой, решил
сделать шаг в сторону асинхронной модели (уж коль 9 и 10-ти шагов уже было сделано, ну или я так думал).
Отличный код, как всегда, в прочем... Спасибо. Хотя это и псевдо-асинхронная модель из-за использования OnTimer, если быть дотошным, что, на мой
взгляд, немного избыточно, но зато универсально (будет работать и на МТ4). В остальном, наши с Вами мысли совпадают (я планировал
использовать связанный список, поскольку fifo тут и не пахло). Поскольку у меня нет задачи обеспечить мульти-платформенность, а
ограничивают событиями OnTradeTransaction и OnTick, хотя я думаю что первичным источником событий всегда выступает OnTick.
По своей невнимательности не увидел, что разработчики MT, как впрочем и все мы, пытаются минимизировать трудозатраты. В результате
ответа, как такового, на request нет. Они сразу пытаются его исполнить, поэтому сначала идут "Транзакции торгового исполнения", и лишь в
конце цепочки, сразу кучей, отправляют ответ и на request и на result, из-за чего один хрен придется ждать TRADE_TRANSACTION_REQUEST, что
возвращает нас, практически, к функциональности OrderSend.
Давно бы сделал двунаправленный связанный буфер транзакций, но останавливает факт, что имею очень вычислительно-нагруженную среду
обработки (куча дип-нетов, комитеты и сложная пред-обработка ценового ряда),.
В любом случае, спасибо. Было весьма познавательно и полезно )).
Никаких трудностей с получением тикета позиции не вижу.
Алексей, вы же понимаете, если написать 10 раз "я не понимаю в чём трудности" то это не приблизит Вас к пониманию?.. Я Вам уже временную диаграмму
нарисовал с ключами первичной идентификации. Даже не знаю, что я могу Вам написать, чтобы помочь с пониманием...
Ведь речь не о невозможности обработать эту ситуацию, а об усложнении обработки из-за упрощений, которые использовали разработчики МТ5 при
реализации асинхронки, выродив асинхронную модель в ту же синхронную...
Постараюсь еще раз пояснить... Ответа, как такового, на request нет. Сервер сразу пытаются его исполнить, поэтому сначала идут "Транзакции
торгового исполнения", и лишь в конце цепочки, сразу кучей, отправляют ответ и на request и на result, из-за чего один хрен придется ждать
ФИНАЛИЗИРУЮЩЕЙ транзакции - TRADE_TRANSACTION_REQUEST, что возвращает нас, практически, к функциональности OrderSend.
Что касается приведенного Вами кода, то он хуже, чем использование OrderSend, и вот почему:
Вы все равно дожидаетесь ФИНАЛИЗИРУЮЩЕЙ транзакции - TRADE_TRANSACTION_REQUEST, что собственно и делает OrderSend;
Но кроме этого вы еще нагружаете эксперт дополнительным двойным вызовом поиска через HistoryOrder*** для получения тикета сделки,
что OrderSend сделает это гораздо быстрее.
Ну и я не большой сторонник использования функций HistoryХХХХХ. При большой динамике торговых транзакций они начинают ощутимо
притормаживать.
Согласитесь, что было бы гораздо эффективнее сначала получить ответ на запрос, в котором вы могли бы обработать ошибки размещения, и в случае
успеха, поймать транзакцию TRADE_TRANSACTION_DEAL_ADD, что подтвердило бы вывод сделки в рынок, но...
Вместо этого мы с вами видим не идентифицированные торговые транзакции (ТТ) и ничего не можем с ними сделать до тех пор пока, в
ФИНАЛИЗИРУЮЩЕЙ транзакции - TRADE_TRANSACTION_REQUEST, не получим данные по их (ТТ) идентификации. И поскольку нет системы
сквозной идентификации транзакций, или хотя бы разделением ответов requet/result - асинхронке "грошь цена"...
На мой взгляд, как бы я реализовал требуемый функционал. 1. Для каждого источника сигнала создал бы свою структуру для
хранения данных по сделкам. 2. Для каждой заявки генерировал бы уникальный меджик и сохранял его в соответствующей сигналу
структуре. 3. Не ждал бы возврата от OrderSendAsync после отправки заявки. А искал бы тикет ордера в OnTradeTransaction
по уникальному меджику. 4. После получения тикета не проблема идентифицировать все сделки, связанные с данным ордером.
В качестве примера прилагаю лог реальных транзакций. Жирным зеленым цветом выделял для себя значимые данные, которые
требуется анализировать. Красным цветом выделены данные не несущие полезной информациии.
Владимир, это так не работает. Поясню попунктно...
Это очевидные вещи. Предлагаю на них не заострять внимание...
Мэджик не решает проблематики идентификации транзакций при их текущей очередности. Мэджик появляется только ФИНАЛИЗИРУЮЩЕЙ транзакции - TRADE_TRANSACTION_REQUEST.
Не очень понял что Вы имели ввиду. OrderSendAsync ждать невозможно. Он отправляет request и тут же возвращает управление.
торговые транзакции (ТТ) не имеют признака меджика - только тикет сделки.
Именно в этом и проблема, что без тикета сквозная идентификация невозможна... Связь между запросом и ТТ вы получите в финальной TRADE_TRANSACTION_REQUEST
Даже в Вашем же файле всю эту проблематику прекрасно видно... Он правда не очень подробный, но даже там это очевидно. Сначала идут ТТ и
финализируются структурами request/result, где и содержаться первичные идентификационные параметры
Ниже привожу блок транзакций, относящихся к открытию одной позиции. Первая часть - это ТТ, второй блок - финальная
TRADE_TRANSACTION_REQUEST. Все расположено в хронологическом порядке.
А теперь прошу, найдите в серии ТТ идентификационный признак, о котором вы говорите?! А я скажу, что кроме тикета сделки и ордера (а их связь
с вашим запросом появится только в финальной TRADE_TRANSACTION_REQUEST) вы ничего там не найдете.
Все, что у вас есть на момент окончания работы OrderSendAsync - Request ID. И где же он?! А он в
финальной TRADE_TRANSACTION_REQUEST.
Если true значит requestID 10009 и другого быть не может. В противном случае получим в trans.type ==TRADE_TRANSACTION_REQUEST requestID и
будем принимать решение.
Я усложнил задачу. Открытие трёх позиций асинхронно по трём валютам.
Благодарю, что хватило сил прочесть до конца ))
Вы просто не умеете пользоваться описанными Вами функциями.
Здесь https://www.mql5.com/ru/forum/38456/page136#comment_15425184 (прикрепленные файлы)
рабочий код. Там все предельно ясно.
Откройте демо счет ФОРТС (фьючерсы) в Открытии или БКС и посмотрите, как нужно пользоваться функциями.
Добавлено
Если ничего не приходит в OnTradeTransaction (в коде этого нет)
То включается механизм проверки что случилось с ордером.
Если есть ордер, то ищем по ордеру, если нет ордера, то ищем по уникальному magic.
Принцип - каждому ордеру присваивается уникальный magic, по которому
идет проверка что произошло с ордером (в коде есть "ошметки" как это делается mem_time - для проверки интервала времени, mem_start_time - для поиска ордера в узком отрезке времени,
magic_storage - для хранения текущего magic). Automagic.mqh позволяет генерить уникальный начальный magic для символа и советника,
позволяющий хранить 254 magic
Да хранение - не проблема. Это все есть. Проблема как раз в привязке (см. временную диаграмму выше).
На мой взгляд, как бы я реализовал требуемый функционал.
1. Для каждого источника сигнала создал бы свою структуру для хранения данных по сделкам.
2. Для каждой заявки генерировал бы уникальный меджик и сохранял его в соответствующей сигналу структуре.
3. Не ждал бы возврата от OrderSendAsync после отправки заявки. А искал бы тикет ордера в OnTradeTransaction по уникальному меджику.
4. После получения тикета не проблема идентифицировать все сделки, связанные с данным ордером.
В качестве примера прилагаю лог реальных транзакций.
Жирным зеленым цветом выделял для себя значимые данные, которые требуется анализировать.
Красным цветом выделены данные не несущие полезной информациии.
Вы не первый. Почитайте посты Михаила. Он много об этом писал здесь несколько лет назад. Ему вроде попробовали отвечать разрабы, но поезд и ныне там. И он кстати тоже использует асинхронную отправку заявок.
Василий, спасибо, почитал... Отрадно что не я один спотыкаюсь об это, но печально что движения нет со стороны разработчиков. Хотя я их понимаю. Людей, которые обращаются к асинхронной модели - единицы...
Не испытывал совсем проблем с OrderSend. Возможно, по причине отсутствия MOEX.
Но если бы нужен был OrderSendAsync, то не использовал бы OnTradeTransaction, а воспользовался бы подобным решением.
За месяц до этого трэда я тоже не испытывал... Но когда OrderSend стали зависать по минуте, а потом возвращаются еще и с ошибкой, решил сделать шаг в сторону асинхронной модели (уж коль 9 и 10-ти шагов уже было сделано, ну или я так думал).
Отличный код, как всегда, в прочем... Спасибо. Хотя это и псевдо-асинхронная модель из-за использования OnTimer, если быть дотошным, что, на мой взгляд, немного избыточно, но зато универсально (будет работать и на МТ4). В остальном, наши с Вами мысли совпадают (я планировал использовать связанный список, поскольку fifo тут и не пахло). Поскольку у меня нет задачи обеспечить мульти-платформенность, а ограничивают событиями OnTradeTransaction и OnTick, хотя я думаю что первичным источником событий всегда выступает OnTick.
По своей невнимательности не увидел, что разработчики MT, как впрочем и все мы, пытаются минимизировать трудозатраты. В результате ответа, как такового, на request нет. Они сразу пытаются его исполнить, поэтому сначала идут "Транзакции торгового исполнения", и лишь в конце цепочки, сразу кучей, отправляют ответ и на request и на result, из-за чего один хрен придется ждать TRADE_TRANSACTION_REQUEST, что возвращает нас, практически, к функциональности OrderSend.
Давно бы сделал двунаправленный связанный буфер транзакций, но останавливает факт, что имею очень вычислительно-нагруженную среду обработки (куча дип-нетов, комитеты и сложная пред-обработка ценового ряда),.
В любом случае, спасибо. Было весьма познавательно и полезно )).
Ну я не понимаю в чём трудности.
Вот код советника
И вот результат выполнения на счёте Netting.
Никаких трудностей с получением тикета позиции не вижу.
Алексей, вы же понимаете, если написать 10 раз "я не понимаю в чём трудности" то это не приблизит Вас к пониманию?.. Я Вам уже временную диаграмму нарисовал с ключами первичной идентификации. Даже не знаю, что я могу Вам написать, чтобы помочь с пониманием...
Ведь речь не о невозможности обработать эту ситуацию, а об усложнении обработки из-за упрощений, которые использовали разработчики МТ5 при реализации асинхронки, выродив асинхронную модель в ту же синхронную...
Постараюсь еще раз пояснить... Ответа, как такового, на request нет. Сервер сразу пытаются его исполнить, поэтому сначала идут "Транзакции торгового исполнения", и лишь в конце цепочки, сразу кучей, отправляют ответ и на request и на result, из-за чего один хрен придется ждать ФИНАЛИЗИРУЮЩЕЙ транзакции - TRADE_TRANSACTION_REQUEST, что возвращает нас, практически, к функциональности OrderSend.
Что касается приведенного Вами кода, то он хуже, чем использование OrderSend, и вот почему:
Согласитесь, что было бы гораздо эффективнее сначала получить ответ на запрос, в котором вы могли бы обработать ошибки размещения, и в случае успеха, поймать транзакцию TRADE_TRANSACTION_DEAL_ADD, что подтвердило бы вывод сделки в рынок, но...
Вместо этого мы с вами видим не идентифицированные торговые транзакции (ТТ) и ничего не можем с ними сделать до тех пор пока, в ФИНАЛИЗИРУЮЩЕЙ транзакции - TRADE_TRANSACTION_REQUEST, не получим данные по их (ТТ) идентификации. И поскольку нет системы сквозной идентификации транзакций, или хотя бы разделением ответов requet/result - асинхронке "грошь цена"...
Вы смотрели код, который я вам порекомендовал?
На мой взгляд, как бы я реализовал требуемый функционал.
1. Для каждого источника сигнала создал бы свою структуру для хранения данных по сделкам.
2. Для каждой заявки генерировал бы уникальный меджик и сохранял его в соответствующей сигналу структуре.
3. Не ждал бы возврата от OrderSendAsync после отправки заявки. А искал бы тикет ордера в OnTradeTransaction по уникальному меджику.
4. После получения тикета не проблема идентифицировать все сделки, связанные с данным ордером.
В качестве примера прилагаю лог реальных транзакций.
Жирным зеленым цветом выделял для себя значимые данные, которые требуется анализировать.
Красным цветом выделены данные не несущие полезной информациии.
Ниже привожу блок транзакций, относящихся к открытию одной позиции. Первая часть - это ТТ, второй блок - финальная TRADE_TRANSACTION_REQUEST. Все расположено в хронологическом порядке.
А теперь прошу, найдите в серии ТТ идентификационный признак, о котором вы говорите?! А я скажу, что кроме тикета сделки и ордера (а их связь с вашим запросом появится только в финальной TRADE_TRANSACTION_REQUEST) вы ничего там не найдете.
Все, что у вас есть на момент окончания работы OrderSendAsync - Request ID. И где же он?! А он в финальной TRADE_TRANSACTION_REQUEST.
Финальная TRADE_TRANSACTION_REQUEST. И вот, наконец, мы видем заветный Request ID, в связке с тикетами:
И только теперь мы можем связать прошедшие ранее транзакции с нашим запросом:
Все, что у вас есть на момент окончания работы OrderSendAsync - Request ID. И где же он?! А он в финальной TRADE_TRANSACTION_REQUEST.
А, простите, на кой дьявол вам requestID если в trans.type == TRADE_TRANSACTION_DEAL_ADD есть trans.position по которому можно проверить
Если true значит requestID 10009 и другого быть не может. В противном случае получим в trans.type ==TRADE_TRANSACTION_REQUEST requestID и будем принимать решение.
Для отложенных ордеров решение другое.
Ну, если вы так бьётесь за пару миллисекунд, то я умолкаю...
Ещё обратите внимание на статьи Артёма Тришкина. У него есть решение лучше, но сложное для моего возраста.
А, простите, на кой дьявол вам requestID ...
:)
А если отложенный ордер и исполнился не полным объемом?