25 二月 2016, 16:23
0
360

### 带自定义指标调用的 EA 的结构

```//+------------------------------------------------------------------+
//|                                               ExpertIndPlan0.mqh |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
//---- EA input parameters
extern int period10 = 15;
extern int period11 = 15;
extern int period12 = 15;
//---- EA input parameters
extern int period20 = 15;
extern int period21 = 15;
extern int period22 = 15;
//---- Declaring buffers for indicator values
double Ind_Buffer1[6];
double Ind_Buffer2[6];
//+------------------------------------------------------------------+
//| Custom Expert initialization function                            |
//+------------------------------------------------------------------+
int init()
{
// Here is the code of EA initialization
//---- initialization end
return(0);
}
//+------------------------------------------------------------------+
//| Custom Expert iteration function                                 |
//+------------------------------------------------------------------+
int start()
{
//---- Checking whether the bars number is enough for further calculation
if(iBars(Symbol(), 0) < period10 + period11 + period12 + 10)
return(0);
if(iBars(Symbol(), 0) < period20 + period21 + period22 + 10)
return(0);
//---- getting indicator values for further calculation
for(int bar = 5; bar >= 1; bar--)
{
Ind_Buffer1[bar] = iCustom("IndicatorPlan", Symbol(), 0, period10,
period11, period12, 0, bar);
Ind_Buffer2[bar] = iCustom("IndicatorPlan", Symbol(), 0, period20,
period21, period22, 0, bar);
}
// Here is the EA code, forming trade signals
// based on the values of indicator buffer cells
//----
// here is the EA executive part code,
// requesting for placing an order
//----
return(0);
}
//+------------------------------------------------------------------+```

```bool Get_IndSeries(int Number,string symbol, int timeframe,
bool NullBarRecount, int period0, int period1,
int period2, double& InputBuffer0[],
double& InputBuffer1[], double& InputBuffer2[])```

