Не пойму, что не так с CopyBuffer

 

Здравствуйте.

Пожалуйста помогите разобраться. Что не так с копированием в буфер. Это заготовка индикатора. Компилирую и накидываю на график. Проверяю по шагам, как говорится. Сейчас накидываю его на часовой график, а данные вынуть хочу с четырех часового. Код компилируется. Начинаю выполнять на графике и всегда с первого раза не идет копирование. Затем со следующим тиком копирование происходит. Почему сразу не копирует?

//+------------------------------------------------------------------+
//|                                                     Inditest.mq5 |
//+------------------------------------------------------------------+
#property indicator_chart_window                                                 // индикатор в основном окне графика
#property indicator_buffers 1                                                    // для построения индикатора используется один буфер
#property indicator_plots   1                                                    // будет одно графическое построение

#property indicator_label1  "first"                                              // имя индикатора
#property indicator_type1   DRAW_LINE                                            // отрисовка индикатора линией
#property indicator_color1  clrRed                                               // цвет линии красный
#property indicator_style1  STYLE_SOLID                                          // сплошная линия
#property indicator_width1  2                                                    // толщина линии

double firstBuffer[];                                                            // динамический массив под буфер
double bill[];                                                                   // динамический массив под данные старшего аллигатора

int handle;                                                                      // хэндл индикатора аллигатор старшего таймфрейма
datetime lastbar=0;

int                  jaw_period=13;                                              // период для линии Челюстей
int                  jaw_shift=8;                                                // смещение линии Челюстей
int                  teeth_period=8;                                             // период для линии Зубов
int                  teeth_shift=5;                                              // смещение линии Челюстей
int                  lips_period=5;                                              // период для линии Губ
int                  lips_shift=3;                                               // смещение линии Губ
ENUM_MA_METHOD       MA_method=MODE_SMMA;                                        // метод усреднения линий Аллигатора
ENUM_APPLIED_PRICE   applied_price=PRICE_MEDIAN;                                 // тип цены, от которой строится Аллигатор

MqlParam pars[8];


    


int OnInit()                                                                     // функция инициализации индикатора
  {
   if(SetIndexBuffer(0,firstBuffer,INDICATOR_DATA)==false)                       // связываем динамический массив с индикаторным буфером
   {
    Alert("Ошибка инициализации индикаторного буфера. Ошибка № ",GetLastError());
    return(INIT_FAILED);  
   } 
   return(INIT_SUCCEEDED);                                                       // инициализация прошла успешно
  }

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[])
{
 if(lastbar==time[rates_total-1])
  return(rates_total);
 ArraySetAsSeries(firstBuffer,true);                                             // устанавливаем индексацию в динамическом массиве, как в таймсерии
 ArraySetAsSeries(bill,true);                                                    // устанавливаем индексацию в динамическом массиве, как в таймсерии
 for(int i=0;i<rates_total;i++)
  CopyLow(Symbol(),Period(),i,1,firstBuffer);
 //MqlParam pars[8];                                                               // используем стандартную структуру для создания старшего Аллигатора
      pars[0].type=TYPE_INT;
      pars[0].integer_value=jaw_period;
      pars[1].type=TYPE_INT;
      pars[1].integer_value=jaw_shift;
      pars[2].type=TYPE_INT;
      pars[2].integer_value=teeth_period;
      pars[3].type=TYPE_INT;
      pars[3].integer_value=teeth_shift;
      pars[4].type=TYPE_INT;
      pars[4].integer_value=lips_period;
      pars[5].type=TYPE_INT;
      pars[5].integer_value=lips_shift;
      pars[6].type=TYPE_INT;//--- тип сглаживания
      pars[6].integer_value=MA_method;
      pars[7].type=TYPE_INT;//--- тип цены
      pars[7].integer_value=applied_price;
 handle=IndicatorCreate(_Symbol,PERIOD_H4,IND_ALLIGATOR,8,pars);
 if(handle==INVALID_HANDLE)
 {
  Alert("Ошибка получения хэндла индикатора. Ошибка № ",GetLastError());
  return(0);
 }
 Alert("Создание старшего Билла прошло успешно. Хендл - ", handle);
 if(CopyBuffer(handle,0,0,2,bill)<0)
 {
  Alert("Не удалось скопировать старшего Билла. Ошибка - ",GetLastError());
  Alert("Результат Билл 1 = ",NormalizeDouble(bill[0],5),"  Билл 0 =",NormalizeDouble(bill[1],5));
  return(0);
 }
 Alert("Результат Билл 1 = ",NormalizeDouble(bill[0],5),"  Билл 0 =",NormalizeDouble(bill[1],5));
 lastbar=time[rates_total-1];
 return(rates_total);
}
//+------------------------------------------------------------------+
Файлы:
Alert.jpg  82 kb
 
RedFish:

Здравствуйте.

Пожалуйста помогите разобраться. Что не так с копированием в буфер. Это заготовка индикатора. Компилирую и накидываю на график. Проверяю по шагам, как говорится. Сейчас накидываю его на часовой график, а данные вынуть хочу с четырех часового. Код компилируется. Начинаю выполнять на графике и всегда с первого раза не идет копирование. Затем со следующим тиком копирование происходит. Почему сразу не копирует?

При запросе данные с другого таймфрейма оказываются не готовыми. Эти данные нужно подготовить.
https://www.mql5.com/ru/docs/series/timeseries_access

 
Но в случае с индикатором не все так просто. Дело в том, что в индикаторах нельзя организовать задержки (Sleep, MessageBox) - так как индикатор работает в одном потоке и остановка расчета индикатора повлечет остановку всего терминала.

Выход для индикатора, в котором Вы хотите иметь доступ к другим таймфреймам - это использовать таймер. В таймере организовать загрузку нужных данных и проверку результата.

Похожая реализация есть в https://www.mql5.com/ru/articles/802
 

barabashkakvn спасибо. Стало понятней. Мне идея открывать график больше понравилась вот здесь

 https://www.mql5.com/ru/forum/16502/page2 попробую этот вариант.

Индикатор использует историю нескольких инструментов. Как предварительно загрузить историю?
Индикатор использует историю нескольких инструментов. Как предварительно загрузить историю?
  • www.mql5.com
Индикатор использует историю нескольких инструментов.
Причина обращения: