为什么我在MQL4中得到数组范围?

时间:2016-10-11 21:29:22

标签: mql4

我正在尝试制作一个指示器,显示图表上出现相同颜色的x个蜡烛。但我得到一个超出范围错误的数组。

  • 有一个向上和向下的数组缓冲区(向上或向下的箭头)
  • minCandlesextern integer,用于确定指向箭头的条数。
  • 熊部分工作但从右到左。

我认为问题可能出在down[i] = Low[i],但我不知道原因。

以下是代码:

//+------------------------------------------------------------------+
//|                                                       SlayEm.mq4 |
//|                               Copyright 2016, Sebastian Bonilla. |
//|                                  https://www.sebastianbonilla.me |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Sebastian Bonilla."
#property link      "https://www.sebastianbonilla.me"
#property description "show X amount of candles of the same color."
#property version   "1.00"
#property strict
#property indicator_chart_window

//--- input parameters
extern int minCandles = 4;
double up[];
double down[];

//+------------------------------------------------------------------+    
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
SetIndexBuffer(0,up); //assign up to the first buffer
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,233);
SetIndexLabel(0, "Up Arrow");

 //stuff for 1
  SetIndexBuffer(1,down); //assign down to the second buffer
  SetIndexStyle(1,DRAW_ARROW);
  SetIndexArrow(1,234);
  SetIndexLabel(1, "Down Arrow");
 //---
return(INIT_SUCCEEDED);
}
  //+------------------------------------------------------------------+
  //| Custom indicator iteration function                              |
 //+------------------------------------------------------------------+
  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[],
            const int &spread[])
  {//------------------------------------------

int limit = MathMax(rates_total-prev_calculated,2);
int i; 
int bull_count = 0;
int bear_count = 0;

for (i = 1; i < limit; i++){

//--bears-----------------------------------------------------------------------------------
if(Open[i] >= Open[i-1]){
   bear_count++;
   if (bear_count > minCandles) up[i] = High[i];
}
else bear_count = 0;   // this by itself works but from right to left


// --- bulls ----------------------------------------

if(Open[i] < Open[i-1]){
   bull_count++;
   if (bull_count > minCandles) down[i] = Low[i];
}
else bull_count = 0;  //this part creates the array out of range error*/

}

Comment((string)bear_count+ " --- ", (string)bull_count +" --- ", (string)i);


 //--- return value of prev_calculated for next call
 return(rates_total);
 }


//+------------------------------------------------------------------+

1 个答案:

答案 0 :(得分:1)

编写快速有效的[自定义指标] MQL4 - 代码背后有一些奇怪的事情。

首先,来自设计决策的实时头痛是将所有现有[自定义指标]的所有计算工作累积到单个线程中。

虽然这是隐藏的,但它增加了压力以最小化所有执行延迟,其代价是以分段小批量操作的colculus,从最深的历史(最远的左边的条)向前迭代向前进行到右边,朝着现在的酒吧。

人们可能会对酒吧的反向编号概念感到困惑,从 [0] 开始 - 对于最近的Bar(实时酒吧),计数,然后更深入并且更深入地了解最左边的历史。

如果还不够,[自定义指标]中还有一些额外的禁止内容,但由于您的网页显示您在商业基础上提供[自定义指标]编程,因此在这里重复它们是毫无价值的试。

[自定义指标]的生产级代码应至少具有:

  • 保护性保险丝
  • 最小化主要工作周期开销
  • 零原始 - Comment() - s以避免损坏GUI / MMI
#property strict

//--- input parameters
extern int    minCandles = 4;

//--- input PROTECTIVE FUSES:

       int    minCandlesFUSED = MathMax( 2, minCandles );               // assign no less than 2 irrespective of the extern
       double up[];
       double down[];

//+------------------------------------------------------------------+    
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {

 // indicator buffers mapping
    SetIndexBuffer( 0, up );                                            // assign up[] to the first buffer
    SetIndexStyle(  0, DRAW_ARROW );
    SetIndexArrow(  0, 233 );
    SetIndexLabel(  0, "Up Arrow" );

 // stuff for 1
    SetIndexBuffer( 1, down );                                          // assign down[] to the second buffer
    SetIndexStyle(  1, DRAW_ARROW );
    SetIndexArrow(  1, 234 );
    SetIndexLabel(  1, "Down Arrow" );

 // RET
    return( INIT_SUCCEEDED );
    }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[],
                 const int      &spread[]
                 ) {
 // ------------------------------------------

    int          limit  = rates_total
                        - prev_calculated
                        + minCandlesFUSED;
    if (  Bars + limit <  minCandlesFUSED + 1 ) return( 0 ); // --> JIT/RET( 0 )
                                //               ^--------------------^--- MEANING-FULL value, ref prev_calculated mechanisation
                                // makes no sense to start indicator w/o at least minCandlesFUSED + 1 Bars ready
    int bull_count = 0;
    int bear_count = 0;

    for ( int i = limit + 1;    // iterator .SET             to start [limit + 1] Bars back in time (towards left), moving forwards -> [0]
              i > 0;            // iterator .PRE-CONDITION   to keep looping while i > [0] points to already exist. Bars->[1], leaving [0] out
              i--               // iterator .DEC             on loop-end, before re-testing next loop .PRE-CONDITION
              ){
       // --------------------------------------------------------------BEARS
          if (  Open[i] >= Open[i-1] ){
                bear_count++;
                if (  bear_count > minCandlesFUSED ) up[i] = High[i];   // ref. above the 
          }
          else  bear_count = 0;                                         // this by itself works

       // --------------------------------------------------------------BULLS
          if (  Open[i] < Open[i-1] ){
                bull_count++;
                if (  bull_count > minCandlesFUSED ) down[i] = Low[i];
          }
          else  bull_count = 0;                                          // this part creates the array out of range error*/

    }

    Comment( (string)bear_count                                         // rather use StringFormat( "TEMPLATE: %d UP --- %d DN --- ", bear_count,
           + " --- ",                                           //                                                            bull_count
             (string)bull_count                                         //                          )
           + " --- "
             );

    return( rates_total );                                              // return( rates_total ) value becomes -> prev_calculated for the next call
    }
//+------------------------------------------------------------------+