# 将指标从 MQL4 迁移到 MQL5

17 十二月 2013, 07:09
0
1 381

### 1. 准备要迁移的指标

```//---- 指标参数
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;
//---- 指标缓存
double     MacdBuffer[];
double     SignalBuffer[];
```

`double &MacdBuffer[],double &SignalBuffer[],int FastEMA,int SlowEMA,int SignalSMA`

`int start()`

```int start(int rates_total,
int prev_calculated,
double &MacdBuffer[],
double &SignalBuffer[],
int FastEMA,
int SlowEMA,
int SignalSMA)
```

`int rates_total, int prev_calculated,`

```//+------------------------------------------------------------------
//| 移动平均的收敛/发散指标（MACD）                                       |
//+------------------------------------------------------------------
int start(int rates_total
,int prev_calculated
,double &MacdBuffer[]
,double &SignalBuffer[]
,int FastEMA
,int SlowEMA
,int SignalSMA)
{
int limit;
int counted_bars=IndicatorCounted();
//---- 最近一次计算的柱形将被重算
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
//---- macd的计算结果在第一个指标缓存中
for(int i=0; i<limit; i++)
MacdBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
-iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- 信号线的计算结果在第二个指标缓存中
for(i=0; i<limit; i++)
SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i);
//---- 完成
return(0);

}
//+------------------------------------------------------------------
```

### 2. 为 MQL5 程序创建一个 MQL4 模板

```//---- 指标参数
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;
```

```//---- 指标缓存
double     MacdBuffer[];
double     SignalBuffer[];
```

```#include <mql4_2_mql5.mqh>
//--- 输入参数

```

`int OnInit()`

`    InitMql4();`

```int bars=MQL4Run(rates_total,prev_calculated);
// bars - MQL4程序可用的柱形数量
```

`int CountedMQL4;`

` prev_calculated,`

CountedMQL4 变量在包含文件中声明；它传递已计算的数据量。

```Start(bars,
CountedMQL4,
MacdBuffer,
SignalBuffer,
FastEMA,
SlowEMA,
SignalSMA);
```

```//+------------------------------------------------------------------
//|                                                     MACD_MQ4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//---绘制 MacdBuffer
#property indicator_label1  "MacdBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- 绘制 SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- 输入参数
#include <mql4_2_mql5.mqh>
input int      FastEMA=12;
input int      SlowEMA=26;
input int      SignalSMA=9;
//--- 指标缓存
double         MacdBuffer[];
double         SignalBuffer[];
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                               |
//+------------------------------------------------------------------
int OnInit()
{
//--- 指标缓存映射
SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//---
InitMql4();
//---
return(0);

}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime& time[],
const double& open[],
const double& high[],
const double& low[],
const double& close[],
const long& tick_volume[],
const long& volume[],
{
//---
int bars=MQL4Run(rates_total,prev_calculated);
// bars - MQL4程序可用的柱形数量

Start(bars,
CountedMQL4,
MacdBuffer,
SignalBuffer,
FastEMA,
SlowEMA,
SignalSMA);//--- 返回prev_calculated的值用于下一次调用
return(rates_total);

}
//+------------------------------------------------------------------
//| 移动平均的收敛/发散指标（MACD）                                       |
//+------------------------------------------------------------------
int Start(int rates_total,
int prev_calculated,
double &MacdBuffer[],
double &SignalBuffer[],
int FastEMA,
int SlowEMA,
int SignalSMA)
{
int limit;
int counted_bars=IndicatorCounted();
//---- 最近一次计算的柱形将被重算
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
//---- macd的计算结果在第一个指标缓存中
for(int i=0; i<limit; i++)
MacdBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
-iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- 信号线的计算结果在第二个指标缓存中
for(i=0; i<limit; i++)
SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i);
//---- 完成
return(0);

}
```

### 3. 在 MQL5 中处理指标缓存的特点