```//+------------------------------------------------------------------+
//|                                               ExpertIndPlan1.mqh |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
//---- EA input parameters
extern int period10 = 15;
extern int period11 = 15;
extern int period12 = 15;
//---- EA input parameters
extern int period20 = 15;
extern int period21 = 15;
extern int period22 = 15;
//---- Indicator buffers declaration
double Ind_Buffer10[], Ind_Buffer11[], Ind_Buffer12[];
double Ind_Buffer20[], Ind_Buffer21[], Ind_Buffer22[];
//+------------------------------------------------------------------+
//| Get_IndSeries() function                                         |
//+------------------------------------------------------------------+
//---- Declaration of the function Get_IndSeries()
bool Get_IndSeries(int Number,string symbol, int timeframe,
bool NullBarRecount, int period0, int period1,
int period2, double& InputBuffer0[],
double& InputBuffer1[], double& InputBuffer2[])
{
//----
// Here is the code of the function GetIdicator()
//----
return(true);
}
//+------------------------------------------------------------------+
//| Custom Expert initialization function                            |
//+------------------------------------------------------------------+
int init()
{
//----
// Here is the code of the EA initialization
//---- initialization end
return(0);
}
//+------------------------------------------------------------------+
//| Custom Expert iteration function                                 |
//+------------------------------------------------------------------+
int start()
{
//---- Checking whether the bars number is enough for further calculation
if(iBars(Symbol(), 0) < period10 + period11 + period12 + 10)
return(0);
if(iBars(Symbol(), 0) < period20 + period21 + period22 + 10)
return(0);
//---- getting indicator values for further calculation
if(!Get_IndSeries(0,Symbol(), 0, false, period10, period11, period12,
Ind_Buffer10, Ind_Buffer11, Ind_Buffer12))
return(0);
if(!Get_IndSeries(1, Symbol(), 0, false, period20, period21, period22,
Ind_Buffer20, Ind_Buffer21,Ind_Buffer22))
return(0);
//----
// Here is the EA code, forming trade signals
// based on the values of indicator buffer cells
//----
// here is the EA executive part code,
// requesting for placing an order
//----

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

1.仅提取函数 int start() 的内容；

2.添加函数 Get_IndSeries() 的声明：

```bool Get_IndSeries(string symbol, int timeframe, bool NullBarRecount,
int period0, int period1, int period2,
double& InputBuffer0, double& InputBuffer1,
double& InputBuffer2)```

3.根据函数 Get_IndSeries() 的外部变量的缓冲区名称 (InputBuffer) 更改代码 (Ind_Buffer) 中的指标缓冲区的名称 (Ind_Buffer)；
4.添加变量 LastCountBar 的声明；
5.检查变量 NullBarRecount 是否为真：

```if(!NullBarRecount)
LastCountBar = 1;```
6.在指标计算的所有循环周期中，将零更改为 LastCountBar；
7.在检查柱数是否足以进行进一步计算时，在代码最开头部分进行更改：将 return(0) 更改为 return(false)；
8.在代码的结尾处，将 return(0) 更改为 return(true)；

```//+------------------------------------------------------------------+
//|                                                Get_IndSeries.mqh |
//|                                        http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
bool Get_IndSeries(int Number, string symbol,int timeframe,
bool NullBarRecount, int period0, int period1,
int period2, double& InputBuffer0[],
double& InputBuffer1[], double& InputBuffer2[])
{
//---- getting the number of all bars of a chart
int IBARS = iBars(symbol, timeframe);
//---- Checking whether the bars number is enough for further calculation
if(IBARS < period0 + period1 + period2)
return(false);
//---- EMULATION OF INDICATOR BUFFERS
if(ArraySize(InputBuffer0) < IBARS)
{
ArraySetAsSeries(InputBuffer0, false);
ArraySetAsSeries(InputBuffer1, false);
ArraySetAsSeries(InputBuffer2, false);
//----
ArrayResize(InputBuffer0, IBARS);
ArrayResize(InputBuffer1, IBARS);
ArrayResize(InputBuffer2, IBARS);
//----
ArraySetAsSeries(InputBuffer0, true);
ArraySetAsSeries(InputBuffer1, true);
ArraySetAsSeries(InputBuffer2, true);
}
//----+ introducing static memory variables
static int IndCounted[];
//----+ changing the size of static variables
if(ArraySize(IndCounted) < Number + 1)
ArrayResize(IndCounted, Number + 1);
//----+ introducing an integer variable
int LastCountBar;
//----+ Checking if the recalculation of the zero bar is allowed
if(!NullBarRecount)
LastCountBar = 1;
else
LastCountBar = 0;
//----+ Inserting a variable with a floating point
double Resalt0, Resalt1, Resalt2;
//----+ Inserting integer variables and getting already calculated bars
int limit, MaxBar, bar, counted_bars = IndCounted[Number];
//----+ Remembering the number of all bars of a chart (we do not count the zero bar!)
IndCounted[Number] = IBARS - 1;
//---- defining the number of the oldest bar,
// starting from which new bars will be recalculated
limit = IBARS - counted_bars - 1;
//---- defining the number of the oldest bar,
// starting from which new bars will be recalculated
MaxBar = IBARS - 1 - (period0 + period1 + period2);
//---- initialization of zero
if(limit > MaxBar)
{
limit = MaxBar;
for(bar = IBARS - 1; bar >= 0; bar--)
{
InputBuffer0[bar] = 0.0;
InputBuffer1[bar] = 0.0;
InputBuffer2[bar] = 0.0;
}
}
//----+ THE FIRST CYCLE OF INDICATOR CALCULATION
for(bar = limit; bar >= LastCountBar; bar--)
{
// Here code of the variable Resalt1 calculation
// based on the external variable period1
InputBuffer1[bar] = Resalt1;
}
//----+ THE SECOND CYCLE OF INDICATOR CALCULATION
for(bar = limit; bar >= LastCountBar; bar--)
{
// Here code of the variable Resalt2 calculation
// based on the values of the buffer Ind_Buffer1[]
// and external variable period2
InputBuffer2[bar] = Resalt2;
}
//----+ THE MAIN CYCLE OF INDICATOR CALCULATION
for(bar = limit; bar >= LastCountBar; bar--)
{
// Here code of the variable Resalt0 calculation
// based on the values of the buffer Ind_Buffer2[]
// and external variable period0
InputBuffer0[bar] = Resalt0;
}
return(true);
}
//+------------------------------------------------------------------+```

```//+------------------------------------------------------------------+
//|                                                         RAVI.mq4 |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
//---- drawing the indicator in a separate window
#property indicator_separate_window
//---- number of indicator buffers
#property indicator_buffers 1
//---- indicator color
#property indicator_color1 Red
//---- INPUT PARAMETERS OF THE INDICATOR
extern int Period1 = 7;
extern int Period2 = 65;
extern int MA_Metod = 0;
extern int PRICE = 0;
//---- indicator buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| RAVI initialization function                                     |
//+------------------------------------------------------------------+
int init()
{
//---- indicator drawing style
SetIndexStyle(0, DRAW_LINE);
//---- indicator buffers
SetIndexBuffer(0,ExtBuffer);
//---- indicator name and labels for subwindows
IndicatorShortName("RAVI (" + Period1+ ", " + Period2 + ")");
SetIndexLabel(0, "RAVI");
//---- initialization end
return(0);
}
//+------------------------------------------------------------------+
//| RAVI iteration function                                          |
//+------------------------------------------------------------------+
int start()
{
int MinBars = MathMax(Period1, Period2);
//---- checking whether the bars number is enough for further calculation
if(Bars < MinBars)
return(0);
//----+ Introducing variables with a floating point
double MA1, MA2, result;
//----+ Introducing integer variables and getting already calculated bars
int MaxBar, bar, limit, counted_bars = IndicatorCounted();
//---- checking for possible errors
if(counted_bars < 0)
return(-1);
//---- the last calculated bar should be recalculated
if(counted_bars > 0)
counted_bars--;
//---- defining the number of the oldest bar,
// starting from which all bars will be recalculated
MaxBar = Bars - 1 - MinBars;
//---- defining the number of the oldest bar,
// starting from which new bars will be recalculated
limit = Bars - counted_bars - 1;
//---- zero initialization
if(limit > MaxBar)
{
for(int ii = Bars - 1; ii >= MaxBar; ii--)
ExtBuffer[ii] = 0.0;
limit = MaxBar;
}
//---- main cycle
for(bar = 0; bar <= limit; bar++)
{
MA1 = iMA(NULL, 0, Period1, 0, MA_Metod, PRICE,bar);
MA2 = iMA(NULL, 0, Period2, 0, MA_Metod, PRICE,bar);
//----
result = ((MA1 - MA2) / MA2)*100;
ExtBuffer[bar] = result;
}
//----
return(0);
}
//+------------------------------------------------------------------+```

1.去除指标代码中所有不必要的元素；
2.为单个缓冲区 ExtBuffer[] 编写指标缓冲区模拟的代码；
3.用变量 IndCounted 替代函数 IndicatorCounted()；
4.使用图表柱的数量减去一初始化变量 IndCounted；
5.将预定义变量 Bars 更改为调用时间序列 iBars（符号，时间范围）；
6.针对 counted_bars 删除不必要的检查：

```//---- checking possible errors
if(counted_bars < 0)
return(-1);
//---- the last calculated bar must be recalculated
if(counted_bars > 0)
counted_bars--;```

7.仅保留函数 int start() 的内容；
8.添加函数 Get_RAVISeries() 的声明：

```bool Get_RAVISeries(int Number, string symbol,int timeframe,
bool NullBarRecount, int Period1,
int Period2, int MA_Metod, int  PRICE,
double& InputBuffer[])```

9.用函数 Get_RAVISeries() 的外部变量的缓冲区名称 (InputBuffer) 相应地替代代码中的指标缓冲区名称 (ExtBuffer)；
10.添加变量 LastCountBar 的声明；
11.根据函数 Get_RAVISeries. mqh 的调用次数，将静态变量 IndCounted 转变成数组 IndCounted[Number] 并添加用于更改变量大小的代码：

```//----+ changing the size of static variables
if(ArraySize(IndCounted) < Number + 1)
{
ArrayResize(IndCounted, Number + 1);
}```

12.检查变量 NullBarRecount 是否为真：

```if(!NullBarRecount)
LastCountBar = 1;```

13.在所有指标计算循环周期中，将零更改为 LastCountBar：

`for(bar = limit; bar >= LastCountBar; bar--)`

14.在检查柱数是否足够时，在代码的开头部分进行更改：将 return(0) 更改为 return(false)；

15.在结尾处，用 return(true) 替代 return(0)。

```//+------------------------------------------------------------------+
//|                                               Get_RAVISeries.mqh |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
bool Get_RAVISeries(int Number, string symbol,int timeframe,
bool NullBarRecount, int Period1, int Period2,
int MA_Metod, int  PRICE, double& InputBuffer[])
{
//---- getting the number of all bars of a chart
int IBARS = iBars(symbol, timeframe);
//---- Checking whether the bars number is enough for further calculation
if(IBARS < MathMax(Period1, Period2))
return(false);
//---- EMULATION OF INDICATOR BUFFERS
if(ArraySize(InputBuffer) < IBARS)
{
ArraySetAsSeries(InputBuffer, false);
//----
ArrayResize(InputBuffer, IBARS);
//----
ArraySetAsSeries(InputBuffer, true);
}
//----+  inserting static variables of memory
static int IndCounted[];
//----+ changing the size of static variables
if(ArraySize(IndCounted) < Number + 1)
{
ArrayResize(IndCounted, Number + 1);
}
//----+ Introducing an integer variable
int LastCountBar;
//----+ Checking whether the recalculation of the zero bar is allowed
if(!NullBarRecount)
LastCountBar = 1;
//----+ Introducing floating point variables
double MA1,MA2,result;
//----+ Introducing integer variables and getting alreadu calculated bars
int MaxBar, bar, limit, counted_bars = IndCounted[Number];
//----+ Remembering the amount of all chart bars
IndCounted[Number] = IBARS - 1;
//---- determining the number of the oldest bar,
// starting from which new bars will be recalculated
limit = IBARS - counted_bars - 1;
// Print(IBARS - counted_bars);
//---- determining the number of the oldest bar,
// starting from which all bars will be recalculated
MaxBar = IBARS - 1 - MathMax(Period1, Period2);
//---- zero initialization
if(limit > MaxBar)
{
limit = MaxBar;
for(bar = IBARS - 1; bar >= 0; bar--)
{
InputBuffer[bar] = 0.0;
}
}
//----+ THE FIRST CYCLE OF INDICATOR CALCULATION
for(bar = limit; bar >= LastCountBar; bar--)
{
MA1 = iMA(symbol, timeframe, Period1, 0, MA_Metod, PRICE, bar);
MA2 = iMA(symbol, timeframe, Period2, 0, MA_Metod, PRICE, bar);
//----
result = ((MA1 - MA2) / MA2)*100;
InputBuffer[bar] = result;
}
//----+
return(true);
}
//+------------------------------------------------------------------+```

```//+------------------------------------------------------------------+
//|                                           Get_RAVISeriesTest.mq4 |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
//---- INPUT EA PARAMETERS
extern bool NullBarRecount = true;
//---- indicator buffers
double RAVI_Buffer0[];
double RAVI_Buffer1[];
double RAVI_Buffer2[];
//+------------------------------------------------------------------+
//| Get_RAVISeries() function                                        |
//+------------------------------------------------------------------+
#include <Get_RAVISeries.mqh>
//+------------------------------------------------------------------+
//| Custom Expert initialization function                            |
//+------------------------------------------------------------------+
int init()
{
//---- initialization end
return(0);
}
//+------------------------------------------------------------------+
//| Custom Expert iteration function                                 |
//+------------------------------------------------------------------+
int start()
{
//----
double Ind_Velue, Resalt;
//----
if(!Get_RAVISeries(0, Symbol(), 0, NullBarRecount, 10, 20, 1, 0,
RAVI_Buffer0))
return(0);
if(!Get_RAVISeries(1, Symbol(), 240, NullBarRecount, 25, 66, 2, 1,
RAVI_Buffer1))
return(0);
if(!Get_RAVISeries(2, Symbol(), 1440, NullBarRecount, 30, 70, 3, 3,
RAVI_Buffer2))
return(0);
//---- getting indicator values for the test 0
Ind_Velue = iCustom(NULL, 0, "RAVI", 10, 20, 1, 0, 0, 2);
Resalt = RAVI_Buffer0[2] - Ind_Velue;
Print("  " + Ind_Velue + "    " + RAVI_Buffer0[2] + "    " + Resalt+"");
//---- getting indicator values for the test 1
Ind_Velue = iCustom(NULL, 240, "RAVI", 25, 66, 2, 1, 0, 2);
Resalt = RAVI_Buffer1[2] - Ind_Velue;
Print("  " + Ind_Velue + "    " + RAVI_Buffer1[2] + "    " + Resalt+"" );
//---- getting indicator values for the test 2
Ind_Velue = iCustom(NULL, 1440, "RAVI", 30, 70, 3, 3, 0, 2);
Resalt = RAVI_Buffer2[2] - Ind_Velue;
Print("  " + Ind_Velue + "    " + RAVI_Buffer2[2] + "    " + Resalt + "");
//----
return(0);
}
//+------------------------------------------------------------------+```

### 总结

ExpertIndPlan0.mqh (2.27 KB)
ExpertIndPlan1.mqh (2.89 KB)
RAVI.mq4 (2.93 KB)