文章 "从 MQL4 迁移到 MQL5"

 

新文章 从 MQL4 迁移到 MQL5已发布:

很多开发人员已经累积了很多用 MQL4 编写的指标和交易策略。要在 Metatrader 5 中使用它们,应将它们转换为 MQL5。用 MQL5 重写所有程序并不是如此容易。如果有转换参考,则进行转换会容易得多,最好以例子说明。

本文是 MQL4 语言函数的快速指南,帮助您将您的程序从 MQL4 迁移到 MQL5。介绍了每个 MQL4 函数(交易函数除外)的说明和 MQL5 实施,从而让您显著减少转换时间。出于方便起见,MQL4 函数被分为组,类似于 MQL4 参考。

作者:Sergey Pavlov

 

你确定它能工作吗????

一个简单的编译已经提出了问题

其次,这个函数会返回什么!

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

将收盘价复制到 Klose 数组中,从位置 "start "开始复制,并正确地复制 "Counts "的数量。

并返回 Klose数组中 最大元素 的索引,从 "起始 "位置开始,只查看 "计数 "元素......。

你的异端邪说是什么?抱歉我的直率.....

 
 
在表格中显示 "无类比 "的单元格中,您应该简要说明 mql5 是如何解决这些问题的,并引用文档中的特定部分(例如,类似这样的内容:"没有意义,因为在 mql5 中这样 那样")。
 
CoreWinTT:

你确定它有效吗????

是的,能用。

//+------------------------------------------------------------------+
//|测试。mq5
//|版权所有 DC2008
//|http://www.mql5.com ||
//+------------------------------------------------------------------+
#property copyright "DC2008"
//--- 时间序列数组
double            Close[];
double            Open[];
double            High[];
double            Low[];
long              Volume[];
datetime          Time[];
//+------------------------------------------------------------------+
//| 专家初始化函数|
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| 专家去初始化函数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| 专家勾选功能|
//+------------------------------------------------------------------+
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 函数 的链接,我会尽量考虑。

 

我们从 TF m2 中提取了这个。

TF迁移的结果是

  default: return(PERIOD_CURRENT);

从 0 bar 开始 这很奇怪

但如果我们试着从20巴开始计算

你又在迷惑我们。

每个函数中都有这样的废话。

为什么要进行 TF 迁移?

如果 mql5 拥有 mql4 甚至更多的所有 TF......。

完全是异端邪说 =))))

你们的版主怎么会错过这样的事情?

亲爱的尤金!我希望你不是检查这篇文章的人。

 
CoreWinTT:

完全异端 =))))

你们的版主怎么会漏掉这个?

亲爱的尤金!我希望你没有查看这篇文章。

亲爱的瓦西里

感谢您的评论,第 18 节的功能已更新。请查看当前版本。

作者做了大量工作,可能会有错误,我们会一起修正。

需要使用 TFMigrate(int tf) 函数来替换 MQL5时间框架的 正确。例如,在 MQL4 中,PERIOD_H1 常量的数值是 60,而在 MQL5 中,PERIOD_H1 的数值=16385,即 TFMigrate(60)=16385。

 

我认为还有很多错误。

我甚至可以说是最简单的错误。


在某些章节中,函数是相互比较的。

在另一些章节中,写的是类比。


没有一个成功的例子来说明如何实施这篇文章、

据我所知,这篇文章试图从 µl4..... 移植一些东西。


您对验证的态度总是令人钦佩的。

我认为这是作者肆无忌惮地想往你的眼睛里扔灰尘。

他确实成功地做到了这一点。

因为我知道您对被核查材料的敏感性。

 
CoreWinTT:


比如说,用 20 个试试看。

你又想糊弄我。

以及每个函数中的这些废话。

为什么要让 TF 迁移????

如果 mql5 拥有 mql4 甚至更多的所有 TF......

完全是异端=)))))


谢谢你发现了错误。我忽略了搜索可以从 0 栏以外的地方开始。以下是更正后的函数:

//+------------------------------------------------------------------+
//|测试。mq5
//|版权所有 DC2008
//|http://www.mql5.com ||
//+------------------------------------------------------------------+
#property copyright "DC2008"
//--- 时间序列数组
double            Close[];
double            Open[];
double            High[];
double            Low[];
long              Volume[];
datetime          Time[];
//+------------------------------------------------------------------+
//| 专家初始化函数|
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| 专家去初始化函数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| 专家勾选功能|
//+------------------------------------------------------------------+
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:

我认为还有很多错误。

我甚至可以说是最简单的错误。


在某些章节中,函数是相互比较的。

在另一些章节中,写的是类比。


没有一个成功的例子来说明如何实施这篇文章、

据我所知,这篇文章试图从 µl4..... 移植一些东西。


您对验证的态度总是令人钦佩的。

我认为这是作者肆无忌惮地想往你的眼睛里扔灰尘。

他确实成功地做到了这一点。

因为我知道您对被核查材料的敏感性。


可能会有错误,因为材料相当多。

在阅读材料的过程中,我们要求作者以参考书的形式撰写一篇文章,涵盖 MQL4 的所有功能(除了交易 - 您很快就会看到它们的解决方案之一),在 MQL5 中为每个功能提供一个类比,总之,将所有功能放在一起,以便重写 MQL4 程序的人可以快速找到类比。关于不受约束的愿望,如果我们谈论的是所考虑的部分的数量--我们坚持要涵盖所有函数(结果超过 250 个)。

至于对某些部分的功能进行比较--这并不完全是一种比较。有必要给出一个类比,即使它是相同的。对于所有函数来说都是如此。因此,看似有比较,但从比较中可以看出,例如数学函数是相同的。顺便提一下,作为建议,在每一节的开头提到这一点可能会有帮助,这是需要注意的地方。

由于这个原因(仿真器函数的架构),作者在实现中使用了一些非显而易见的东西(例如,对于 iLowest/iHighest 全局 Open[]...High[]...,之前是全局声明的,并在 OnInit 中设置为 AsSeries),这在仿真器中是隐含的。

至于使用技术指标,可能会有很多问题,使用技术指标 不应像在 MQL4 中那样--最好在 OnInit 中手动创建技术指标 并引用描述符,而不是每次都在本地函数中创建技术指标。但作者建议的方法也行得通,因为终端不会立即销毁指标。因此,这其中有很多微妙之处。

重要的是,现在有了一些可以讨论的东西,如果您发现错误(包括由建议的函数结构引起的错误),请提出您的变体。