Индикаторный буфер возвращает ноли, помогите разобраться

 

Совсем мало работал с индикаторами, поэтому не могу понять в чем бага. Строится индикатор RSI по хэндлу другого индикатора, который возвращает модифицированные цены. Так вот индикатор RSIscaled по 0 буферу возвращает ноли при обращении к нему из эксперта, хотя буфер не пустой..

Код индикатора:

//+------------------------------------------------------------------+
//|                                                    RSIscaled.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#property indicator_buffers 2
//--- input parameters
input int AnalyzeDepth=200;
input int Shift=50;
input int ScaleMultiplier=5;

double PricesBuffer[], ForecastPrices[];
double IntermediatePrices[], IntermediateForecasts[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   ArrayResize(IntermediatePrices,AnalyzeDepth*ScaleMultiplier);
   ArrayResize(IntermediateForecasts,Shift*ScaleMultiplier);
   ArrayResize(PricesBuffer,AnalyzeDepth);
   ArrayInitialize(PricesBuffer,0.0);
   ArrayResize(ForecastPrices,Shift);
   ArrayInitialize(ForecastPrices,0.0);
//--- indicator buffers mapping
   SetIndexBuffer(0,PricesBuffer);
   SetIndexBuffer(1,ForecastPrices); 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---  
   ArrayCopy(IntermediatePrices,price,0,Shift*ScaleMultiplier,AnalyzeDepth*ScaleMultiplier);
   ArrayCopy(IntermediateForecasts,price,0,0,Shift*ScaleMultiplier);
   
   int scnext=0;
         for(int l=0; l<AnalyzeDepth;l++)
           {
            PricesBuffer[l]=IntermediatePrices[scnext];
            scnext+=ScaleMultiplier;
            //Print(PricesBuffer[l]); В БУФЕР ПОПАДАЮТ ЗНАЧЕНИЯ
           }
         scnext=0;
         for(int l=0; l<Shift;l++)
           {
            ForecastPrices[l]=IntermediateForecasts[scnext];
            scnext+=ScaleMultiplier;
           // Print(ForecastPrices[l]); 
           }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Код эксперта, вызывающего индикатор:

//+------------------------------------------------------------------+
//|                                              ScaledRSItrader.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
input int AnalyzeDepth=200;
input int Shift=50;
input int ScaleMultiplier=5;
double RSIbuff[], Spricesbuff[];
int sprices_hnd, rsi_hnd;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   sprices_hnd = iCustom(NULL,0,"RSIscaled",AnalyzeDepth,Shift,ScaleMultiplier,PRICE_CLOSE); //ЗАДАЕМ ХЭНДЛ ИНДИКАТОРА
   rsi_hnd = iRSI(NULL,0,9,sprices_hnd);
   ArrayResize(Spricesbuff,AnalyzeDepth);
   ArrayInitialize(Spricesbuff,0);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   CopyBuffer(sprices_hnd,0,0,AnalyzeDepth,Spricesbuff); //ОБРАЩАЕМСЯ К НУЛЕВОМУ БУФЕРУ ИНДИКАТОРА
   CopyBuffer(rsi_hnd,0,0,AnalyzeDepth,RSIbuff);
   Print(Spricesbuff[0]); //МАССИВ ВСЕ ВРЕМЯ ПУСТОЙ, В ЧЕМ КОСЯК?
  }
//+------------------------------------------------------------------+
 

1. Накидываем индикатор на график, смотрим в окно "DataWindow" - а там нули:

пусто

2. Так сколько же буферов в индикаторе? И сколько в индикаторе графических серий?

 
Vladimir Karputov:

1. Накидываем индикатор на график, смотрим в окно "DataWindow" - а там нули:

2. Так сколько же буферов в индикаторе? И сколько в индикаторе графических серий?


2 буфа, нет графических серий т.к. они не нужны, это просто обменник.. странно, а через Print() показывает что буфер не пустой (в самом индикаторе)

2-й буф пока не смотрим, с 0-м не могу понять

 
Maxim Dmitrievsky:

2 буфа, нет графических серий т.к. они не нужны, это просто обменник.. странно, а через Print() показывает что буфер не пустой


Если массив будет буфером для данных - он должен помечаться как INDICATOR_DATA, если это будет расчётный буфер - используется для промежуточных вычислений - он должен помечаться как  INDICATOR_CALCULATIONS.

Хоть это обменник, хоть разменник нужно обрабатывать первый запуск (prev_calculate==0).

Так как буферы БУДУТ помечены как INDICATOR_DATA и как INDICATOR_CALCULATIONS, то не нужно (даже более того - это нельзя) делать ArrayResize над ИНДИКАТОРНЫМИ буферами.

 
Vladimir Karputov:


Если массив будет буфером для данных - он должен помечаться как INDICATOR_DATA, если это будет расчётный буфер - используется для промежуточных вычислений - он должен помечаться как  INDICATOR_CALCULATIONS.

Хоть это обменник, хоть разменник нужно обрабатывать первый запуск (prev_calculate==0).

Так как буферы БУДУТ помечены как INDICATOR_DATA и как INDICATOR_CALCULATIONS, то не нужно (даже более того - это нельзя) делать ArrayResize над ИНДИКАТОРНЫМИ буферами.


Да его хоть как не помечай он все равно ноли возвращает

Все разобрался, нужно сделать ArraySetAsSeries(PricesBuffer,true); и массив price тоже :)

INDICATOR_DATA не обязательно делать, он все равно возвращает значения

Причина обращения: