При использовании деления гистограмма перестает рисоватся

 
//+------------------------------------------------------------------+
//|                                   Накопитель остаточной силы.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- plot Label2
#property indicator_label2  "Label2"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
//--- indicator buffers

// Общие переменные
double Buf_0[],Buf_1[];
int realbar,futurebar;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buf_0);
   SetIndexBuffer(1,Buf_1);
   realbar = Bars;
   futurebar = Bars + 1;
//---
   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 i, 
        limit = prev_calculated == 0    // Переменной limit, при условии что prev_calculated равно нулю
        ? rates_total-1                 // будет присвоено значение rates_total(количество баров в окне) минус 1
        : prev_calculated;              // иначе будет присвоено prev_calculated(количество не посчитанных баров
  
  for(i = 0; i < limit; i++)            // цикл 
  {
//+------------------------------------------------------------------+
//| Накопление показателей                                           |
//+------------------------------------------------------------------+
  bulls_high = (high[i] + open[i]) / 2;
  bulls_low = (low[i] + open[i]) / 2;
//+------------------------------------------------------------------+
//| Объявление нового бара                                           |
//+------------------------------------------------------------------+  
  realbar = Bars;  
  if(realbar >= futurebar)
  { 
      /////////////////////////////////////////////////////////
      Buf_1[i] = (100 / (bulls_high + bulls_low)) * bulls_high;
      Buf_0[i] = (100 / (bulls_low + bulls_high)) * bulls_low;
      /////////////////////////////////////////////////////////
      
      futurebar = Bars + 1;
  }  
  } 
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Это пример кода.

Как подставить подсчитанные значения буферу, чтобы индикатор работал. Почему то при делении в уравнении буфер перестает работать?

 
novichek:

Это пример кода.

Как подставить подсчитанные значения буферу, чтобы индикатор работал. Почему то при делении в уравнении буфер перестает работать?

Наверное, не "буфер перестает работать", а "индикатор перестает работать, т. к. возникает фатальная ошибка"? Видимо, именно так. А дело в том, что при некоторых условиях сумма bull_high + bulls_low дает нулевое значение. В свою оечередь, деление на ноль и приводит к фатальной ошибке (см. закладку "Эксперты" в окне Терминал).

Чтобы предотвратить такую ошибку, перед выполнением операции деления всегда проверяйте знаменатель на равенство нулю. Если условие истинно, то операцию выполнять нельзя.

 
Ihor Herasko:

Наверное, не "буфер перестает работать", а "индикатор перестает работать, т. к. возникает фатальная ошибка"? Видимо, именно так. А дело в том, что при некоторых условиях сумма bull_high + bulls_low дает нулевое значение. В свою оечередь, деление на ноль и приводит к фатальной ошибке (см. закладку "Эксперты" в окне Терминал).

Чтобы предотвратить такую ошибку, перед выполнением операции деления всегда проверяйте знаменатель на равенство нулю. Если условие истинно, то операцию выполнять нельзя.

Добавил условие на проверку нулевых значений, индикатор заработал но отображение не происходит. Может проблема именно в буферизации, я точно не знаю как это работает, но если подставить простые переменные то подсчет происходит, а с переменными буфера все встает в стопор!
 
novichek:
Добавил условие на проверку нулевых значений, индикатор заработал но отображение не происходит. Может проблема именно в буферизации, я точно не знаю как это работает, но если подставить простые переменные то подсчет происходит, а с переменными буфера все встает в стопор!

А для чего вот это условие?

  realbar = Bars;  
  if(realbar >= futurebar)
  { 
     // Не важно что тут происходит.
      futurebar = Bars + 1;
  }  

И не мешало-бы посчитать на калькуляторе, ну или посмотреть в дебагере, какие значения принимают realbar и futurbar

Что-то подозреваю код внутрь условия не входит больше 1го раза...

 
Alexey Viktorov:

А для чего вот это условие?

И не мешало-бы посчитать на калькуляторе, ну или посмотреть в дебагере, какие значения принимают realbar и futurbar

Что-то подозреваю код внутрь условия не входит больше 1го раза...

это синхронизация расчетов с открытием бара

 

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

вот так отображает буферы, только у вас расчет наверно какой-то, что все значения почти одинаковые (но различия небольшие есть)

 

//+------------------------------------------------------------------+
//|                                   Накопитель остаточной силы.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- plot Label2
#property indicator_label2  "Label2"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
//--- indicator buffers

// Общие переменные
double Buf_0[],Buf_1[];
double bulls_high, bulls_low;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buf_0);
   SetIndexBuffer(1,Buf_1);
//---
   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 i,pos;
//---
   if(rates_total<=1)
      return(0);
    
//--- starting calculation
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=0;
    
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      bulls_high = (high[i] + open[i]) / 2;
      bulls_low = (low[i] + open[i]) / 2;
      Buf_1[i] = (100 / (bulls_high + bulls_low)) * bulls_high;
      Buf_0[i] = (100 / (bulls_low + bulls_high)) * bulls_low;
      //---
     }
      
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 

Вот так можно проверить что все правильно считает, отображаем в буферах сколько осталось не посчитанных баров

 

//+------------------------------------------------------------------+
//|                                   Накопитель остаточной силы.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- plot Label2
#property indicator_label2  "Label2"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
//--- indicator buffers

// Общие переменные
double Buf_0[],Buf_1[];
double bulls_high, bulls_low;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buf_0);
   SetIndexBuffer(1,Buf_1);
//---
   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 i,pos;
//---
   if(rates_total<=1)
      return(0);
     
//--- starting calculation
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=0;
    
   for(i=pos; i<rates_total && !IsStopped(); i++)
     {
      Buf_1[i] = i; - тут пишем номер бара
      Buf_0[i] = i+1; - номер бара +1 для второго буфера, что бы было видно зеленую гистограмму
      //---
     }
      
//--- return value of prev_calculated for next call
   return(rates_total);
  }
Причина обращения: