Пропадает график индикатора

 

Добрый день!

Индикатор предназначен для фьючерсных контрактов.

По умолчанию для BR со следующим месяцем = 1

Для трехмесячных контрактов нужно установить "След. фьючерс" = 3

Почему пропадает график (см. код)?


//+------------------------------------------------------------------+
//|                                                   BR_Scalper.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1

//--- plot Label1
#property indicator_label1  "Spread"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrYellow
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1


#define on_call -111
//
input int NextFutMonth = 1;    //След фьючерс (мес.)
input int aBars = 50;          //Бары  
//
double Buff[];//, BuyBuff[];
double pr_last, sec_last;
string sec_symbol;
bool pr_book, sec_book;
int event_cnt;

//+------------------------------------------------------------------+
//| Indicator Set second Symbols function                            |
//+------------------------------------------------------------------+
string SetSecSymbol(const string aSymbol)
{
  int str_tire = StringFind(aSymbol, "-");
  int str_tochka = StringFind(aSymbol, ".", str_tire);
  int str_size = StringLen(aSymbol);
  if((str_tire > 0) && (str_tochka > 0) && (str_size > 0))
  {
    string str_month = StringSubstr(aSymbol, str_tire + 1, str_tochka - str_tire - 1);
    string str_year = StringSubstr(aSymbol, str_tochka + 1, str_size - str_tochka - 1);
    long aMonth = StringToInteger(str_month);
    long aYear = StringToInteger(str_year);
    if((aMonth > 0) && (aYear > 0))
    {
      long n_month = aMonth + long(NextFutMonth);
      long add_year = (n_month - 1) / 12;
      aYear += add_year;
      str_year = IntegerToString(aYear); 
      aMonth = n_month - add_year * 12;
      str_month = IntegerToString(aMonth);
      return(StringSubstr(aSymbol, 0, str_tire + 1) + str_month + "." + str_year);
    } 
  }
  return("");
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  event_cnt = 0;
  sec_symbol = SetSecSymbol(Symbol());
  if(SymbolSelect(sec_symbol, true) == false)
  {
    return(INIT_FAILED);
  }
  pr_book = MarketBookAdd(Symbol());
  sec_book = MarketBookAdd(sec_symbol);
  IndicatorSetInteger(INDICATOR_DIGITS, 0);
  IndicatorSetString(INDICATOR_SHORTNAME, "BR_Scalper");
//---  
  SetIndexBuffer(0, Buff, INDICATOR_DATA);
  PlotIndexSetDouble( 0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
  ArraySetAsSeries(Buff, true );
//---Set objects
   int window=ChartWindowFind(ChartID(),"BR_Scalper");
   ObjectCreate(ChartID(),"BR_label_1",OBJ_LABEL,window,0,0);
   ObjectSetInteger(ChartID(),"BR_label_1",OBJPROP_YDISTANCE,15);
   ObjectSetInteger(ChartID(),"BR_label_1",OBJPROP_XDISTANCE,5);
   ObjectSetInteger(ChartID(),"BR_label_1",OBJPROP_COLOR,clrWhite);
   ObjectSetString(ChartID(),"BR_label_1",OBJPROP_TEXT,"Буфер: 0");

   
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
// Custom indicator DeInit function                                  |
//+------------------------------------------------------------------+
void OnDeinit( const int reason )
{
  ObjectDelete(ChartID(),"BR_label_1");
  if(pr_book == true) MarketBookRelease(Symbol());
  if(sec_book == true) MarketBookRelease(sec_symbol);
  if(reason == REASON_INITFAILED)
  {
    Print("Индикатор удалён! Причина - ошибка инициализации.");
    string short_name = ChartIndicatorName(ChartID(), 1, 0);
    ChartIndicatorDelete(ChartID(), 1, short_name); 
  }
}
//+------------------------------------------------------------------+
// Custom indicator On book event function                           |
//+------------------------------------------------------------------+
void OnBookEvent( const string& symbol )
{
  if((symbol == Symbol()) || (symbol == sec_symbol))
  {
    sec_last = SymbolInfoDouble(sec_symbol, SYMBOL_LAST);
    pr_last = SymbolInfoDouble(Symbol(), SYMBOL_LAST);
//---
    double price[]; 
    OnCalculate( event_cnt, event_cnt, on_call, price ); 
  }
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
  if(prev_calculated == 0)
  {
    ArrayInitialize(Buff, EMPTY_VALUE);
  }
  else
  {
    if(begin == on_call)
    {
      for(int i = aBars - 1; i > 0; i--)
      {
        Buff[i] = Buff[i - 1];
      }
    }
    else
    {
      sec_last = SymbolInfoDouble(sec_symbol, SYMBOL_LAST);
      pr_last = SymbolInfoDouble(Symbol(), SYMBOL_LAST);
    }
    Buff[aBars] = EMPTY_VALUE;
    Buff[0] = (sec_last - pr_last) /Point(); 
  } 
  ObjectSetString(ChartID(),"BR_label_1",OBJPROP_TEXT,"Буфер: " + DoubleToString(Buff[0])); 
  ChartRedraw();
//---    
  event_cnt = rates_total;  
//--- return value of prev_calculated for next call
  return(rates_total);
}
//+------------------------------------------------------------------+
 
Судя по скрину пропадает визуализация, а в буфере есть информация?
 
Большое подозрение, что if(begin == on_call) всегда true
 
Aleksey Vyazmikin:
Судя по скрину пропадает визуализация, а в буфере есть информация?

Как раз это и паказывает состояние буфера

ObjectSetString(ChartID(),"BR_label_1",OBJPROP_TEXT,"Буфер: " + DoubleToString(Buff[0])); 
 
Попробуйте убрать ChartRedraw.
 

Добавил

#property indicator_maximum 30
#property indicator_minimum -30

И все заработало. Т.е без ограничений, индикатор не автомаштабировался.

Но мне не нужны ограничения.

Как быть?

 
Stanislav Korotky:
Попробуйте убрать ChartRedraw.

То же самое

 

А при каких условиях пропадает?

Что в выводится в окне данных в этот момент?

Учтите, что при подгрузке данных могут быть вызовы OnCalculate() с prev_calculated = 0. Как я понял, при этом буфер будет сброшен.

После этого в буфере может быть только одна точка с данными, а остальные EMPTY_VALUE, если правильно помню, такое будет нарисовано примерно как у вас показано.
 
Ilya Baranov:

А при каких условиях пропадает?

Что в выводится в окне данных в этот момент?

Учтите, что при подгрузке данных могут быть вызовы OnCalculate() с prev_calculated = 0. Как я понял, при этом буфер будет сброшен.

Индикатор работает нормально, если установить

#property indicator_maximum 30
#property indicator_minimum -30

Т.е без min и max индикатор не автомасштабируется.

Для того, чтобы посмотреть что в буфере сделано это

ObjectSetString(ChartID(),"BR_label_1",OBJPROP_TEXT,"Буфер: " + DoubleToString(Buff[0])); 

В буфере нормальные данные.

 
prostotrader:

В буфере нормальные данные.

Подробнее, пожалуйста. Они случайно не все одинаковые, или все кроме одного пустые?

 
Ilya Baranov:

Подробнее, пожалуйста. Они случайно не все одинаковые, или все кроме одного пустые?

Нормальные данные не пустые, а меняются.

Но вседа небольшие отрицательные целые числа

Не туда копаем.

Повторяю, когда ставим

#property indicator_maximum 30
#property indicator_minimum -30

Все работает НОРМАЛЬНО