Не читаются данные с буфера

 

Есть у меня индикатор Zig-Zag, который прекрасно работает. В нём используется enum:

enum ENUM_TREND_DIRECTION {
  TREND_NONE,
  TREND_UPWARDS,
  TREND_DOWNWARDS
};

Использовался он до сегодня лишь в рассчётах. В буфер ес-но его значения не передавались. До сегодня в индикаторе был лишь один буфер с данными - буер цен.

Вот решил я добавить ещё 1 буфер с направлением. Буфер добавлен, значения присваиваю там же, где и цены т.е. на не пустых значениях. Всё, вроде как хорошо. Но вот получить значения из этого буфера не выходит. Функция CopyBuffer() всегда возвращает ошибку при копирования значения с хэндла этого индикатора из нового буфера, где находится значение направления тренда:

2018.09.14 14:31:46.765 Fakey (EURJPY,H1)       Copying extremumTrend failed! Error = 4806

Причём ошибка возникает на любом индексе таймсерии. Я думал. Единственное, на что я обратил внимание, так это то, что обычно в буфер помещаются значения примитивных типов. А у меня в этом новом буфере, который я сегодня добавил в буфер помещаются значения вышеприведённого enum'а ENUM_TREND_DIRECTION.

Но буфер в мкл может быть только типа double. Может в этом какой-то косяк? Возможно это влияет на то, что не возможно получить значения из этого буфера? Других объяснений нет т.к. данные цен экстремумов и направления тренда записываются в индикаторе на одном индексе, соответственно, и значения с одного индекса браться должны. А они вообще не копируются из хэндла..

Думаю, как это лучше проверить.

 
Viktar Dzemikhau:

Есть у меня индикатор Zig-Zag, который прекрасно работает. В нём используется enum:

Использовался он до сегодня лишь в рассчётах. В буфер ес-но его значения не передавались. До сегодня в индикаторе был лишь один буфер с данными - буер цен.

Вот решил я добавить ещё 1 буфер с направлением. Буфер добавлен, значения присваиваю там же, где и цены т.е. на не пустых значениях. Всё, вроде как хорошо. Но вот получить значения из этого буфера не выходит. Функция CopyBuffer() всегда возвращает ошибку при копирования значения с хэндла этого индикатора из нового буфера, где находится значение направления тренда:

Причём ошибка возникает на любом индексе таймсерии. Я думал. Единственное, на что я обратил внимание, так это то, что обычно в буфер помещаются значения примитивных типов. А у меня в этом новом буфере, который я сегодня добавил в буфер помещаются значения вышеприведённого enum'а ENUM_TREND_DIRECTION.

Но буфер в мкл может быть только типа double. Может в этом какой-то косяк? Возможно это влияет на то, что не возможно получить значения из этого буфера? Других объяснений нет т.к. данные цен экстремумов и направления тренда записываются в индикаторе на одном индексе, соответственно, и значения с одного индекса браться должны. А они вообще не копируются из хэндла..

Думаю, как это лучше проверить.

А вы объявили буфер типа int?

Ну пусть будет double и при прочтении значения его переводить в тип int.

 

Числа - Люди...

195031

 
Viktar Dzemikhau:

Есть у меня индикатор Zig-Zag, который прекрасно работает. В нём используется enum:

Использовался он до сегодня лишь в рассчётах. В буфер ес-но его значения не передавались. До сегодня в индикаторе был лишь один буфер с данными - буер цен.

Вот решил я добавить ещё 1 буфер с направлением. Буфер добавлен, значения присваиваю там же, где и цены т.е. на не пустых значениях. Всё, вроде как хорошо. Но вот получить значения из этого буфера не выходит. Функция CopyBuffer() всегда возвращает ошибку при копирования значения с хэндла этого индикатора из нового буфера, где находится значение направления тренда:

Причём ошибка возникает на любом индексе таймсерии. Я думал. Единственное, на что я обратил внимание, так это то, что обычно в буфер помещаются значения примитивных типов. А у меня в этом новом буфере, который я сегодня добавил в буфер помещаются значения вышеприведённого enum'а ENUM_TREND_DIRECTION.

Но буфер в мкл может быть только типа double. Может в этом какой-то косяк? Возможно это влияет на то, что не возможно получить значения из этого буфера? Других объяснений нет т.к. данные цен экстремумов и направления тренда записываются в индикаторе на одном индексе, соответственно, и значения с одного индекса браться должны. А они вообще не копируются из хэндла..

Думаю, как это лучше проверить.

Как буфер добавляли? Покажите код от шапки до конца OnInit()

 
Artyom Trishkin:

Как буфер добавляли? Покажите код от шапки до конца OnInit()

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//|                                                                                                                                       ZigZag_HightLow_MTF.mq5 |
//|                                                                                                                                                           hoz |
//|                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
#property copyright "hoz"
#property link      ""
#property version   "1.00"
#property indicator_chart_window       // Индикатор выводится в окне графика
#property indicator_buffers 2          // Используется 1 буфер индикатора
#property indicator_plots   1          // Количество графических серий индикатора
//---- plot properties
#property indicator_type1  DRAW_SECTION     // Вид графического построения
#property indicator_color1 clrRed           // Цвет отображения данных 1-го буфера
#property indicator_style1 STYLE_SOLID      // Стиль графической серии
#property indicator_width1 1                // Толщина линий 1-го буфера

// ============================================================== Включения и импорт внешних модулей =============================================================+
#import "EnvironmentInfo\TimeSeries.ex5"
  int      barsTotal(ENUM_TIMEFRAMES tf = PERIOD_CURRENT);
  int      barShift(datetime initialBarTime, ENUM_TIMEFRAMES tf = PERIOD_CURRENT);
  double   barHighPrice(int shift, ENUM_TIMEFRAMES tf = PERIOD_CURRENT);
  double   barLowPrice(int shift, ENUM_TIMEFRAMES tf = PERIOD_CURRENT);
  datetime barOpenTime(int shift, ENUM_TIMEFRAMES tf = PERIOD_CURRENT);
#import

#include   <HOZ_Code\Enums\Direction.mqh>
#include   "Structures\ZZ_Properties.mqh"

input ENUM_TIMEFRAMES i_tf = PERIOD_H1;    // Расчётный ТФ

double ZZ_price_buffer[],        // Буфер, хранящий цены экстремумов
       ZZ_direction_buffer[];    // Буфер, хранящий направление тренда
int    g_prevCalculated;
ZZ_Properties ZZ;
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
//|                                                            Custom indicator initialization function                                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit() {
//---
  if (i_tf != PERIOD_CURRENT && Period() > i_tf) {
    Alert("Расчетный ТФ не может быть младше текущего ТФ. Индиктаор отключен.");
    return INIT_PARAMETERS_INCORRECT;
  }
  g_prevCalculated = 0;
  SetIndexBuffer(0, ZZ_price_buffer, INDICATOR_DATA);               // Первый буфер - экстремумы
  PlotIndexSetDouble(DRAW_NONE, PLOT_EMPTY_VALUE, EMPTY_VALUE);     // Установка пустого значения буфера ZZ_price_buffer, по которому нет отрисовки
  ArraySetAsSeries(ZZ_price_buffer, true);
  SetIndexBuffer(1, ZZ_direction_buffer, INDICATOR_CALCULATIONS);   // Второй буфер - направление тренда
  ArraySetAsSeries(ZZ_direction_buffer, true);
//---
  return INIT_SUCCEEDED;
}

Косяк в жёлтой строке вчера был. Я часа полтора продолбался и понял, что в документации или даже не в документации, а в реализации архитектуры вообще буферов косяк. Не логично как-то. Если буфер не рисует и у него SetIndexBuffer связывает с INDICATOR_DATA, то данные с буфера получить не возможно никак. Изменил на INDICATOR_CALCULATIONS и всё заработало, хотя, написано же, что мол INDICATOR_CALCULATIONS - для рпссчётов. Ну, есс-но, я подумал, что этот вариант нужен лишь для промежуточные рассчётов, а для хранения данных INDICATOR_DATA. Оказалось не так..

 
Alexey Viktorov:

А вы объявили буфер типа int?

Ну пусть будет double и при прочтении значения его переводить в тип int.

Всмысле буфер типа int? Как потом из него читать данные? Ведь функция CopyBuffer, возвращает данные только в double-переменную. Как ни крути значение принимается не как целое..

 
Viktar Dzemikhau:

Косяк в жёлтой строке вчера был. Я часа полтора продолбался и понял, что в документации или даже не в документации, а в реализации архитектуры вообще буферов косяк. Не логично как-то. Если буфер не рисует и у него SetIndexBuffer связывает с INDICATOR_DATA, то данные с буфера получить не возможно никак. Изменил на INDICATOR_CALCULATIONS и всё заработало, хотя, написано же, что мол INDICATOR_CALCULATIONS - для рпссчётов. Ну, есс-но, я подумал, что этот вариант нужен лишь для промежуточные рассчётов, а для хранения данных INDICATOR_DATA. Оказалось не так..

А вот это?

#property indicator_buffers 2          // Используется 1 буфер индикатора
#property indicator_plots   1          // Количество графических серий индикатора

Графических серий (рисуемых буферов) один. Поставьте 2 и верните INDICATOR_DATA на место. Правда нужно будет ещё задать тип отображения для нового буфера. Что-то типа:

#property indicator_type2  DRAW_ARROW       // Вид графического построения
#property indicator_color2 clrRed           // Цвет отображения данных 2-го буфера
#property indicator_style2 STYLE_SOLID      // Стиль графической серии
#property indicator_width2 1                // Толщина линий 2-го буфера

Задать код стрелок для второго буфера (можно 32 - не будет ничего рисовать, но в окне данных значения будут).

А вот это что вообще?

PlotIndexSetDouble(DRAW_NONE, PLOT_EMPTY_VALUE, EMPTY_VALUE);     // Установка пустого значения буфера ZZ_price_buffer, по которому нет отрисовки

Здесь вы нулевому буферу (DRAW_NONE = 0) задаёте пустое значение. А нулевой буфер у вас рисуемый. А написали, что ставите тому, по которому нет отрисовки - для второго (с индексом 1)

 
Artyom Trishkin:

А вот это?

#property indicator_buffers 2          // Используется 1 буфер индикатора
#property indicator_plots   1          // Количество графических серий индикатора

Что здесь не так? Открываем справку и смотрим:

indicator_buffers

int

Количество буферов для расчета индикатора

Соответственно, здесь всё в порядке. Для рассчёта индикатора используется 2 буфера. Не написано же про отображение (отрисовку) касательно буфера.


Artyom Trishkin:

Графических серий (рисуемых буферов) один. Поставьте 2 и верните INDICATOR_DATA на место. Правда нужно будет ещё задать тип отображения для нового буфера. Что-то типа:

#property indicator_type2  DRAW_ARROW       // Вид графического построения
#property indicator_color2 clrRed           // Цвет отображения данных 2-го буфера
#property indicator_style2 STYLE_SOLID      // Стиль графической серии
#property indicator_width2 1                // Толщина линий 2-го буфера

Какой смсыл задавать 2 графические таймсерии, если, на самом деле имеется лишь 1 серия? Не проще ли тогда сделать как я сделал буфер рассчётный? Да, как-бы тоже чушь какая-то получается, но без лишних строк задания свойств для буфера, который не отображается.


Artyom Trishkin:

А вот это что вообще?

PlotIndexSetDouble(DRAW_NONE, PLOT_EMPTY_VALUE, EMPTY_VALUE);     // Установка пустого значения буфера ZZ_price_buffer, по которому нет отрисовки

Здесь вы нулевому буферу (DRAW_NONE = 0) задаёте пустое значение. А нулевой буфер у вас рисуемый. А написали, что ставите тому, по которому нет отрисовки - для второго (с индексом 1)

А это я накосячил. Перетрудился видимо. Поправил..

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