Почему я получаю массив нашего диапазона в MQL4?

Я пытаюсь сделать индикатор, который показывает, когда на графике появляется x свечей одного цвета. Но я получаю ошибку массива вне диапазона.

  • Существует буфер массива вверх и вниз (стрелка, указывающая вверх или вниз)
  • minCandles – это extern 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);
 }


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

person Sebastian Bonilla    schedule 11.10.2016    source источник
comment
Не могли бы вы, Себастьян, опубликовать полный код? Отсутствуют как объявления, так и экстерны, определения индикаторных буферов также не включены. StackOverflow рекомендует пользователям публиковать сообщения высокого качества на основе M-минимум C-полный V-проверяемый E- обширные (включая данные, где это уместно), которые одновременно демонстрируют проблему и служат автономным средством проверки рабочего решения. Еще одна справедливая политика — опубликовать полную копию возражаемого сообщения об ошибке (из журнала терминала MetaTrader 4… используя щелчок правой кнопкой мыши + Копировать… можно публиковать его довольно удобно)   -  person user3666197    schedule 12.10.2016
comment
готово, я скопировал весь код   -  person Sebastian Bonilla    schedule 12.10.2016
comment
Отличный шаг, Себастьян, и фактическое сообщение об ошибке из [MetaTrader Terminal 4] Terminal - log (копировать/вставить)?   -  person user3666197    schedule 12.10.2016
comment
Кроме того, почему вы изменили утверждение медвежья часть работает, а бычья – нет на другое, работает медвежья часть, но справа налево.? Было ли это связано с некоторыми новыми наблюдениями, относящимися к усилиям по изоляции проблемы, или просто с необходимостью пересмотреть сформулированную исходную гипотезу из исходного вопроса, поскольку она вводила в заблуждение часть определения проблемы?   -  person user3666197    schedule 12.10.2016


Ответы (1)


За написанием быстрого и эффективного [ Пользовательского индикатора ] MQL4 кода стоит несколько странных вещей.

Во-первых, головная боль в реальном времени, возникающая из-за дизайнерского решения собрать все вычислительные усилия всех существующих [Пользовательских индикаторов] в один поток.

Хотя это скрыто, это увеличивает давление, чтобы свести к минимуму все задержки выполнения за счет того, что совокупность работает в сегментированных мини-пакетах, от самой глубокой истории (самые дальние столбцы слева) итеративно продвигаясь вперед вправо, к Текущий Бар.

Можно запутаться в концепции обратной нумерации баров, начиная с [0] — для самого последнего бара (живого бара), считая вверх, погружаясь все глубже и глубже в историю на далеко слева.

Если этого недостаточно, внутри [ Пользовательского индикатора ] есть еще некоторые запрещенные вещи, но, поскольку ваша веб-страница показывает, что вы предоставляете программирование [ Пользовательского индикатора ] на коммерческой основе, бесполезно повторять их здесь снова.


Код производственного уровня для [Пользовательского индикатора] должен содержать как минимум:

  • защитные предохранители
  • минимальные накладные расходы основного рабочего цикла
  • ноль необработанных-Comment()-ов, чтобы избежать повреждений графического интерфейса пользователя / 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
    }
//+------------------------------------------------------------------+
person user3666197    schedule 12.10.2016
comment
Спасибо, это имеет больше смысла. Я все еще новичок в MQL4, и мне еще многое предстоит узнать. - person Sebastian Bonilla; 12.10.2016
comment
когда я запускаю это, я все еще получаю ошибку массива вне диапазона - person Sebastian Bonilla; 12.10.2016
comment
Ну, а как насчет того, чтобы добавить трассировочную сетку отладочных Print( __LINE__, ... , GetLastError() );-ов между всеми строками, перезапустить код + скопировать/вставить Terminal-Log? - person user3666197; 13.10.2016