Появление дублей ордеров/позиций в MT5 - архитектурная особенность платформы, с которой многие сталкиваются. Данная неприятность вызывает серьезные перекосы в торговых рисках, ломает логику, усложняет код в попытках обойти и иногда замедляет работу кода, когда пытаются "пересидеть" неудобные моменты неопределенности в платформе.
Чтобы понять, что это за дубли, можно запустить лаконичный код воспроизведения. К счастью, было найдено удобное решение, которое позволило практически забыть про основную проблему. Причем сделать это бесплатно для пользователя, скрывая всю работу от его глаз, за счет симбиоза с библиотекой MT4Orders.
Примененный механизм синхронизации торгового окружения был также распространен на методы работы через снепшоты. В общем, даже для взыскательного программиста все стало просто. Но если захотеть разобраться, как же на самом деле все работает, будет очень трудно.
Сложный код.
В качестве примера сложного торгового кода когда-то был представлен скрипт. Он стал серьезной причиной улучшения MT5.
К данной заметке приложен другой короткий, но тоже сложный скрипт-анализатор. Скрипт выдает подозрительные места задвоения ордеров/позиций и тем самым помогает разобраться, проявлялась ли проблема или нет.
Поиск.
Довольно проблематично посчитать, сколько совершил сделок в MT5 на реальных счетах. Но точно больше миллиона. Поэтому неплохая историческая база для анализа присутствует.
Поиск подозрительных дублей на разных счетах иногда заканчивался успешно - были найдены дубли. Это капля в море, но та капля, что может испортить всю торговлю.
Пример.
Приведу кусок результата работы скрипта.
3217964 - 3218078 #3217964 2021.08.02 23:55:12.972 sell limit 0.10 GBPJPY 151.817 0.000 151.799 2021.08.03 01:00:01.513 151.756 0.00 0.00 0.00 2;[0] 2 #3218078 2021.08.02 23:55:13.111 sell limit 0.10 GBPJPY 151.817 0.000 151.799 2021.08.03 01:00:01.415 151.756 0.00 0.00 0.00 2 2 3345363 - 3345505 #1969732 2021.08.11 23:01:29.885 buy 0.65 GBPJPY 153.131 0.000 153.122 2021.08.12 03:51:18.637 153.122 -3.60 -7.20 -5.30 4;[+1] 4 #1969733 2021.08.11 23:01:30.008 buy 0.65 GBPJPY 153.131 0.000 153.122 2021.08.12 03:51:18.637 153.122 -3.60 -7.20 -5.30 4;[0] 4
Здесь показаны две проблемы: задвоение отложенных ордеров и дубль позиции. Очевидно, что это крайне нежелательные спутники любой ТС.
Анализ.
Попробуем разобраться в причинах задвоения позиции. Для этого введем соответствующий тикет во входные скрипта.
На выходе такие подробности.
3345363 - 3345505 #1969732 2021.08.11 23:01:29.885 buy 0.65 GBPJPY 153.131 0.000 153.122 2021.08.12 03:51:18.637 153.122 -3.60 -7.20 -5.30 4;[+1] 4 OpenTicket = 3345363, Magic = 4, Type = ORDER_TYPE_BUY_LIMIT, State = ORDER_STATE_FILLED, Reason = ORDER_REASON_EXPERT, 2021.08.11 23:00:16.948 - 2021.08.11 23:01:29.885, Lots = 0.00/0.65 CloseTicket = 3352934, Magic = 4, Type = ORDER_TYPE_SELL, State = ORDER_STATE_FILLED, Reason = ORDER_REASON_TP, 2021.08.12 03:51:18.584 - 2021.08.12 03:51:18.637, Lots = 0.00/0.65 #1969733 2021.08.11 23:01:30.008 buy 0.65 GBPJPY 153.131 0.000 153.122 2021.08.12 03:51:18.637 153.122 -3.60 -7.20 -5.30 4;[0] 4 OpenTicket = 3345505, Magic = 4, Type = ORDER_TYPE_BUY_LIMIT, State = ORDER_STATE_FILLED, Reason = ORDER_REASON_EXPERT, 2021.08.11 23:01:29.916 - 2021.08.11 23:01:30.008, Lots = 0.00/0.65 CloseTicket = 3352936, Magic = 4, Type = ORDER_TYPE_SELL, State = ORDER_STATE_FILLED, Reason = ORDER_REASON_TP, 2021.08.12 03:51:18.585 - 2021.08.12 03:51:18.637, Lots = 0.00/0.65
Цветом выделил места, анализ которых позволил (вкупе с разбором торговых логов) сделать следующий вывод.
- Был выставлен BuyLimit1.
- Когда цена до него дошла, он был отправлен на исполнение.
- В определенный момент в Терминале не стало открытого BuyLimit1, но и Buy1 не появился.
- В этой ситуации (отсутствие отложенного ордера и позиции) ТС выставляет новый BuyLimit2, т.к. того требует торговая логика.
- Появляется Buy1-позиция.
- Выставленный BuyLimit2 отправляется брокером на исполнение и порождает Buy2.
- Как итог, был изначально только BuyLimit1, а стало две позиции: Buy1 и Buy2.
Лог этой ситуации.
2021.08.11 23:00:18.056 Trades '': buy limit 0.65 GBPJPY at 153.133 tp: 153.198 2021.08.11 23:00:18.094 Trades '': accepted buy limit 0.65 GBPJPY at 153.133 tp: 153.198 2021.08.11 23:00:18.098 Trades '': order #3345363 buy limit 0.65 / 0.65 GBPJPY at 153.133 done in 43.832 ms 2021.08.11 23:01:30.183 Trades '': failed modify order #3345363 buy limit 0.65 GBPJPY at 153.13200 sl: 0.00000 tp: 153.19700 -> 153.13100, sl: 0.00000 tp: 153.19700 [Invalid request] 2021.08.11 23:01:31.016 Trades '': failed modify order #3345363 buy limit 0.65 GBPJPY at 153.13200 sl: 0.00000 tp: 153.19700 -> 153.13100, sl: 0.00000 tp: 153.19700 [Invalid request] 2021.08.11 23:01:31.023 Trades '': buy limit 0.65 GBPJPY at 153.131 tp: 153.197 2021.08.11 23:01:31.024 Trades '': deal #1967630 buy 0.65 GBPJPY at 153.131 done (based on order #3345363) 2021.08.11 23:01:31.036 Trades '': accepted buy limit 0.65 GBPJPY at 153.131 tp: 153.197 2021.08.11 23:01:31.039 Trades '': order #3345505 buy limit 0.65 / 0.65 GBPJPY at 153.131 done in 16.477 ms
Сценарии задвоения, конечно, могут быть разными.
Для кого все это?
Начал с истории написания замечательного синхронизатора торгового окружения не просто так. Он, действительно, показал себя очень эффективно - более 99.9% возможных задвоений нивелирует. Однако, не 100%. И что-то проскакивает, говоря о том, что механизм не совершенен и автору надо разбираться.
Однако, любой может проверить на своей истории наличие проблемы. Если скрипт ничего не выведет - все отлично. В противном случае, как минимум, есть повод поинтересоваться проблемой и методами ее решения, не обязательно вникая в их сложную внутреннюю реализацию.
За счет Маркета у кого-то есть обширные базы для различных проверок. Возможно, этот вариант - один из них.