Обсуждение статьи "Переход с MQL4 на MQL5"

 

Опубликована статья Переход с MQL4 на MQL5:

У большинства разработчиков торговых стратегий накопились целые коллекции индикаторов и советников на языке MQL4. Переход на новую платформу МТ5 без них теряет смысл. Заново всё переписывать очень утомительно. Вот если бы был словарь-переводчик с одной версии языка на другую, да ещё с примерами.

Данная статья, построенная в форме справочника по функциям MQL4, призвана помочь переходу с MQL4 на MQL5. Для каждой функции языка MQL4 приведено описание и представлен способ ее реализации на MQL5, что позволит вам значительно ускорить перевод своих программ с MQL4 на MQL5. Для удобства функции разбиты на группы, как в документации по MQL4.

Автор: Sergey

 

вы уверенны что это работает????

при простой компиляции уже возникат вопрос

а во вторых что вернёт эта функция!

     CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMaximum(Close,start,count));

копируем цены закрытия в массив клозе, копируем с позиции "старт" и количество "коунт" правильно

и возвращает индекс  максимального элемента массива Клозе начиная с позиции "старт" и смотря только "коунт" элементов.....

ваше что за ересь простите за откровенность..... 

 

 
В тех клетках таблиц, где написано "Аналога нет" надо бы давать краткое описание, как теперь данные вещи решаются в mql5 с ссылками на конкретный раздел документации (что-то вроде, например, такого: "не имеет смысла, так как в mql5 то-то и то-то").

 
CoreWinTT:

вы уверенны что это работает????

 Да, работает.

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                                                 Copyright DC2008 |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "DC2008"
//--- Массивы-таймсерии
double            Close[];
double            Open[];
double            High[];
double            Low[];
long              Volume[];
datetime          Time[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArraySetAsSeries(Close,true);
   ArraySetAsSeries(Open,true);
   ArraySetAsSeries(High,true);
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Volume,true);
   ArraySetAsSeries(Time,true);
   ArraySetAsSeries(Low,true);

