Несколько буферов в одном советнике. Ошибка возврата CopyBuffer 4806 - PullRequest
1 голос
/ 28 марта 2020

В советнике использовалось 3 скользящих средних, и каждая МА имеет свой собственный буфер, но CopyBuffer никогда не возвращает запрошенный счетчик баров для второй МА. Только первая MA ExtFastBuffer получила значения буфера, все остальное остается пустым, а их CopyBuffer возвращает ошибку 4806. В чем моя ошибка?

#property indicator_buffers 3

input ENUM_TIMEFRAMES ma_fast_timeframe = PERIOD_M1;
input int ma_fast_period = 2;
input ENUM_APPLIED_PRICE ma_fast_price_type = PRICE_MEDIAN;

input ENUM_TIMEFRAMES ma_middle_timeframe = PERIOD_M1;
input int ma_middle_period = 15;
input ENUM_APPLIED_PRICE ma_middle_price_type = PRICE_MEDIAN;

input ENUM_TIMEFRAMES ma_slow_timeframe = PERIOD_M1;
input int ma_slow_period = 30;
input ENUM_APPLIED_PRICE ma_slow_price_type = PRICE_MEDIAN;

int ExtFastHandle;
int ExtMiddleHandle;
int ExtSlowHandle;

double ExtFastBuffer[];
double ExtMiddleBuffer[];
double ExtSlowBuffer[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, ExtFastBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(1, ExtMiddleBuffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(2, ExtSlowBuffer, INDICATOR_CALCULATIONS);

   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);

   ExtFastHandle = iMA(NULL, ma_fast_timeframe, ma_fast_period, 0, MODE_SMA, ma_fast_price_type);
   ExtMiddleHandle = iMA(NULL, ma_middle_timeframe, ma_middle_period, 0, MODE_SMA, ma_middle_price_type);
   ExtSlowHandle = iMA(NULL, ma_slow_timeframe, ma_slow_period, 0, MODE_SMA, ma_slow_price_type);

   if(ExtFastHandle == INVALID_HANDLE || ExtMiddleHandle == INVALID_HANDLE || ExtSlowHandle == INVALID_HANDLE)
     {
      Print("Error creating MA indicator-----------------------------------------------------------------------");
      return(INIT_FAILED);
     }

   return(INIT_SUCCEEDED);
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   int startFromIndex = 0;
   int bufferSize = 2;

//---------------- Fast MA
   if(CopyBuffer(ExtFastHandle, 0, startFromIndex, bufferSize, ExtFastBuffer) < 2)
     {
      Print("Loading ExtFastHandle failed ", GetLastError());
     }
   ENUM_ORDER_TYPE fastDir = ExtFastBuffer[0] == ExtFastBuffer[1] ? NULL : (ExtFastBuffer[0] < ExtFastBuffer[1] ? ORDER_TYPE_BUY : ORDER_TYPE_SELL);

//---------------- Middle MA
   if(CopyBuffer(ExtMiddleHandle, 1, startFromIndex, bufferSize, ExtMiddleBuffer) < 2)
     {
      Print("Loading ExtMiddleHandle failed ", GetLastError());
     }
   ENUM_ORDER_TYPE middleDir = ExtMiddleBuffer[0] == ExtMiddleBuffer[1] ? NULL : (ExtMiddleBuffer[0] < ExtMiddleBuffer[1] ? ORDER_TYPE_BUY : ORDER_TYPE_SELL);

//---------------- Slow MA
   if(CopyBuffer(ExtSlowHandle, 2, startFromIndex, bufferSize, ExtSlowBuffer) < 2)
     {
      Print("Loading ExtSlowHandle failed ", GetLastError());
     }
   ENUM_ORDER_TYPE slowDir = ExtSlowBuffer[0] == ExtSlowBuffer[1] ? NULL : (ExtSlowBuffer[0] < ExtSlowBuffer[1] ? ORDER_TYPE_BUY : ORDER_TYPE_SELL);

   string fast = fastDir == NULL ? "EMPTY" : fastDir == ORDER_TYPE_BUY ? "BUY" : "SELL";
   string middle = middleDir == NULL ? "EMPTY" : middleDir == ORDER_TYPE_BUY ? "BUY" : "SELL";
   string slow = slowDir == NULL ? "EMPTY" : slowDir == ORDER_TYPE_BUY ? "BUY" : "SELL";
   Comment("Fast: ", fast, " Middle: ", middle, " Slow: ", slow);
  }
//+------------------------------------------------------------------+

1 Ответ

1 голос
/ 28 марта 2020

Посмотрите на примеры советников, таких как EMA или MACD.

  1. Нет необходимости в SetIndexBuffer вызовах в советнике, они используются в индикаторах.
  2. Второй параметр в CopyBuffer - это номер буфера индикаторов. Так что, если у MA есть только один буфер, используйте 0 все время. Если индикатор имеет два буфера, как MACD, главная линия будет иметь индекс 0, сигнальная линия будет вызываться с индексом 1.

    //---------------- Middle MA
    if(CopyBuffer(ExtMiddleHandle, 0, startFromIndex, bufferSize, ExtMiddleBuffer) < 2)  
      {  
       Print("Loading ExtMiddleHandle failed ", GetLastError());
      }  
    ENUM_ORDER_TYPE middleDir = ExtMiddleBuffer[0] == ExtMiddleBuffer[1] ? NULL : (ExtMiddleBuffer[0] < ExtMiddleBuffer[1] ? ORDER_TYPE_BUY : ORDER_TYPE_SELL);
    
    //---------------- Slow MA  
    if(CopyBuffer(ExtSlowHandle, 0, startFromIndex, bufferSize, ExtSlowBuffer) < 2)  
      {  
       Print("Loading ExtSlowHandle failed ", GetLastError());
      }  
    ENUM_ORDER_TYPE slowDir = ExtSlowBuffer[0] == ExtSlowBuffer[1] ? NULL : (ExtSlowBuffer[0] < ExtSlowBuffer[1] ? ORDER_TYPE_BUY : ORDER_TYPE_SELL);
    
...