Особенности языка mql5, тонкости и приёмы работы

 
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql5, примеры решения тех, или иных задач. Хотелось бы, чтобы эта ветка была по содержанию ближе к FAQ, чем к обсуждению. Предлагаю всем опытным программистам делиться найденными решениями и приёмами программирования. Особенно приветствуется освещение не описанных в справке возможностей.
 
fxsaber:

при успешном открытии позиции маркет-ордером каждый раз получается нулевой Result.deal?

Из СД
Заполнение тикета результирующей сделки не гарантировано. Заполнение или не заполнение зависит от режима исполнения инструмента и настроек конкретного сервера.
Кто закладывался на ненулевой Result.deal - примите меры.
 
После выполнения OrderSend обращение к соответствующим ордеру, позиции или сделке не всегда успешно. Бывают ситуации, когда нужно подождать несколько десятков миллисекунд, пока историческая или текущая торговая информация станет корректной.
 
fxsaber:
После выполнения OrderSend обращение к соответствующим ордеру, позиции или сделке не всегда успешно. Бывают ситуации, когда нужно подождать несколько десятков миллисекунд, пока историческая или текущая торговая информация станет корректной.
то же и в МТ4 встречается, зависит от конкретного сервера
 
Не всегда возможно узнать цену ордера, который породил сделку
 
Не всегда возможно узнать SL/TP-уровни закрытой позиции.

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

TakeProfit (и StopLoss) закрытой позиции

fxsaber, 2016.07.17 20:19

До введения хэджа TakeProfit открытых позиций хранились не на бирже в виде лимитных ордеров, а на MT5-торговом сервере. При этом в момент акцепта они отправлялись на биржу не как лимитные ордера по заявленной цене, а как маркет-ордера по заявленной цене.

Эта особенность очень хорошо видна в тестере, когда срабатывает TP: появляется соответствующий маркет-ордер (а не limit). Поскольку takeprofit - это не существующий биржевой вид ордеров (есть только маркеты и лимитные), то такое положение вещей вполне укладывалось в "рыночность".

С появлением хэджа ситуация не изменилась - takeprofit остались виртуальными. При этом в MT4 ситуация иная: за многие годы существования MT4-мостов стало стандартом, что MT4-takeprofit - это лимитные ордера.

Именно из-за этой виртуальности, как шлейф, тянутся некоторые особенности MT5. Мало того, что takeprofit в MT5 лучше не выставлять, если вы хотите лимитный аналог, то после закрытия позиции вы никак через MQL5 не сможете узнать ее значения takeprofit и stoploss.

Это не огульные обвинения, а результат многочасовых попыток разобраться (никакие HistorySelectByPosition и прочее не помогают), как же все работает. И я готов с радостью принести свои извинения, если ошибаюсь. Чтобы не быть голословным привожу советник для тестера (так проще разобраться) на сервере RoboForexEU-MetaTrader 5, который открывает позицию, затем ставит SL и TP-уровни.

void OnTick()
{
  static bool Flag = true;

  if (Flag)
  {
    // Открываем SELL-позицию
    MqlTradeRequest Request = {0};

    Request.action = TRADE_ACTION_DEAL;

    Request.symbol = Symbol();
    Request.volume = 1;
    Request.price = SymbolInfoDouble(Symbol(), SYMBOL_BID);

    Request.type = ORDER_TYPE_SELL;

    MqlTradeResult Result;

    if (OrderSend(Request, Result))
    {
      // Устанавливаем SL и TP
      Request.position = Result.deal;

      Request.action = TRADE_ACTION_SLTP;

      Request.tp = Result.ask - 10 * _Point;
      Request.sl = Result.ask + 10 * _Point;

      if (OrderSend(Request, Result))
        Print("Сделка в тестере закроется либо по SL, TP, либо по окончании бэктеста")    ;

      Flag = false;
    }
  }
}

В этом советнике невозможно определить (в OnDeinit) SL и TP единственной закрытой позиции. Это так задумано?


Из цитаты так же следует, что TP позиции в MT5 - всегда маркет-ордер. Не закладывайетсь на лимитный аналог - см. выше.
 

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

Ошибки, баги, вопросы

Slawa, 2017.02.14 13:46

Зачем? Достаточно однократного действия.

И пока символ выбран в обзоре рынка и история по символу удерживается экспертом, то она поддерживается в синхронизированном состоянии. Удержание экспертом означает не реже 1 раза в 2 минуты обращаться к этой истории, например копированием одного бара. Если история синхронизирована, то на копирование одного бара время не тратится - всего несколько тактов процессора. Либо, как тут только что сказали, спрашивать количество баров, тоже несколько тактов

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

Ошибки, баги, вопросы

Alexey Kozitsyn, 2017.02.14 13:47

К индикаторам относится интервал в 2 минуты?

Да, а проверкой факта синхронизации синхронизация также будет удерживаться?

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

Ошибки, баги, вопросы

Slawa, 2017.02.14 13:50

К индикаторам тоже относится. Создайте 1-минутный таймер и спрашивайте количество баров у всех интересующих Вас таймсерий.

Проверкой факта синхронизированности синхронизация не удерживается.

 
fxsaber:
После выполнения OrderSend обращение к соответствующим ордеру, позиции или сделке не всегда успешно. Бывают ситуации, когда нужно подождать несколько десятков миллисекунд, пока историческая или текущая торговая информация станет корректной.

Да не надо ждать несколько миллисекунд.

Сообщение придёт в OnTradeTransaction 

см. код 

Файлы:
 
prostotrader:

Да не надо ждать несколько миллисекунд.

Сообщение придёт в OnTradeTransaction 

см. код 

В скриптах этого нет. Вместо скрипта использовать связку советник+ExpertRemove глупо.

Более того, OrderSend вываливается по таймауту, если нет ответа от сервера 180 секунд. Это говорит о том, что в OnTradeTransaction могут скапливаться вечно ожидаемые тикеты. И вариант всего одного order_ticket для OnTradeTransaction, как в скрипте у Вас, плох. После асинхронной отправки идет работа со списков ордеров. На то она и асинхронная, чтобы работать с пачками. А если работы с пачками нет, то асинхронность никогда не нужна.

 
MT4-OrderClosePrice-фишка работает и в MT5 - PositionGetDouble(POSITION_PRICE_CURRENT).