//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   Comment(
           "\niHighest",iHighest("EURUSD",PERIOD_M2,0,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,0,10,0),"   Open",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,1,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,1,10,0),"   Low",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,2,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,2,10,0),"   High",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,3,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,3,10,0),"   Close",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,4,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,4,10,0),"   Volume",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,5,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,5,10,0),"   Time",
           "\n",""
           );

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int iLowest(string symbol,
            int tf,
            int type,
            int count=WHOLE_ARRAY,
            int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMinimum(Open,start,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMinimum(Low,start,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMinimum(High,start,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMinimum(Close,start,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMinimum(Volume,start,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMinimum(Time,start,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int iHighest(string symbol,
             int tf,
             int type,
             int count=WHOLE_ARRAY,
             int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMaximum(Open,start,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMaximum(Low,start,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMaximum(High,start,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMaximum(Close,start,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMaximum(Volume,start,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMaximum(Time,start,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES TFMigrate(int tf)
{
   switch(tf)
   {
      case 0: return(PERIOD_CURRENT);
      case 1: return(PERIOD_M1);
      case 5: return(PERIOD_M5);
      case 15: return(PERIOD_M15);
      case 30: return(PERIOD_M30);
      case 60: return(PERIOD_H1);
      case 240: return(PERIOD_H4);
      case 1440: return(PERIOD_D1);
      case 10080: return(PERIOD_W1);
      case 43200: return(PERIOD_MN1);      
      default: return(PERIOD_CURRENT);
   }
}

 

 
marketeer:
В тех клетках таблиц, где написано "Аналога нет" надо бы давать краткое описание, как теперь данные вещи решаются в mql5 с ссылками на конкретный раздел документации (что-то вроде, например, такого: "не имеет смысла, так как в mql5 то-то и то-то").

 

Надо понимать так: реализация слишком сложная и не оправдана. Всё-таки цель - полностью отказаться от функций MQL4.

А то что бы ссылки дать на те функции MQL5 с помощью которых что-то подобное можно сделать, то это постараюсь учесть.

 

берем данный с ТФ м2 правильно я понимаю

но это типа бросить пыль в глаза ТФ миграйте выдаёт нам 

  default: return(PERIOD_CURRENT);

с 0 бара как странно

а если попробовать с 20 например

что опять запутать пытаетесь

и такая ересь в каждой функции

и зачем делать ТФ миграйте???

если в mql5 есть все ТФ что и в mql4 даже больше.....

полная ересь =)))

как ваше модераторы такое пропустили

уважаемый Евгений! надеюсь не вы проверяли данную статью.

 
CoreWinTT:

полная ересь =)))

как ваше модераторы такое пропустили

уважаемый Евгений! надеюсь не вы проверяли данную статью.

Уважаемый Василий!

Спасибо Вам за замечания, функции раздела 18 обновлены. Просим Вас проверить текущий вариант.

Автор проделал огромную работу, могут быть ошибки, их мы исправим совместными усилиями.

Функция TFMigrate(int tf) нужна для подстановки корректных значений таймфреймов MQL5. Например в MQL4 численное значение константы PERIOD_H1 равно 60, а в MQL5 численное значение PERIOD_H1=16385, т.е. TFMigrate(60)=16385.

 

думаю там ещё много ошибок.

так как возникают даже в таких простых моментах. я бы даже сказал наипростещих.


в одних разделал функции сравниваться друг с другом

в других пишется аналог


нет ни одного удачного примера внедрения статьи,

насколько я понимаю в данной статье пыла предпринята попытка перенести что то с мкл4....


ваше отношение к проверке всегда вызывает восхищение.

думаю здесь сказывается безудержное желание автора бросить пыль в глаза

что ему несомненно удалось.

так как знаю вашу щепетильность к проверяемому материалу.

 
CoreWinTT:


а если попробовать с 20 например

что опять запутать пытаетесь

и такая ересь в каждой функции

и зачем делать ТФ миграйте???

если в mql5 есть все ТФ что и в mql4 даже больше.....

полная ересь =)))


Спасибо за найденную ошибку. Я упустил из вида, что поиск можно начать не с нулевого бара. Вот исправленные функции:

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                                                 Copyright DC2008 |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "DC2008"
//--- Массивы-таймсерии
double            Close[];
double            Open[];
double            High[];
double            Low[];
long              Volume[];
datetime          Time[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArraySetAsSeries(Close,true);
   ArraySetAsSeries(Open,true);
   ArraySetAsSeries(High,true);
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Volume,true);
   ArraySetAsSeries(Time,true);
   ArraySetAsSeries(Low,true);

//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   Comment(Open[0],Close[0],Open[1],Close[1],
           "\niHighest",iHighest("EURUSD",PERIOD_M2,0,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,0,10,20),"   Open",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,1,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,1,10,20),"   Low",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,2,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,2,10,20),"   High",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,3,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,3,10,20),"   Close",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,4,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,4,10,20),"   Volume",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,5,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,5,10,20),"   Time",
           "\n",""
           );

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int iLowest(string symbol,
            int tf,
            int type,
            int count=WHOLE_ARRAY,
            int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMinimum(Open,0,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMinimum(Low,0,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMinimum(High,0,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMinimum(Close,0,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMinimum(Volume,0,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMinimum(Time,0,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int iHighest(string symbol,
             int tf,
             int type,
             int count=WHOLE_ARRAY,
             int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMaximum(Open,0,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMaximum(Low,0,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMaximum(High,0,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMaximum(Close,0,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMaximum(Volume,0,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMaximum(Time,0,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES TFMigrate(int tf)
{
   switch(tf)
   {
      case 0: return(PERIOD_CURRENT);
      case 1: return(PERIOD_M1);
      case 5: return(PERIOD_M5);
      case 15: return(PERIOD_M15);
      case 30: return(PERIOD_M30);
      case 60: return(PERIOD_H1);
      case 240: return(PERIOD_H4);
      case 1440: return(PERIOD_D1);
      case 10080: return(PERIOD_W1);
      case 43200: return(PERIOD_MN1);      
      default: return(PERIOD_CURRENT);
   }
}
 
CoreWinTT:

думаю там ещё много ошибок.

так как возникают даже в таких простых моментах. я бы даже сказал наипростещих.


в одних разделал функции сравниваться друг с другом

в других пишется аналог


нет ни одного удачного примера внедрения статьи,

насколько я понимаю в данной статье пыла предпринята попытка перенести что то с мкл4....


ваше отношение к проверке всегда вызывает восхищение.

думаю здесь сказывается безудержное желание автора бросить пыль в глаза

что ему несомненно удалось.

так как знаю вашу щепетильность к проверяемому материалу.


Ошибки могут быть, материал достаточно большой.

Тема переноса (точнее тема написания класса-эмулятора с методами MQL4) была предпринята в другой статье (надеемся, она будет закончена), в процессе ознакомления с материалом мы попросили автора написать статью в виде справочника, чтобы охватить все функции MQL4 (кроме торговых-одно из решений для них Вы скоро увидите), для каждой привести аналог на MQL5, в общем собрать все вместе чтобы те, кто переписывает программы c MQL4 могли быстро найти аналог. О безудержном желании, если речь идет о количестве рассмотренных разделов - мы настояли на охватите всех функций (их получилось более 250).

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

По этой причине (архитектура функций эмулятора) у автора в реализации были некоторые неочевидные вещи (например для iLowest/iHighest раньше использовались глобальные Open[]...High[]..., которые предварительно объявлялись глобально и делались AsSeries в OnInit), которые подразумевались как в эмуляторе, естесственно для универсальности в функциях лучше использовать локальные массивы.

По поводу работы с техническими индикаторами - тоже может быть множество вопросов, работа с ними не должна быть как в MQL4, - их лучше создавать руками в OnInit и обращаться к дескрипторами, а не создавать их каждый раз в как локальных функциях. Но предложенный автором подход также работает, поскольку терминал не сразу уничтожает индикаторы. Так что тонкостей много.

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

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