MQL4
MQL5
IndicatorCounted()
prev_calculated
Bars rates_total
iMA( iMAMql4(
iMAOnArray( iMAOnArrayMql4(

```//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+
```

```   ArraySetAsSeries(MacdBuffer,true);
ArraySetAsSeries(SignalBuffer,true);
```

```//+------------------------------------------------------------------
//|                                                    MACD_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//---绘制 MacdBuffer
#property indicator_label1  "MacdBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- 绘制 SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#include <mql4_2_mql5.mqh>
//--- 输入参数
input int      FastEMA=12;
input int      SlowEMA=26;
input int      SignalSMA=9;
//--- 指标缓存
double         MacdBuffer[];
double         SignalBuffer[];
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                               |
//+------------------------------------------------------------------
int OnInit()
{
//--- 指标缓存映射
SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//---
InitMql4();
//---
ArraySetAsSeries(MacdBuffer,true);
ArraySetAsSeries(SignalBuffer,true);
//---
return(0);

}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
{
//---
int bars=MQL4Run(rates_total,prev_calculated);
// bars - MQL4程序可用的柱形数量
Start(bars,
CountedMQL4,
MacdBuffer,
SignalBuffer,
FastEMA,
SlowEMA,
SignalSMA);
//--- 返回prev_calculated的值用于下一次调用
return(rates_total);

}
//+------------------------------------------------------------------
//| 移动平均的收敛/发散指标（MACD）                                       |
//+------------------------------------------------------------------
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+
int Start(int rates_total,
int prev_calculated,
double &MacdBuffer[],
double &SignalBuffer[],
int FastEMA,
int SlowEMA,
int SignalSMA)
{
int limit;
int counted_bars=prev_calculated;
//---- 最近一次计算的柱形将被重算
if(counted_bars>0) counted_bars--;
limit=rates_total-counted_bars;
//---- macd的计算结果在第一个指标缓存中
for(int i=0; i<limit; i++)
MacdBuffer[i]=iMAMql4(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
-iMAMql4(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- 信号线的计算结果在第二个指标缓存中
for(int i=0; i<limit; i++)
SignalBuffer[i]=iMAOnArrayMql4(MacdBuffer,rates_total,SignalSMA,0,MODE_SMA,i);
//---- 完成
return(0);

}
//+------------------------------------------------------------------
```

### 4. 迁移随机动量指标的例子

```int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
```

`#property indicator_plots   2`

```   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
```

```//+------------------------------------------------------------------
//|                                              Stochastic_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property version   "1.00"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 4
#property indicator_plots   2
//--- 绘制 MainBuffer
#property indicator_label1  "MainBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- 绘制 SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#include <mql4_2_mql5.mqh>
//--- 输入参数
input int      Kperiod=14;
input int      Dperiod=5;
input int      Slowing=5;
//--- 指标缓存
double         MainBuffer[];
double         SignalBuffer[];
double         HighesBuffer[];
double         LowesBuffer[];
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                               |
//+------------------------------------------------------------------
int OnInit()
{
//--- 指标缓存映射
SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
//---
InitMql4();
//---
ArraySetAsSeries(MainBuffer,true);
ArraySetAsSeries(SignalBuffer,true);
ArraySetAsSeries(HighesBuffer,true);
ArraySetAsSeries(LowesBuffer,true);
//---
return(0);

}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
{
//---
int bars=MQL4Run(rates_total,prev_calculated);
// bars - MQL4程序可用的柱形数量
start(bars,
CountedMQL4,
MainBuffer,
SignalBuffer,
HighesBuffer,
LowesBuffer,
Kperiod,
Dperiod,
Slowing);
//--- 返回prev_calculated的值用于下一次调用
return(rates_total);

}
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+
int start(int rates_total,
int prev_calculated,
double &MainBuffer[],
double &SignalBuffer[],
double &HighesBuffer[],
double &LowesBuffer[],
int KPeriod,
int DPeriod,
int Slowing)
{
int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
int    i,k;
int    counted_bars=prev_calculated;
double price;
//----
if(rates_total<=draw_begin2) return(0);
//---- 用0初始化
if(counted_bars<1)
{
for(i=1;i<=draw_begin1;i++) MainBuffer[rates_total-i]=0;
for(i=1;i<=draw_begin2;i++) SignalBuffer[rates_total-i]=0;

}
//---- 最少的计数
i=rates_total-KPeriod;
if(counted_bars>KPeriod) i=rates_total-counted_bars-1;
while(i>=0)
{
double min=1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=Low[k];
if(min>price) min=price;
k--;

}
LowesBuffer[i]=min;
i--;

}
//---- 最大计数
i=rates_total-KPeriod;
if(counted_bars>KPeriod) i=rates_total-counted_bars-1;
while(i>=0)
{
double max=-1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=High[k];
if(max<price) max=price;
k--;

}
HighesBuffer[i]=max;
i--;

}
//---- %K线
i=rates_total-draw_begin1;
if(counted_bars>draw_begin1) i=rates_total-counted_bars-1;
while(i>=0)
{
double sumlow=0.0;
double sumhigh=0.0;
for(k=(i+Slowing-1);k>=i;k--)
{
sumlow+=Close[k]-LowesBuffer[k];
sumhigh+=HighesBuffer[k]-LowesBuffer[k];

}
if(sumhigh==0.0) MainBuffer[i]=100.0;
else MainBuffer[i]=sumlow/sumhigh*100;
i--;

}
//---- 最近一次计算的柱形将被重算
if(counted_bars>0) counted_bars--;
int limit=rates_total-counted_bars;
//---- 信号线是移动平均
for(i=0; i<limit; i++)
SignalBuffer[i]=iMAOnArrayMql4(MainBuffer,rates_total,DPeriod,0,MODE_SMA,i);
//----
return(0);

}
//+------------------------------------------------------------------
```

### 5. 迁移 RSI 指标的例子

```//---- 输入参数
extern int RSIPeriod=14;
//---- 缓存
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];
```

`#property indicator_buffers 3`

`#property indicator_plots   1`

```   SetIndexBuffer(1,PosBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,NegBuffer,INDICATOR_CALCULATIONS)
```

```//+------------------------------------------------------------------
//|                                                     RSI_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   1
//--- 绘制 RSIBuffer
#property indicator_label1  "RSIBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- 绘制 PosBuffer
#property indicator_label2  "PosBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- 绘制 NegBuffer
#property indicator_label3  "NegBuffer"
#property indicator_type3   DRAW_LINE
#property indicator_color3  Red
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

#include <mql4_2_mql5.mqh>
//--- 输入参数
input int      RSIPeriod=14;
//--- 指标缓存
double         RSIBuffer[];
double         PosBuffer[];
double         NegBuffer[];
//+------------------------------------------------------------------
//| 自定义指标初始化函数                                               |
//+------------------------------------------------------------------
int OnInit()
{
//--- 指标缓存映射
SetIndexBuffer(0,RSIBuffer,INDICATOR_DATA);
SetIndexBuffer(1,PosBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,NegBuffer,INDICATOR_CALCULATIONS);
//---
InitMql4(3);

ArraySetAsSeries(RSIBuffer,true);
ArraySetAsSeries(PosBuffer,true);
ArraySetAsSeries(NegBuffer,true);

return(0);

}
//+------------------------------------------------------------------
//| 自定义指标迭代函数                                                 |
//+------------------------------------------------------------------
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
{
int bars=MQL4Run(rates_total,prev_calculated);
// bars - MQL4程序可用的柱形数量
RSImql4(bars,
CountedMQL4,
RSIBuffer,
PosBuffer,
NegBuffer,
RSIPeriod);
return(rates_total);

}
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+
int RSImql4(int rates_total,
int prev_calculated,
double &RSIBuffer[],
double &PosBuffer[],
double &NegBuffer[],
int RSIPeriod)
{
int    i,counted_bars=prev_calculated;
double rel,negative,positive;
//----fd
if(rates_total<=RSIPeriod) return(0);
//---- 用0初始化
if(counted_bars<1)
for(i=1;i<=RSIPeriod;i++) RSIBuffer[rates_total-i]=0.0;
//----
i=rates_total-RSIPeriod-1;
if(counted_bars>=RSIPeriod) i=rates_total-counted_bars-1;
while(i>=0)
{
double sumn=0.0,sump=0.0;
if(i==rates_total-RSIPeriod-1)
{
int k=rates_total-2;
//---- 初始累加
while(k>=i)
{
rel=Close[k]-Close[k+1];
if(rel>0) sump+=rel;
else      sumn-=rel;
k--;

}
positive=sump/RSIPeriod;
negative=sumn/RSIPeriod;

}
else
{
//---- 平滑移动平均
rel=Close[i]-Close[i+1];
if(rel>0) sump=rel;
else      sumn=-rel;
positive=(PosBuffer[i+1]*(RSIPeriod-1)+sump)/RSIPeriod;
negative=(NegBuffer[i+1]*(RSIPeriod-1)+sumn)/RSIPeriod;

}
PosBuffer[i]=positive;
NegBuffer[i]=negative;
if(negative==0.0) RSIBuffer[i]=0.0;
else RSIBuffer[i]=100.0-100.0/(1+positive/negative);
i--;

}
//----
return(0);

}
//+------------------------------------------------------------------
```

```int start()
{
```

`int RSImql4(`

### 7. 改进

`#include <InitMQL4.mqh>`

### 附注

`iMA(Symb,TimFram,iMAPeriod,ma_shift,ma_method,applied_price);`

macd_mql4.mq5 (7.83 KB)
mql4_2_mql5.mqh (32.21 KB)
rsi_mql4.mq5 (9.27 KB)
stochastic_mql4.mq5 (10.61 KB)