Ошибки, баги, вопросы - страница 3202

 
Volodymyr Zubov #:

Я не понимаю зачем вы это делаете, ищете скрупулёзно баги ? Идеально ничего не будет, если ищут то находят баги и в CPU, но миллиарды умеют в такой среде работать и весь мир не идеален!

Никто специально баги не ищет, но программисты периодически наталкиваются на них. 
 
Andrey Dik #:

вот именно. у меня первой мысль была именно такой.
OrderSend () заявлена как синхронная функция, в этом её несомненная прелесть, но ведёт себя так не у всех брокеров.

Большое спасибо за логи и код - в них содержится вся необходимая информация для обсуждения.

Функция OrderSend() во всех случаях отработала в соответствии с документацией, т.е. правильно. И вернула в каждом из случаев всё, что могла на момент выполнения. Я ниже попробую объяснить, почему так считаю и в чем её отличие от асинхронной версии. Если я в чём то не прав - буду очень благодарен, если меня поправят. Понимание схемы работы этих функций очень важно для меня, т.к. позволяет избежать ошибок в работе роботов.

Схема взаимосвязи терминала со Срочной секцией MOEX. В части работы OrderSend() и OrderSendAsync() нет разницы какой брокер/биржа рассматриваются:

|       зона ответственности Биржи        ||                       зона ответственности Брокера                                ||        интернет       ||      клиент     |    

[биржа (MOEX)] <==> [шлюз Plaza2]   <===>  [шлюз в MOEX] <=> [MT5 торговый сервер] <=> [Точка доступа]  <================>      [Терминал]  -   true OrderSend()

[биржа ( MOEX)] <==> [шлюз Plaza2]  <===>  [шлюз в MOEX] <=> [MT5 торговый сервер] <=> [Точка доступа]  <================>      [Терминал]  -   true OrderSendAsync()

Золотым цветом выделена зона успешного выполнения OrderSend() и  OrderSendAsync(), т.е. участок, который выполнен успешно, в случае, если они вернули true.

Цена рыночной сделки (и она сама) формируется на бирже (в данном случае MOEX).  OrderSend() в нормальной ситуации, не должен возвращать цену и тикет сделки т.к. сам о ней пока ничего не знает. Сделка происходит позже и в нормальном случае - в другом месте (не на сервере МТ5).

Ваши логи подтверждают схему выше, кроме одного случая - в котором [MT5 торговый сервер] знает цену сразу - т.е. дальше запрос скорее всего уже не идет (это догадки). Я кстати, не утверждаю, что это плохо. Схемы работы "брокера" бывают разные, у всех есть свои достоинства и недостатки.

То что левее  [MT5 торговый сервер]  во всех случаях разное. Каждый брокер городит свою инфраструктуру, как может.

Вся инфа на основе анализа/наблюдений и из открытых источников.

 
Andrey Miguzov #:

Ваши логи подтверждают схему выше, кроме одного случая - в котором [MT5 торговый сервер] знает цену сразу - т.е. дальше запрос скорее всего уже не идет (это догадки). Я кстати, не утверждаю, что это плохо. Схемы работы "брокера" бывают разные, у всех есть свои достоинства и недостатки.

а что мешает брокеру отправить ответ уже после того, как заявка будет исполнена, или же сообщение об ошибке? - хитропопость?))

 
Andrey Dik #:

а что мешает брокеру отправить ответ уже после того, как заявка будет исполнена, или же сообщение об ошибке? - хитропопость?))

Так он и отправляет. Когда сам получит её. Но это уже к OrderSend() не имеет отношение.

Практический вывод - после  OrderSend() результат быстрее всего можно получить в OnTrade(), ну или ждать по аналогии с проверочным кодом выше. 

А на структуру возврата лучше основную логику алгоритма не завязывать.  

Но Вы это и без меня знаете. Я думаю у Вас завязка на структуру возврата связана с каким-то замороченным алгоритмом или чужим кодом.

 
Andrey Dik #:

2022.06.14 21:43:06.321 sTestGetDealPrice (EURUSD,M1) ----------------------Just2Trade Online Ltd----------------------
2022.06.14 21:43:06.321 sTestGetDealPrice (EURUSD,M1) Ask: 1.04177 Bid: 1.04167 цена для сделки: 1.04177
2022.06.14 21:43:06.321 sTestGetDealPrice (EURUSD,M1) Buy
2022.06.14 21:43:06.545 sTestGetDealPrice (EURUSD,M1) Успешный OrderSend ()!
2022.06.14 21:43:06.545 sTestGetDealPrice (EURUSD,M1) retcode         : 10009
2022.06.14 21:43:06.545 sTestGetDealPrice (EURUSD,M1) deal            : 0
2022.06.14 21:43:06.545 sTestGetDealPrice (EURUSD,M1) order           : 80163272

Как и предполагалось, сделки не было. Ордер отправлен, его тикет есть. Но по какой цене он реально исполнится, еще не известно.

Хочешь трушный синхронный ордерсенд — запили его сам с помощью предложенного бесконечного цикла.

 
Andrey Miguzov #:

Так он и отправляет. Когда сам получит её. Но это уже к OrderSend() не имеет отношение.

Практический вывод - после  OrderSend() результат быстрее всего можно получить в OnTrade(), ну или ждать по аналогии с проверочным кодом выше. 

А на структуру возврата лучше основную логику алгоритма не завязывать.  

Но Вы это и без меня знаете. Я думаю у Вас завязка на структуру возврата связана с каким-то замороченным алгоритмом или чужим кодом.

так вот и хотелось бы изменить это. зачем трейдеру все промежуточные шаги от отправки торгового приказа до приходя отчета об итогах сделки? - тем более если трейдер никак на это повлиять не может!))) для более детального ковыряния в процессах торговли есть специализированные функции OrderSendAsync() и типа OnTrade().

OrderSend () должен быть полностью синхронным, трейдер отправил приказ а назад получить отчет о результатах сделки и всех промежуточных шагов брокера, поставщика ликвидности и за что вообще захочет отчитываться брокер. Всё.

Andrey Khatimlianskii #:

Хочешь трушный синхронный ордерсенд — запили его сам с помощью предложенного бесконечного цикла.

 мы программисты - народ плечистый, запилено уже давно. но не правильно это, не по людски как то.

 
Andrey Khatimlianskii #:

Хочешь трушный синхронный ордерсенд — запили его сам

Есть даже стресс-тест, который трушный синхронный OrderSend не пройдет.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Великий и ужасный МТ4 навсегда (или как грамотно выработать стратегию перехода)

fxsaber, 2021.05.05 02:04

// Демонстрация открытия дубля позиции в MT5.

#include <Trade\Trade.mqh>

void OnStart()
{
  CTrade Trade;
  
  while (!IsStopped() && (PositionsTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (PositionsTotal() == 1)
      Trade.PositionClose(PositionGetTicket(0)); // Если есть позиция - закрываем.
    else if (!OrdersTotal())
      Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
}

Запустите этот код на пустом демо-счете и убедитесь в открытии двух позиций через несколько секунд.


Эта же логика на MT4 выглядит так.

void OnStart()
{
  while (!IsStopped() && (OrdersTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0) // Если есть позиция - закрываем.
    else
      OrderSend(_Symbol, OP_BUY, 0.01, Ask, 0, 0, 0) // Если нет позиции и ордера - открываем позицию.
}

Понятно, что такой код на MT4 не вызовет задвоения позиции. Но не на MT5.

Потому что в MT5 асинхронность повсюду:

  1. Был выставлен BuyLimit1.
  2. Когда цена до него дошла, он был отправлен на исполнение.
  3. В определенный момент в Терминале не стало открытого BuyLimit1, но и Buy1 не появился.
  4. В этой ситуации (отсутствие отложенного ордера и позиции) ТС выставляет новый BuyLimit2, т.к. того требует торговая логика.
  5. Появляется Buy1-позиция.
  6. Выставленный BuyLimit2 отправляется брокером на исполнение и порождает Buy2.
  7. Как итог, был изначально только BuyLimit1, а стало две позиции: Buy1 и Buy2.
Проверка на наличие дублей ордеров/позиций в MT5
Проверка на наличие дублей ордеров/позиций в MT5
  • 2021.09.12
  • www.mql5.com
Появление дублей ордеров/позиций в MT5 - архитектурная особенность платформы, с которой многие сталкиваются. Данная неприятность вызывает серьезные перекосы в торговых рисках, ломает логику, усложняет
 
fxsaber #:

Есть даже стресс-тест, который трушный синхронный OrderSend не пройдет.

Потому что в MT5 асинхронность повсюду:

вот. так к чему в добавок к  OrderSendAsync() ещё и НедоSendAsync ()?

подобное положение вещей порождает кучу проблем и торговых рисков там, где казалось бы проблем быть недолжно никогда и ни при каких обстоятельствах, если торговая логика чуть сложнее, чем торговля по MA.

 
Andrey Dik #:

так вот и хотелось бы изменить это. зачем трейдеру все промежуточные шаги от отправки торгового приказа до приходя отчета об итогах сделки? - тем более если трейдер никак на это повлиять не может!))) для более детального ковыряния в процессах торговли есть специализированные функции OrderSendAsync() и типа OnTrade().

OrderSend () должен быть полностью синхронным, трейдер отправил приказ а назад получить отчет о результатах сделки и всех промежуточных шагов брокера, поставщика ликвидности и за что вообще захочет отчитываться брокер. Всё.

наличие OrderSendSync() в дополнение к имеющимся OrderSend() и OrderSendAsync() упростило бы код в простых/односимвольных экспертах.

Но у меня голова уже "заточилась" под текущую/имеющуюся схему работы и она кажется мне вполне удобной.

OrderSend() точно переделывать не надо.

 
Andrey Dik #:

вот. так к чему в добавок к  OrderSendAsync() ещё и НедоSendAsync ()?

подобное положение вещей порождает кучу проблем и торговых рисков там, где казалось бы проблем быть недолжно никогда и ни при каких обстоятельствах, если торговая логика чуть сложнее, чем торговля по MA.

Именно базовые функции терминала разработчиков MT не сильно беспокоят. Какие-то рюшечки будут пилить, а базовый функционал - нет.
Вот и сейчас, реакции от разрабов за несколько дней не последовало, хотя, стоило прокомментировать ситуацию с псевдоасинхронной функцией.
Оно и понятно, не от доходов трейдеров живёт индустрия, а наоборот. 
Причина обращения: