Обсуждение статьи "Готовые советники из Мастера MQL5 работают в MetaTrader 4"

 

Опубликована статья Готовые советники из Мастера MQL5 работают в MetaTrader 4:

В статье предлагается простой эмулятор торгового окружения MetaTrader 5 для MetaTrader 4. С его помощью выполняются перенос и адаптация торговых классов стандартной библиотеки. В результате советники, генерируемые в Мастере MetaTrader 5, могут компилироваться и запускаться без изменений в MetaTrader 4.

На графике EURUSD M15 торговля данного эксперта выглядит нормально, включая, в частности, установку уровней стоп-лосса и тейк-профита.

Окно с графиком, иллюстрирующем работу эксперта из Мастера MetaTrader 5 в MetaTrader 4

Окно с графиком, иллюстрирующим работу эксперта из Мастера MetaTrader 5 в MetaTrader 4

Автор: Stanislav Korotky

Готовые советники из Мастера MQL5 работают в MetaTrader 4
Готовые советники из Мастера MQL5 работают в MetaTrader 4
  • 2017.03.09
  • Stanislav Korotky
  • www.mql5.com
В статье предлагается простой эмулятор торгового окружения MetaTrader 5 для MetaTrader 4. С его помощью выполняются перенос и адаптация торговых классов стандартной библиотеки. В результате советники, генерируемые в Мастере MetaTrader 5, могут компилироваться и запускаться без изменений в MetaTrader 4.
 

А‌втору Спасибо!

MT4-юзеры установят MT5 хотя бы ради Визарда - хитрый маркетинг? Лишь отчасти.

Сейчас статья удовлетворяет любопытство программеров - как же реализовано? Но не юзеров.

Маркетинг требует еще статьи уже другого уровня, где просто пошагово будет расписано, что куда нажать, чтобы Визард заработал в MT4.

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

 
fxsaber:

А‌втору Спасибо!

MT4-юзеры установят MT5 хотя бы ради Визарда - хитрый маркетинг? Лишь отчасти.

Сейчас статья удовлетворяет любопытство программеров - как же реализовано? Но не юзеров.

Маркетинг требует еще статьи уже другого уровня, где просто пошагово будет расписано, что куда нажать, чтобы Визард заработал в MT4.

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

Написать - не проблема. Только по объему на статью вряд ли потянет. По сути эта инфа уже есть в статье и занимает пару параграфов.

Р‌ади точности отмечу, что визард НЕ заработает в МТ4, такой визард есть только в МТ5. Заработать должны сгенерированные эксперты, но вероятно не все.

 

Для сравнения предлагаю взять триал Tick Data Suite (Compatible: MT4 build 940 – 1052).

В MT5-тестере выбрать режим "по реальным тикам". Сохранить их и через TDS скормить MT4-тестеру.

Т‌огда котиры в обоих тестерах будут совпадать на 100%, что позволит уже точно сравнить их не только по сделкам, но и по скорости.

М‌ожно было бы тогда сравнить конвертацию/создание советников в обе стороны.

 

Есть такое явление, как публикация в кодобазе советников, как результат конвертации MT4 -> MT5 через СБ.

Похоже, статью можно использовать и таким авторам для самопроверки. Если конвертация правильная, то обратная конвертация через MT5Bridge должна дать идентичный с MT4-оригиналом результат.

 
fxsaber:

Есть такое явление, как публикация в кодобазе советников, как результат конвертации MT4 -> MT5 через СБ.

Похоже, статью можно использовать и таким авторам для самопроверки. Если конвертация правильная, то обратная конвертация через MT5Bridge должна дать идентичный с MT4-оригиналом результат.

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

MT4-Tester VS MT5-Tester

fxsaber, 2017.05.08 15:12

Сконвертировал Ваш код в MT4 через MT5Bridge. MT4build1072

EURUSD,M1: 1865415 tick events (7292 bars, 1865515 bar states) processed in 0:00:07.645 (total time 0:00:08.362)


Оригинальный код

EURUSD,M1: 1865415 tick events (7292 bars, 1865515 bar states) processed in 0:00:03.744 (total time 0:00:04.493)


Результаты после конвертации идентичны! Скорость упала в два раза.

 

Мой MT5 советник (сгенерированный, но со своей реализацией CExpertSignal вместо стандартных индикаторов) с вашими инклудами скомпилился и тестировался на MT4 без проблем, спасибо!

Но вот сейчас отправил советник на реал, и оказалось что он совсем не торгует. Никаких ошибок, ничего не показывает. Просто не торгует. Долго копался в коде, нашёл причину - функция bool CTrade::FillingCheck(const string symbol) в Trade.mqh

Для рыночных ордеров срабатывает такая проверка - 

// get possible filling policy types by symbol
  uint filling = (uint)SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
  // check execution mode again
  if(exec == SYMBOL_TRADE_EXECUTION_MARKET)
  {
    // for the MARKET execution mode
    // analyze order
    if(m_request.action != TRADE_ACTION_PENDING)
    {
      // in case of instant execution order
      // if the required filling policy is supported, add it to the request
      if(m_type_filling == ORDER_FILLING_FOK && (filling & SYMBOL_FILLING_FOK) != 0)
      {
        m_request.type_filling = m_type_filling;
        return(true);
      }
      if(m_type_filling == ORDER_FILLING_IOC && (filling & SYMBOL_FILLING_IOC) != 0)
      {
        m_request.type_filling = m_type_filling;
        return(true);
      }
      // wrong filling policy, set error code
      m_result.retcode = TRADE_RETCODE_INVALID_FILL;
      return(false);
    }
    return(true);
  }

В моём случае и m_type_filling и filling равны нулю, поэтому функция возвращает false.
filling по логике кода не должен быть равен нулю, но согласно справке SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE) для MT4 не поддерживается. Поэтому в тестере проверка почему-то проходит, и может быть у некоторых брокеров на реале тоже. Но для меня не прокатило, я пока-что просто поменял функцию чтоб весь код пропускался и из функции возвращалось true.

 
Dr. Trader:

Для рыночных ордеров срабатывает такая проверка - 

В моём случае и m_type_filling и filling равны нулю, поэтому функция возвращает false.
filling по логике кода не должен быть равен нулю, но согласно справке SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE) для MT4 не поддерживается. Поэтому в тестере проверка почему-то проходит, и может быть у некоторых брокеров на реале тоже. Но для меня не прокатило, я пока-что просто поменял функцию чтоб весь код пропускался и из функции возвращалось true.

Спасибо за сообщение. Я на такое не натыкался. Данный метод оставлен без изменений. Видимо, нужно все filling переменные устанавливать в конкретные константы в зависимости от типа ордера и/или инструмента (вероятно, это нельзя вытащить через API никак, а тестер пользуется какими-то умолчаниями). Если кто-то знает, как МТ4 внутри себя выбирает filling - поделитесь.

 
Stanislav Korotky:

Если кто-то знает, как МТ4 внутри себя выбирает filling - поделитесь.

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

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

fxsaber, 2017.02.25 16:12

// Возвращает тип исполнения ордера, равный Type, если он доступен на символе Symb, иначе - корректный вариант.
ENUM_ORDER_TYPE_FILLING GetFilling( const string Symb, const uint Type = ORDER_FILLING_FOK )
{
  const ENUM_SYMBOL_TRADE_EXECUTION ExeMode = (ENUM_SYMBOL_TRADE_EXECUTION)::SymbolInfoInteger(Symb, SYMBOL_TRADE_EXEMODE);
  const int FillingMode = (int)::SymbolInfoInteger(Symb, SYMBOL_FILLING_MODE);

  return((FillingMode == 0 || (Type >= ORDER_FILLING_RETURN) || ((FillingMode & (Type + 1)) != Type + 1)) ?
         (((ExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (ExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ?
           ORDER_FILLING_RETURN : ((FillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) :
          (ENUM_ORDER_TYPE_FILLING)Type);
}
Применение
Request.type_filling = GetFilling(Request.symbol);
Не проверял, исправили ли баг со стоповыми отложками.
 
fxsaber:

Спасибо, можно этот код чуть изменить чтоб получить аналог SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE) для MT4. Нужно чтоб функция возвращала не ENUM_ORDER_TYPE_FILLING а (SYMBOL_FILLING_FOK | SYMBOL_FILLING_IOC).

ORDER_FILLING_FOK = 0, ORDER_FILLING_IOC = 1, в то время как SYMBOL_FILLING_FOK = 1 и SYMBOL_FILLING_IOC = 2, так что можно результат просто увеличить на 1.

//фунция возвращает symbol filling mode, он же SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE) для MT4.
//Параметр Type - order filling type
uint GetSymbolFilling( const string Symb, const uint Type = ORDER_FILLING_FOK )
{
  const ENUM_SYMBOL_TRADE_EXECUTION ExeMode = (ENUM_SYMBOL_TRADE_EXECUTION)::SymbolInfoInteger(Symb, SYMBOL_TRADE_EXEMODE);
  const int FillingMode = (int)::SymbolInfoInteger(Symb, SYMBOL_FILLING_MODE);

  return ((FillingMode == 0 || (Type >= ORDER_FILLING_RETURN) || ((FillingMode & (Type + 1)) != Type + 1)) ?
         (((ExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (ExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ?
           ORDER_FILLING_RETURN : ((FillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) :
          (ENUM_ORDER_TYPE_FILLING)Type) + 1;
}

И потом вызывать код в функции bool CTrade::FillingCheck(const string symbol)

uint filling = GetSymbolFilling(symbol, m_type_filling);
//вместо
//uint filling = (uint)SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);


Хотя на самом деле это просто подгонка кода чтоб заработало. Лучше так не делать а найти правильное решение.

Причина обращения: