如何在MQL4中量化指标?

时间:2012-07-11 19:41:32

标签: algorithmic-trading mql4 metatrader4

我正在尝试让这个指标在中使用2个缓冲区进行量化。经过很长一段时间的阅读后,我已经放了2个额外的缓冲区来挤压它:/因为:

  

指标目前位于 0.1430-0.1427 之间,但没有固定的顶部和底部

我似乎无法理解它;很酷的指标,但不会公平!

#property indicator_separate_window
#property indicator_buffers   4
#property indicator_color1    Lime
#property indicator_color2    Red
#property indicator_color3    CLR_NONE
#property indicator_color4    CLR_NONE
//#property indicator_minimum 0
//#property indicator_maximum 100
extern int    P   =   13;
extern int    T   = 3000;
extern double P2  =    0.001;
//int         MIN =    0;
//int         MAX =  100;
double G[];
double R[];
double B3[];
double B4[];

int init(){
   IndicatorBuffers(4);
   SetIndexBuffer( 0, G  );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime );
   SetIndexBuffer( 1, R  );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red  );
   SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE );
   SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE );
   return(0);
}
int start(){
      if (  T >= Bars ) T = Bars;

      SetIndexDrawBegin( 0, Bars - T + P + 1 );
      SetIndexDrawBegin( 1, Bars - T + P + 1 );
      SetIndexDrawBegin( 2, Bars - T + P + 1 );
      SetIndexDrawBegin( 3, Bars - T + P + 1 );

      int Z, C, Opt = IndicatorCounted();

      if (  Bars <= 38 ) return(0);

      if (  Opt  <  P ){
         for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0;
         for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0;
      }

      Z = T - P - 1;

      while( Z >= 0 ){
         double A, S1, S2;
         S1 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S1 = S1 + (   High[Z+C] + Low[Z+C] ) / 2;}
         S2 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );}
         A  = S1 / S2;
         // if (  A < MIN ){ MIN = A;}
         // if (  A > MAX ){ MAX = A;}
         // A = ( MIN / MAX ) * 100;
         G[Z] = A;
         if (  Z > 0 ){ R[Z-1] = A;}
         Z--;
      }
      for ( int N = T-P-2; N >= 0; N-- ){
         if (  N > 0 ){
               if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;}
               if ( G[N-1] < G[N] ){ G[N] = R[N];        continue;}
         }
         B3[0] = G[0] + P2;
         B4[0] = G[0] - P2; //forced quantise using 2 extra buffers
      }
      return(0);
   }

1 个答案:

答案 0 :(得分:1)

让我们先分开任务

0 )指标逻辑
1 )指标量化步骤
2 )指标效果

MQL4 自定义指标编程依赖于对底层 MetaTrader4终端平台的更深入理解。每个外部市场事件(更改交易的工具价格)都通过网络传递来自 MetaTrader4服务器 QUOTE ... 消息通知lcoalhost。这也就是Tick,它会触发对最初名为 start() 的函数的调用,在较新的 - MQL4.56789中重命名为 {{ 1}}

以下修改后的OnTick()列表包含核心逻辑消歧的备注,该备注必须位于以下列出的所有步骤之前。

1 )指标量化步骤

虽然代码仍然非常低效(如下面[2]所述),但逻辑不包括任何直接的障碍形式,其输出量化为其任何形式{binary |三元|任意数量的状态} - 量化系统。当指标核心逻辑被清除时,量化步骤只是从 R(1) I(1)的微不足道的转换。

2 )指标效果

任何Tick到达都可以,但无需修改MQL4High[0],这是建议的自定义指标演算的唯一可变部分。

这是关于如何减少重新计算范围的核心思想,Low[0]代码必须实现每个滴答。在MT4的最新版本中,所有自定义指标共享一个线程,对自定义指标的高效算法化施加的压力就越大,这可能会阻碍平台在糟糕,低效的代码循环上做出的交易决策。卷积/递归重新执行。

MQL4

- #property indicator_separate_window #property indicator_buffers 4 #property indicator_color1 Lime #property indicator_color2 Red #property indicator_color3 CLR_NONE #property indicator_color4 CLR_NONE extern int P = 13; extern int T = 3000; extern double P2 = 0.001; double G[]; // 0: LINE double R[]; // 1: LINE double B3[]; // 2: BUT NEVER PAINTED, NEVER CONSUMED _?_ double B4[]; // 3: BUT NEVER PAINTED, NEVER CONSUMED _?_ int init(){ IndicatorBuffers(4); SetIndexBuffer( 0, G );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime ); SetIndexBuffer( 1, R );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red ); SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE ); SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE ); return(0); } int start(){ if ( Bars <= 38 ) return(0); // JIT/RET in case Bars < 39 --^ --^ --^ --^ if ( T >= Bars ) T = Bars; // (TRIM´d) T < Bars .OR. = Bars int aDrawBegins = Bars - T + P + 1; // ( extern P = 13 ) + 1 + ( Bars - ( extern T = 3000 if T < Bars else Bars ) ) //tIndexDrawBegin( 0, Bars - T + P + 1 ); // PREF: ( reused 4x ) SetIndexDrawBegin( 0, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw? SetIndexDrawBegin( 1, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw? SetIndexDrawBegin( 2, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw? SetIndexDrawBegin( 3, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw? double A, S1, S2; // auxiliary var for bar-mid-price calculi int Z; // auxiliary stepper int Opt = IndicatorCounted(); // Opt ( NEVER RE-USED ) if ( Opt < P ){ // if ( ( extern P = 13 ) > IndicatorCounted() ) // ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 ) for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0; // .STO G[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 ) for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0; // .STO R[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 ) // ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 ) } Z = T - P - 1; // .STO Z, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 1 while( Z >= 0 ){ // .DEC Z // !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !! S1 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S1 = S1 + ( High[Z+C] + Low[Z+C] ) / 2; } S2 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );} // !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !! A = S1 / S2; G[Z] = A; // .STO G[Z], A if Z >= 0 if ( Z > 0 ){ R[Z-1] = A;} // .STO R[Z-1], A if Z > 0 Z--; } for ( int N = T - P - 2; N >= 0; N-- ){ // .STO N, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 2 if ( N > 0 ){ // N > 0: if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;} // .BLNK R[N], EMPTY if G[N-1] > G[N] if ( G[N-1] < G[N] ){ G[N] = R[N]; continue;} // .SET G[N], R[N] if G[N-1] < G[N] } // ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ?? B3[0] = G[0] + P2; // .STO B3[0], G[0] + ( extern P2 = 0.001 ) B4[0] = G[0] - P2; // .STO B4[0], G[0] - ( extern P2 = 0.001 ) // forced quantise using 2 extra buffers // ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ?? } return(0); } 语法

当需要通过 Calculate事件计算指标值时,仅在自定义指标中调用 MQL4.56789 函数。这通常在收到符号的新刻度时发生,为此计算指标。此指标不需要附加到此符号的任何价格图表中。

第一个 OnCalculate() 参数包含 rates_total 的数量,可用于计算指标,并对应于可用的柱数在图表中。

我们应该注意 bars 的返回值与第二个输入参数 OnCalculate() 之间的关联。在prev_calculated函数调用期间,OnCalculate()参数包含{strong}上一次调用期间prev_calculated返回的值。这允许用于计算自定义指标的经济算法,以避免重复计算自上次运行此函数以来未发生变化的那些条。

为此,通常足以返回OnCalculate()参数的值,该参数包含当前函数调用中的柱数。如果自rates_total的最后一次调用以来价格数据发生了变化(下载了更深的历史记录或填充了历史空白),则终端将输入参数OnCalculate() 的值设置为零。

prev_calculated