Помогите решить проблему при синхронизации кода с открытием бара - линия перестает рисоваться

 

Вот сам код, это пример для наглядности, но принцип работы тот же.

Мне важно синхронизировать с открытием бара, поскольку работаю с тиками и при появлении нового бара некоторые показатели обнуляються. 

#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Label1
#property indicator_label1  "bulls_middleline"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Label2
#property indicator_label2  "bears_middleline"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- indicator buffers
double bulls_middleline[],bears_middleline[];
int realbar,futurebar;
double up,up_buffer,down,down_buffer;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,bulls_middleline);
   SetIndexBuffer(1,bears_middleline);
//---
   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 = limit-1; i >= 0; i--)            // цикл 
  {
//+------------------------------------------------------------------+
//| Накопитель показателей                                           |
//+------------------------------------------------------------------+
  up = (open[i] + high[i]) / 2;
  down = (open[i] + low[i]) / 2;
//+------------------------------------------------------------------+
//| Объявление нового бара                                           |
//+------------------------------------------------------------------+  
  realbar = Bars;
  if(realbar >= futurebar)
  {
      bulls_middleline[i] = (up_buffer + up) / 2;
      up_buffer = bulls_middleline[i];
      bears_middleline[i] = (down_buffer + down) / 2;
      down_buffer = bears_middleline[i];
      
      futurebar = Bars + 1;
  }
  }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
Переменные up_buffer и down_buffer, а также futurebar у Вас на момент первого использования не инициализированы. Скорей всего равны нулю. Это так и задумывалось?
 
Dmitriy Skub:
Переменные up_buffer и down_buffer, а также futurebar у Вас на момент первого использования не инициализированы. Скорей всего равны нулю. Это так и задумывалось?
Нет дело не в этом, хотя надо добавить строку futurebar = Bars + 1; в функцию OnInit. Проблема где в строках объявления бара, но не пойму что не так...
 

Убери это

if(realbar >= futurebar)

и поставь условие

if(rates_total > prev_calculated)

Дальше пойми что i-тый бар, это только-что сформированный бар у которого OHLC равны... Соответственно надо работать с i+1 баром, с завершённым баром.

 
Alexey Viktorov:

Убери это

и поставь условие

Дальше пойми что i-тый бар, это только-что сформированный бар у которого OHLC равны... Соответственно надо работать с i+1 баром, с завершённым баром.

Так доведи тему до конца, потому что если просто поставить это условие код перестанет работать. И к слову мое условие и расчитано на работу с данными уже сформированного бара(то есть предыдущего) при открытие нового бара. Просто получается конфликт цикла с моим условием как я понимаю.
 
Ну неужели ни кто не знает решения, все же просто в цикле получили показатели, при объявлении бара подсчиталось и вывелось значение... Что тут может не работать? Эта идиотская привязка к барам вечно геморой вызывает, такие логичные вещи и не работают!!!
 

сделайте так

realbar = Bars;
  if(realbar > futurebar)
  {
      bulls_middleline[i] = (up_buffer + up) / 2;
      up_buffer = bulls_middleline[i];
      bears_middleline[i] = (down_buffer + down) / 2;
      down_buffer = bears_middleline[i];
      
      futurebar = Bars;
  }
 
Alexander Bereznyak:

сделайте так

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

Вот сам код, это пример для наглядности, но принцип работы тот же.

Мне важно синхронизировать с открытием бара, поскольку работаю с тиками и при появлении нового бара некоторые показатели обнуляються. 

А вот и неугадал :-)

return(rates_total);

говорит о том что работа идёт по открытию баров. И что там синхронизовать ?

да, и переменные надо инициализовать..хотя-бы в OnInit

 
Maxim Kuznetsov:

А вот и неугадал :-)

говорит о том что работа идёт по открытию баров. И что там синхронизовать ?

да, и переменные надо инициализовать..хотя-бы в OnInit

Что не угадал то?

Переменные я инициализирую по необходимости(когда требуется). Еще раз повторю, индикатор работает по принципу накопления \ передачи данных \ и обнуления вот для чего синхронизация, чтобы с нового бара обнулялись показатели и шли данные нового бара... Я понимаю что тут все жутко умные, но это ни как не помогает в решении задачи! Я дилетант и не скрываю этого, но основы понимаю, поэтому хотелось бы по существу.

 
novichek:

Что не угадал то?

Переменные я инициализирую по необходимости(когда требуется). Еще раз повторю, индикатор работает по принципу накопления \ передачи данных \ и обнуления вот для чего синхронизация, чтобы с нового бара обнулялись показатели и шли данные нового бара... Я понимаю что тут все жутко умные, но это ни как не помогает в решении задачи! Я дилетант и не скрываю этого, но основы понимаю, поэтому хотелось бы по существу.

приведя код, неплохо было-бы пояснить что вы от него хотели и что именно не получили. Простыми словами типа "хотел нарисовать два уровня, один между high и open, другой ещё как-то там, а рисуется зелёная тыква". Получить ответ на несформулированный вопрос можно только на форуме телепатов :-)

и ещё раз про то "что не угадал" : в приведённом примере OnCalculate вызывается только при открытии нового бара (то есть не на тики). У вас каждый раз бар новый.Всегда. Переменные не инициализованы и при первом обращении могут содержать мусор.

ps. не злоупотребляйте болдом и оформительством текста - не очень удобно читать

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