Почему индикаторные буфера не инициализируются? - страница 2

 
Vasiliy Pushkaryov:

Конечно можно все вручную самому делать.
Может чтобы более наглядным было. Код, который предоставлял выше перенес в четверку (во вложении). Единственное заменил PlotIndexSetDouble() на SetIndexEmptyValue().

И ячейка содержит нужный мне EMPTY_VALUE:

Как в МТ5 сделать, чтобы точно также работало, а не нули выдавал?

Дык оно точно так же и работает - в массиве art[] - неопределенное значение.

Ты ж не заполнял этот массив еще ? В нем мусор должен быть, и как я вижу - мусор и есть... Просто совпадает с EMPTY_VALUE. Не факт, что оно всегда там будет такое.

Если хочешь, чтобы в массиве было EMPTY_VALUE - должен использовать ArrayFill(), независимо от того, МТ4, МТ5 или какой-то другой язык.

 
George Merts:

Дык оно точно так же и работает - в массиве art[] - неопределенное значение.

Ты ж не заполнял этот массив еще ? В нем мусор должен быть, и как я вижу - мусор и есть... Просто совпадает с EMPTY_VALUE. Не факт, что оно всегда там будет такое.

Если хочешь, чтобы в массиве было EMPTY_VALUE - должен использовать ArrayFill(), независимо от того, МТ4, МТ5 или какой-то другой язык.

Работает не точно так же. Прикладываю коды.

Разница в них только в том, что заменил PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 1) на SetIndexEmptyValue(0, 1).

Поставил умолчательное значение 1. Я не заполнял массив ни в 4-ке, ни в 5-ке. Но вот результат их работы:

МТ5

МТ4


Сформулирую немного по другому вопрос. Есть ли в MQL5 аналог четверочной функции SetIndexEmptyValue(), которая в OnInit() задает значение по умолчанию и инициализацию новых буферных ячеек в дальнейшем?

Файлы:
 
Vasiliy Pushkaryov:

Сформулирую немного по другому вопрос. Есть ли в MQL5 аналог четверочной функции SetIndexEmptyValue(), которая в OnInit() задает значение по умолчанию и инициализацию новых буферных ячеек в дальнейшем?

Нет, такого нет, в пятерке нужно кое-что из того, что в четверке было автоматом, делать самому. 
 
Alexey Kozitsyn:
Нет, такого нет, в пятерке нужно кое-что из того, что в четверке было автоматом, делать самому. 

Понятно, спасибо.

 
Vasiliy Pushkaryov:
 

Сформулирую немного по другому вопрос. Есть ли в MQL5 аналог четверочной функции SetIndexEmptyValue(), которая в OnInit() задает значение по умолчанию и инициализацию новых буферных ячеек в дальнейшем?

Нет, конечно.

В МТ4 эта функция работает "с превышением полномочий", она лезет в индикаторные буффера, и изменяет их значение, хотя во-первых, по логике этого не должно быть, а во-вторых, насколько я знаю, и в документации об этом не говорится.

Вобще, в МТ4 "для облегчения жизни" довольно многие вещи сделаны вот так, "по умолчанию" (заполнение пустым значением, заполнение нулями), что приучает программистов не обращать внимания на важные моменты, что, в свою очередь, приводит к трудновыявляемым "плавающим" ошибкам.

На мой взгляд, любые инициализации должны вызываться явно. Более того, лично я сразу после объявления любой переменной всегда ее инициализирую, если нет значения по умолчанию - то некорректным значением. Как раз для того, чтобы не было возможности случайно использовать неинициализированную переменную.

 
George Merts:

Нет, конечно.

В МТ4 эта функция работает "с превышением полномочий", она лезет в индикаторные буффера, и изменяет их значение, хотя во-первых, по логике этого не должно быть, а во-вторых, насколько я знаю, и в документации об этом не говорится.

Вобще, в МТ4 "для облегчения жизни" довольно многие вещи сделаны вот так, "по умолчанию" (заполнение пустым значением, заполнение нулями), что приучает программистов не обращать внимания на важные моменты, что, в свою очередь, приводит к трудновыявляемым "плавающим" ошибкам.

На мой взгляд, любые инициализации должны вызываться явно. Более того, лично я сразу после объявления любой переменной всегда ее инициализирую, если нет значения по умолчанию - то некорректным значением. Как раз для того, чтобы не было возможности случайно использовать неинициализированную переменную.

Т.е. получается PlotIndexSetDouble() вызывать в OnInit() нет смысла? И ее нужно использовать уже когда есть размерность у буфера? Это как аналог ArrayInitialize()?
 
Vasiliy Pushkaryov:
Т.е. получается PlotIndexSetDouble() вызывать в OnInit() нет смысла? И ее нужно использовать уже когда есть размерность у буфера? Это как аналог ArrayInitialize()?

Нет.

Это совершенно разные функции. Первая - устанавливает дубль-свойства индикатора. А вторая - инициализирует массив. Нужны обе функции, каждая в своем месте. (Обычно, и ту и другую вызывают в OnInit())

 
George Merts:

Нет.

Это совершенно разные функции. Первая - устанавливает дубль-свойства индикатора. А вторая - инициализирует массив. Нужны обе функции, каждая в своем месте. (Обычно, и ту и другую вызывают в OnInit())

Понятно. Я просто не мог уловить предназначение PlotIndexSetDouble(): Задает значение соответствующего свойства соответствующей линии индикатора.

" Соответствующее свойство" у этой функции одно:

PLOT_EMPTY_VALUE

Пустое значение для построения, для которого нет отрисовки


Сейчас разобрался.

Т.е. если я задал через эту функцию в OnInit() значение "1". А у меня диапазон линии, например, от 5 до -5, тогда на значении "1" просто будет "исчезать" линия отрисовки.

 


а вот что не так в коде, что в профилировщике идёт прямая линия от индикатора вниз?

при обычном запуске индикатора её нет. в тестере тоже нет.

кажется что это зависит от компилирования. или просто носит случайный характер. из 10 компиляций+запусков 1 с таким феноменом.


#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1 DRAW_LINE
#property indicator_type2 DRAW_LINE
#property indicator_label1 "D"
#property indicator_label2 "U"
#property indicator_color1 Red
#property indicator_color2 Lime
#property indicator_width1 1
#property indicator_width2 1
double UpperBuffer[];
double LowerBuffer[];

input int  History_Size = 1100;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{         
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   SetIndexBuffer(0,UpperBuffer);
   SetIndexBuffer(1,LowerBuffer);    
   ArraySetAsSeries(UpperBuffer,true);
   ArraySetAsSeries(LowerBuffer,true);      
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
   
   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[])
{
   
   ArraySetAsSeries(time,true);
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);

   int limit=0; 
   if( prev_calculated <= 0 || rates_total > prev_calculated+1) 
   {    
      limit=rates_total-(rates_total-History_Size);  
 
      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,Bars(NULL,0)-limit);
      PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,Bars(NULL,0)-limit);   
      ArrayInitialize(UpperBuffer,EMPTY_VALUE);
      ArrayInitialize(LowerBuffer,EMPTY_VALUE);       
   } 
   else {limit=rates_total-prev_calculated;} 

   for(int a=limit; !IsStopped() && a>=1; a--)
   {  
      UpperBuffer[a]=high[a];
      LowerBuffer[a]=low[a];  
   } 
   return(rates_total);
}
//+------------------------------------------------------------------+