English Русский Español Deutsch 日本語 Português
具有最小延迟的有效平均算法: 在指标和 Expert Advisor 中使用

具有最小延迟的有效平均算法: 在指标和 Expert Advisor 中使用

MetaTrader 4示例 | 12 四月 2016, 12:38
4 576 1
Nikolay Kositsin
Nikolay Kositsin

简介

在基于任何平均算法的指标的基础上构建的机械交易系统中,它们的开发人员很少使用一个以上的平均算法。 在很多情况下,如果 EA 算法是基于简单移动和包括在 MetaTrader 4 终端的标准指标集合中的指标的,将仅使用四个标准算法:简单平均、指数平均、平滑平均和线性加权平均。 这种方法相当限制 Expert Advisor 的可能性。

使用不同平均算法的同一个交易系统在交易结果方面会有很大的不同。 同时,无法预先知道哪种可用算法能够使交易系统实现盈利最大化。 因此,更为合理的做法是能够使用完全不同的平均算法编写代码,而这些算法可通过更改 EA 的外部变量的值来进行选择。 结果,通过这种方法,我们用我们自己的指标替换了 EA 指标,我们自己的指标具有更灵活的平均算法选择设置。 因此,这种方法可以分成三个阶段:

1. 我们基于标准移动和包括在 MetaTrader 4 客户终端的技术指标集合中的指标,编写 Expert Advisor 代码。
2. 我们根据标准指标的说明编写自定义指标,这些自定义指标能够更灵活地替换平滑算法。
3. 通过将这些自定义指标的外部参数提取到 EA 的外部变量中,我们用自定义指标的调用替换了技术指标的调用。

在本文中,我想详细介绍更为通用的指标,能够(如果可以这样说)热替换这些指标中使用的平均算法。 本文是“具有最小延迟的有效平均算法: 在指标中使用”的续篇,因此,建议在阅读本文之前仔细阅读上一篇文章。



通用平均函数

在我的上一篇文章中,我介绍了五个平均函数。 我想在此列表中再添加一个函数 - MASeries(),它具有经典的平均算法:

double MASeries
(
  int number, int MA_Method, int MaxBar, int limit, int period, double series, int bar, int& reset
)

至于此函数的用途,它完全类似于前面五个函数。 本文已附上此函数的代码 - MASeries.mqh。

现在,基于这六个函数,我们可以构建一个通用平均函数,我将它命名为 SmoothXSeries(),并将其放置在文件 SmoothXSeries.mqh 中。 与前面的函数类似,此函数也是一个 #include < > 指令:

#include <SmoothXSeries.mqh>

在外部变量方面,此函数类似于 JJMASeries(),但有一个新的平滑算法标识符变量 - SmoothMode:

double SmoothXSeries
(
  int number,int SmoothMode, int din, int MaxBar, int limit, int Phase, int Length, double Series, int bar, int& reset
)

由 SmoothMode 参数的值来选择所需的平均算法,SmoothMode 参数的值介于 0 到 8 之间:

  // 0 : JJMA
  // 1 : JurX        
  // 2 : ParMA
  // 3 : LRMA
  // 4 : T3
  // 5 : SMA
  // 6 : EMA
  // 7 : SSMA
  // 8 : LWMA

当然,变量 din 和 Phase 仅应用于它们最初被定义用于的平均算法。 在指标代码中使用此函数之前,应对此函数的变量进行初始化,并应为变量分配内存。 为此,在指标初始化块中,调用 SmoothXSeriesResize() 函数。 使用指标代码中 SmoothXSeries() 函数调用的次数作为外部变量 Size 的值。

  //Ten calls of the SmoothXSeriesResize() function in the indicator code
  SmoothXSeriesResize(10);

现在有了通用平均算法 SmoothXSeries(),我们可以开始编写指标的代码。



通用移动

任何移动都是通过平滑处理价格时间序列而获得。 在上一篇文章中,我谈到了 PriceSeries() 函数,此函数用于选择时间序列的价格行的值。 构建移动的任务实际上是使用 SmoothXSeries() 函数处理价格序列的这些值并将这些值传递到指标缓冲区中。 下面是代码实现的形式:

/*
For the operation of the indicator the files

SmoothXSeries.mqh
T3Series.mqh
MASeries.mqh
LRMASeries.mqh
JurXSeries.mqh
ParMASeries.mqh
JJMASeries.mqh 
PriceSeries.mqh 
should be located in  the directory: MetaTrader\experts\include\

Heiken Ashi#.mq4
should be located in the directory: MetaTrader\indicators\
*/
//+X================================================================X+  
//|                                                         X1MA.mq4 | 
//|                        Copyright © 2009,        Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+X================================================================X+   
#property copyright "Copyright © 2009, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing the indicator in the main window
#property indicator_chart_window 
//---- number of indicator buffers
#property indicator_buffers 1 
//---- color of the indicator
#property indicator_color1 Red
//---- INPUT PARAMETERS OF THE INDICATOR +--------------------------------------------+
extern int Smooth_Mode = 0;   // Choosing the smoothing algorithm 0 - JJMA, 1 - JurX,        
                 // 2 - ParMA, 3 - LRMA, 4 - T3, 5 - SMA, 6 - EMA, 7 - SSMA, 8 - LWMA
extern int Length = 11;   // depth of smoothing
extern int Phase  = 100; // parameter changing in limits -100 ... +100, 
                                       //influences the quality of the transient process; 
extern int Shift  = 0;   // indicator shift along the time axis
extern int Input_Price_Customs = 0; /* Selecting prices, upon which the calculation of
the indicator is performed (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */
//---- +------------------------------------------------------------------------------+
//---- buffers
double XMA[]; 
//---- variables
bool INIT;
int  StartBar;
//+X================================================================X+   
//| SmoothXSeries() function                                         |
//+X================================================================X+    
//----+ Declaring the function SmoothXSeries
//----+ Declaring the function SmoothXSeriesResize 
//----+ Declaring the function SmoothXSeriesAlert   
#include <SmoothXSeries.mqh> 
//+X================================================================X+   
//| PriceSeries() function                                           |
//+X================================================================X+    
//----+ Declaring the function PriceSeries
//----+ Declaring the function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+X================================================================X+   
//| X1MA initialization function                                     |
//+X================================================================X+ 
int init() 
{ 
//----+
   //---- setting the style of the indicator presentation 
   SetIndexStyle(0, DRAW_LINE); 
   //---- defining a buffer for calculations 
   SetIndexBuffer(0, XMA);
   //---- setting the values of the indicator that will not be visible on the chart
   SetIndexEmptyValue(0, 0.0);  
   //---- setting alerts for not allowed values of external variables
   JJMASeriesAlert (0, "Length", Length);
   JJMASeriesAlert (1, "Phase",   Phase);
   PriceSeriesAlert(Input_Price_Customs);
   //----+ Changing sizes of buffer variables of the function
           //SmoothXSeries, number = 1(One call of the SmoothXSeries function)
   if (SmoothXSeriesResize(1) != 1)
    {
     INIT = false;
     return(0);
    }
   //---- initialization of variables
   if (Smooth_Mode > 0 && Smooth_Mode < 9) 
                              StartBar = Length;
   else StartBar = 30;
   //---- setting the bar number,
                     //starting from which the indicator will be drawn 
   SetIndexDrawBegin(0, StartBar); 
   //---- Setting the format of accuracy of the indicator drawing
   IndicatorDigits(Digits);
   //---- end of initialization
   INIT = true;
   return(0);
//----+ 
}
//+X================================================================X+  
//| X1MA iteration function                                          | 
//+X================================================================X+   
int start()
{
//----+ 
   //---- Getting the number of all bars
   int Bars_ = Bars - 1;
//---- checking the initialization end and 
     //checking if the number of bars is enough for calculation
if (!INIT || Bars_ <= StartBar)
                  return(-1); 
//---- Introducing variables with a floating point
double Price, xma;
//---- Introducing integer variables and obtaining the number 
                           //of already calculated bars
int reset, MaxBar, limit, bar, counted_bars = IndicatorCounted();
//---- checking for possible errors
if (counted_bars < 0)
    return(-1);
//---- the last calculated bar must be recalculated
if (counted_bars > 0)
counted_bars--;
//---- defining the number of the oldest bar, 
//starting from which new bars will be recalculated 
limit = Bars_ - counted_bars;
//---- defining the number of the oldest bar, 
//starting from which all bars will be recalculated 
MaxBar = Bars_;
//----+ the main cycle of the indicator calculation
for(bar = limit; bar >= 0; bar--)
{
  //---- Getting the initial value of the price series
  Price = PriceSeries(Input_Price_Customs, bar);
  //---- X1MA smoothing of the initial value of the price series 
  //---- Call of the SmoothXSeries function number 0, 
//parameters Phase and Length are not changed at each bar (din = 0)
  xma = SmoothXSeries(0, Smooth_Mode, 0, MaxBar, limit, 
                                     Phase, Length, Price, bar, reset);
  //---- checking that there are no errors in the previous operation
  if(reset != 0)
  return(-1);
  
  XMA[bar] = xma;
  //----
}
//---- end of the indicator values calculation
return(0); 
//----+  
} 
//+X--------------------+ <<< The End >>> +--------------------X+

在此指标中,通过更改 Smooth_Mode 变量的值来选择平均算法。



使用双平均的通用移动

如果再对同一 SmoothXSeries() 函数获得指标进行一次平均处理,可显著提高处理此类移动的效率。

/*
For the operation of the indicator the files 

SmoothXSeries.mqh
T3Series.mqh
MASeries.mqh
LRMASeries.mqh
JurXSeries.mqh
ParMASeries.mqh
JJMASeries.mqh 
PriceSeries.mqh 
should be located in the directory: MetaTrader\experts\include\

Heiken Ashi#.mq4
should be located in the directory: MetaTrader\indicators\
*/
//+X================================================================X+  
//|                                                         X2MA.mq4 | 
//|                        Copyright © 2009,        Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+X================================================================X+   
#property copyright "Copyright © 2009, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing the indicator in the main window
#property indicator_chart_window 
//---- number of indicator buffers
#property indicator_buffers 1 
//---- color of the indicator
#property indicator_color1 Lime
//---- INPUT PARAMETERS OF THE INDICATOR +---------------------------------------------+
extern int Smooth_Mode1 = 0;   // Choosing the 1st smoothing algorithm 0 - JJMA, 1 - JurX,        
                 // 2 - ParMA, 3 - LRMA, 4 - T3, 5 - SMA, 6 - EMA, 7 - SSMA, 8 - LWMA
extern int Length1 = 9;   // depth of smoothing 
extern int Phase1  = 100; // parameter changing in limits -100 ... +100, 
                                       //influences the quality of the transient process;
extern int Smooth_Mode2 = 0;   // Choosing the 2nd smoothing algorithm 0 - JJMA, 1 - JurX,        
                 // 2 - ParMA, 3 - LRMA, 4 - T3, 5 - SMA, 6 - EMA, 7 - SSMA, 8 - LWMA
extern int Length2 = 5;   // depth of smoothing 
extern int Phase2  = 100; // parameter changing in limits -100 ... +100, 
                                       //influences the quality of the transient process;  
extern int Shift  = 0;   // indicator shift along the time axis 
extern int Input_Price_Customs = 0; /* Selecting prices, upon which the calculation of 
the indicator is performed (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */
//---- +------------------------------------------------------------------------------+
//---- buffers
double X2MA[];
//---- variables  
bool INIT;
int  StartBar, StartBar1, StartBar2;
//+X================================================================X+   
//| SmoothXSeries() function                                         |
//+X================================================================X+    
//----+ Declaring the function SmoothXSeries
//----+ Declaring the function SmoothXSeriesResize 
//----+ Declaring the function SmoothXSeriesAlert   
#include <SmoothXSeries.mqh> 
//+X================================================================X+   
//| PriceSeries() function                                           |
//+X================================================================X+    
//----+ Declaring the function PriceSeries
//----+ Declaring the function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+X================================================================X+   
//| X2MA initialization function                                     |
//+X================================================================X+ 
int init() 
{ 
//----+
   //---- setting the style of the indicator presentation 
   SetIndexStyle(0, DRAW_LINE); 
   //---- defining a buffer for calculations 
   SetIndexBuffer(0, X2MA);
   //---- setting the values of the indicator that will not be visible on the chart
   SetIndexEmptyValue(0, 0.0); 
   //---- setting alerts for not allowed values of external variables
   JJMASeriesAlert (0, "Length1", Length1);
   JJMASeriesAlert (1, "Phase1",   Phase1);
   JJMASeriesAlert (0, "Length2", Length2);
   JJMASeriesAlert (1, "Phase2",   Phase2);
   PriceSeriesAlert(Input_Price_Customs);
   //----+ Changing sizes of buffer variables of the function
           //SmoothXSeries, number = 2(Two calls of the SmoothXSeries function)
   if (SmoothXSeriesResize(2) != 2)
    {
     INIT = false;
     return(0);
    }
   //---- initialization of variables
   if (Smooth_Mode1 > 0 && Smooth_Mode1 < 9) 
                              StartBar1 = Length1;
   else StartBar1 = 30;
   
   if (Smooth_Mode2 > 0 && Smooth_Mode2 < 9) 
                              StartBar2 = Length2;
   else StartBar2 = 30;
   StartBar = StartBar1 + StartBar2;
   //---- setting the bar number,
                     //starting from which the indicator will be drawn 
   SetIndexDrawBegin(0, StartBar); 
   //---- Setting the format of accuracy of the indicator drawing
   IndicatorDigits(Digits);
   //---- end of initialization
   INIT = true;
   return(0);
//----+ 
}
//+X================================================================X+  
//| X2MA iteration function                                          | 
//+X================================================================X+   
int start()
{
//----+ 
   //---- Getting the number of the last bar
   int Bars_ = Bars - 1;
//---- checking the initialization end and 
     //checking if the number of bars is enough for calculation
if (!INIT || Bars_ <= StartBar)
                  return(-1); 
//---- Introducing variables with a floating point
double Price, x1ma, x2ma;
//---- Introducing integer variables and obtaining the number 
                        //of already calculated bars
int reset, MaxBar1, MaxBar2, limit, 
                   bar, counted_bars = IndicatorCounted();
//---- checking for possible errors
if (counted_bars < 0)
    return(-1);
//---- the last calculated bar must be recalculated
if (counted_bars > 0)
counted_bars--;
//---- defining the number of the oldest bar, 
//starting from which new bars will be recalculated 
limit = Bars_ - counted_bars;
//---- defining the number of the oldest bar, 
//starting from which all bars will be recalculated 
MaxBar1 = Bars_;
MaxBar2 = MaxBar1 - StartBar1;

//----+ the main cycle of the indicator calculation
for(bar = limit; bar >= 0; bar--)
{
  //---- Getting the initial value of the price series
  Price = PriceSeries(Input_Price_Customs, bar);
  //---- X1MA smoothing of the initial value of the price series, 
  //---- Call of the SmoothXSeries function number 0, 
//parameters Phase and Length are not changed at each bar (din = 0)
  x1ma = SmoothXSeries(0, Smooth_Mode1, 0, MaxBar1, limit, 
                                     Phase1, Length1, Price, bar, reset);
  //---- checking that there are no errors in the previous operation
  if(reset != 0)
  return(-1);
  //---- X2MA smoothing of the obtained indicator, 
  //---- Call of the SmoothXSeries function number 1, 
//parameters Phase and Length are not changed at each bar (din = 0)
  x2ma = SmoothXSeries(1, Smooth_Mode2, 0, MaxBar2, limit, 
                                     Phase2, Length2, x1ma,  bar, reset);
  //---- checking that there are no errors in the previous operation
  if(reset != 0)
  return(-1);
  //----      
  X2MA[bar] = x2ma;
  //----
}
//----+ end of the indicator values calculation
return(0); 
//----+  
} 
//+X--------------------+ <<< The End >>> +--------------------X+

当然,与原始指标相比,最终指标会稍有延迟,但此类移动收到的错误提醒的数量将少得多,因此可与延迟相抵消。

可通过将此指标转换成一系列连续的值从而进入量化(离散),改进此指标。 一个简单的算法可用于此目的:

       //----+ normalizing the obtained value x2ma
       double Norma = Step * Point;
       //----
       x2ma /= Norma;
       x2ma = NormalizeDouble(x2ma, 0);
       x2ma *= Norma;

Step 变量是指标的整个外部参数,它定义获得的移动值离散步长(以点为单位)。 我未在本文中列入其代码 - 你可以使用本文附上的指标 X2DigMa.mq4 进行查看。



有关使用 X2DigMa.mq4 指标优化 Expert Advisor 的实用建议

此移动有大量外部变量,这就是基于此指标制定的任何 Expert Advisor 都能很好地适应任何市场的原因。 然而,对于进一步操作而言,EA 参数的格式安排并不是最佳的编程方式。 我们来详细介绍在 Expert Advisor 中处理此类移动的外部变量的工作详情。 假设我们有一个 EA,在此 EA 中,移动 X2DigMA.mq4 的所有外部变量都被设置成 EA 的外部变量。

extern int Smooth_Mode1 = 0; 
extern int Length1 = 9; 
extern int Phase1  = 100;
extern int Smooth_Mode2 = 0;
extern int Length2 = 5; 
extern int Phase2  = 100;
extern int Step = 10;
extern int Input_Price_Customs = 0;

Smooth_Mode1 变量接受 0 到 8 的值,但我不建议在测试程序中使用遗传算法对此变量的值进行优化。 最好的做法是,为此变量的每个值进行八次单独的优化。 重复平滑处理的类似变量 Smooth_Mode2 的值应最好固定为零。 在这种情况下,JMA 平均算法将被用作为重复平滑处理。 此算法具有最小延迟,并提供最佳结果作为很多情况下的额外平均处理。

仅用于 JMA 系列和 T3 系列平均的参数 Phase1 和 Phase2 应最好固定为 100。 Length2 参数可以使用任何值,但在很多情况下和在完全不同的 EA 中,最佳值往往与系列 3、5、 7、 9、11 中的值相同。 使用 Length2 参数的这些值足以构成一项规则。 Step 参数很大程度上依赖于 EA 所针对的市场和图表周期;然而,它往往固定为同一个值。 Input_Price_Customs 参数的最佳值通常为 0 和 9。 经过深入分析,只剩下一个参数 - Length1;它的值可以不同。



通用 MACD 图表

使用我提供的 SmoothXSeries() 函数,你可以构建任何经典技术分析指标,例如 MACD 图表,它是包含两个指标的图表。 第一个是关于两个移动之间的差的图表;第二个是此差的移动平均线。

/*
For the operation of the indicator the files 

SmoothXSeries.mqh
T3Series.mqh
MASeries.mqh
LRMASeries.mqh
JurXSeries.mqh
ParMASeries.mqh
JJMASeries.mqh 
PriceSeries.mqh 
should be located in  the directory: MetaTrader\experts\include\

Heiken Ashi#.mq4
should be located in  the directory: MetaTrader\indicators\
*/
//+X================================================================X+  
//|                                                        XMACD.mq4 | 
//|                        Copyright © 2009,        Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+X================================================================X+   
#property copyright "Copyright © 2009, Nikolay Kositsin"
#property link "farria@mail.redcom.ru" 
//---- drawing the indicator in the main window
#property  indicator_separate_window 
//---- number of indicator buffers
#property indicator_buffers 2 
//---- colors of the indicator
#property  indicator_color1  Blue
#property  indicator_color2  Magenta
//---- width of the diagram line
#property  indicator_width1  2
//---- INPUT PARAMETERS OF THE INDICATOR
extern int MACD_Mode = 0;  // Choosing the smoothing algorithm for MACD 0 - JJMA, 1 - JurX,        
                 // 2 - ParMA, 3 - LRMA, 4 - T3, 5 - SMA, 6 - EMA, 7 - SSMA, 8 - LWMA
extern int MACD_Phase = 100;
extern int FastXMA = 12;
extern int SlowXMA = 26;
extern int Signal_Mode = 0;  // Choosing the smoothing algorithm for the signal line 
  //0 - JJMA, 1 - JurX, 2 - ParMA, 3 - LRMA, 4 - T3, 5 - SMA, 6 - EMA, 7 - SSMA, 8 - LWMA
extern int Signal_Phase = 100;
extern int SignalXMA = 9;
extern int Input_Price_Customs = 0; /* Selecting prices, upon which the calculation of 
the indicator is performed (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */
//---- indicator buffers
double     XMacdBuffer[];
double     XSignalBuffer[];
//---- variabless 
bool   INIT;
int    StartBar, StartBar1, StartBar2;
//+X================================================================X+   
//| SmoothXSeries() function                                         |
//+X================================================================X+    
//----+ Declaring the function SmoothXSeries
//----+ Declaring the function SmoothXSeriesResize 
//----+ Declaring the function SmoothXSeriesAlert   
#include <SmoothXSeries.mqh> 
//+X================================================================X+   
//| PriceSeries() function                                           |
//+X================================================================X+    
//----+ Declaring the function PriceSeries
//----+ Declaring the function PriceSeriesAlert 
#include <PriceSeries.mqh>
//+X================================================================X+ 
//| XMACD indicator initialization function                          |
//+X================================================================X+ 
int init()
  {
//----+
   //---- setting the style of the indicator presentation 
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexStyle(1, DRAW_LINE);
   //---- Setting the accuracy format (number of digits 
        //after the decimal point) for the visualization of the indicator values 
   IndicatorDigits(Digits + 1);
   //---- defining buffers for calculation 
   SetIndexBuffer(0, XMacdBuffer);
   SetIndexBuffer(1, XSignalBuffer);
   //---- names for data windows and labels for subwindows
   IndicatorShortName(StringConcatenate
            ("XMACD(", FastXMA, ",", SlowXMA, ",", SignalXMA, ")"));
   SetIndexLabel(0, "XMACD");
   SetIndexLabel(1, "XSignal");
   //---- setting alerts for not allowed values of external variables
   JJMASeriesAlert (0, "FastXMA", FastXMA);
   JJMASeriesAlert (0, "SlowXMA", SlowXMA);
   JJMASeriesAlert (0, "SignalXMA", SignalXMA);
   //----
   JJMASeriesAlert (1, "MACD_Phase", MACD_Phase);  
   JJMASeriesAlert (1, "Signal_Phase", Signal_Phase);
   PriceSeriesAlert(Input_Price_Customs);
   //---- Changing sizes of buffer variables of the function
           //SmoothXSeries, number = 3(Three calls of the SmoothXSeries function)
   if (SmoothXSeriesResize(3) != 3)
    {
     INIT = false;
     return(0);
    }
   //---- initialization of variables 
   if (MACD_Mode > 0 && MACD_Mode < 9) 
                            StartBar1 = MathMax( FastXMA, SlowXMA);
   else StartBar1 = 30;
   //----
   if (Signal_Mode > 0 && Signal_Mode < 9) 
                          StartBar2 = SignalXMA;
   else StartBar2 = 30;
   //----
   StartBar = StartBar1 + StartBar2;
   //----
   SetIndexDrawBegin(0, StartBar1);
   SetIndexDrawBegin(1, StartBar);
   //---- end of initialization
   INIT = true;
   return(0);
//----+
  }
//+X================================================================X+ 
//| XMACD indicator iteration function                               |
//+X================================================================X+ 
int start()
  {
//----+
   //---- Getting the number of the last bat
   int Bars_ = Bars - 1;
//---- checking the initialization end and 
     //checking if the number of bars is enough for calculation
if (!INIT || Bars_ <= StartBar)
                  return(-1); 
//---- Introducing variables with a floating point
double Price, FastXMA_, SlowXMA_, XMACD, SignalXMA_;
//---- Introducing integer variables and obtaining the number 
                        //of already calculated bars
int reset, MaxBar1, MaxBar2, limit, 
                   bar, counted_bars = IndicatorCounted();
//---- checking for possible errors
if (counted_bars < 0)
    return(-1);
//---- the last calculated bar must be recalculated
if (counted_bars > 0)
counted_bars--;
//---- defining the number of the oldest bar, 
//starting from which new bars will be recalculated 
limit = Bars_ - counted_bars;
//---- defining the number of the oldest bar, 
//starting from which all bars will be recalculated 
MaxBar1 = Bars_;
MaxBar2 = MaxBar1 - StartBar1;

   //----+ the main cycle of the indicator calculation
for(bar = limit; bar >= 0; bar--)
{
  //---- Getting the initial value of the price series
  Price = PriceSeries(Input_Price_Customs, bar);
  //---- FastXMA smoothing of the initial value of the price series, 
  //---- Call of the SmoothXSeries function number 0, 
//parameters Phase and Length are not changed at each bar (din = 0)
  FastXMA_ = SmoothXSeries(0, MACD_Mode, 0, MaxBar1, limit, 
                              MACD_Phase, FastXMA, Price, bar, reset);
  //---- checking that there are no errors in the previous operation
  if(reset != 0)
  return(-1);
  //---- SlowXMA smoothing of the initial value of the price series, 
  //---- Call of the SmoothXSeries function number 1, 
//parameters Phase and Length are not changed at each bar (din = 0)
  SlowXMA_ = SmoothXSeries(1, MACD_Mode, 0, MaxBar1, limit, 
                             MACD_Phase, SlowXMA, Price,  bar, reset);                       
  //---- checking that there are no errors in the previous operation
  if(reset != 0)
  return(-1);
  //----   
  if(bar < MaxBar2) 
         XMACD = FastXMA_ - SlowXMA_;
  
  //---- SignalXMA smoothing of the obtained XMACD diagram, 
  //---- Call of the SmoothXSeries function number 2, 
//parameters Phase and Length are not changed at each bar (din = 0)
  SignalXMA_ = SmoothXSeries(2, Signal_Mode, 0, MaxBar2, limit, 
                         Signal_Phase, SignalXMA, XMACD,  bar, reset);            
  //---- checking that there are no errors in the previous operation
  if(reset != 0)
  return(-1);
  //----
  XMacdBuffer[bar] = XMACD;
  XSignalBuffer[bar] = SignalXMA_;   
    }
   return(0);
  
//----+
  }
//+X----------------------+ <<< The End >>> +-----------------------X+

在 Expert Advisor 中处理此类指标的逻辑在很多方面都类似于我在上面所写到的,但在这里,Signal_Mode 变量的值应最好进行遗传优化。



总结

使用 SmoothXSeries() 函数的调用,你可以构建任何技术分析指标,而这些指标可能往往会高于其经典类似对象的技术分析指标。 当然,这需要在指标编写方面具有一定的经验,但得到的最终结果值得付出所有的努力。

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1563

附加的文件 |
INCLUDE.zip (47.51 KB)
indicators.zip (11.54 KB)
最近评论 | 前往讨论 (1)
wten123
wten123 | 30 11月 2016 在 03:16

Hello!

I'm the new mt4 learner, very like your code。XMACD.mq4 

but this code (XMACD.mq4 include ) does not contain SmoothXSeries. mq4。

 

I hope you can send me a copy.

Thank you very much!

通道 高级模型 沃夫波浪 通道 高级模型 沃夫波浪
本文描述了标记沃夫波浪形态的规则。 你可以在这里找到构建的详情和准确标记的规则,有助于快速无误的找到正确的波浪形态。
神经网络诀窍 神经网络诀窍
本文面向"多层"蛋糕烘焙初学者。
在 MetaTrader 中使用神经网络 在 MetaTrader 中使用神经网络
本文介绍如何轻松在你的 MQL4 代码中使用神经网络,利用最佳的免费人工神经网络库 (FANN),并在 MQL4 代码中采用多个神经网络。
在 MQL4 中处理双精度浮点数 在 MQL4 中处理双精度浮点数
在本文中我们将研究典型的编程错误,这种错误在处理 MQL4 程序中的双精度数值时会出现。