program file Experts\..\..ПУТЬ К ЭКСПЕРТУ..\CandlePatterns.ex5 read error - страница 2

 
Виктор Демихов:

Откуда такие сведения? У меня написан класс один, который протестирован уже ни один раз. Так с 1 слэшем. Вот так там написано:


То что я создал 2 раза тот же хэндл, это лишь случайность. Тестировал, проверял. Переписал всё в одной функции без проверок под идеальные условия для тестера. В реале, конечно, допишу проверки. Вот что вышло:

Параметры функции getCandlePatternsValue() видны на прикреплённом скрине.

Я бы мог показать целый код, но это усложнит анализ кода. Я вижу, что ошибка в этом момент. Поэтому я его и показываю.

Там более, видно, что функция CopyBuffer() возвращает res == -1. А это значит, что не получается считать данные с буфера индикатора CandlePatterns.

Виктор, ну вы же продолжаете создавать индикатор непосредственно перед обращением к нему. 

Надо заранее в ОнИнит все что нужно создать, а потом обращаться. Скорее всего не успевает.
Как самому создать советника или индикатор - Алгоритмический трейдинг, торговые роботы - Справка по MetaTrader 5
Как самому создать советника или индикатор - Алгоритмический трейдинг, торговые роботы - Справка по MetaTrader 5
  • www.metatrader5.com
Для разработки торговых систем в платформу встроен собственный язык программирования MetaQuotes Language 5 (MQL5), среда разработки MetaEditor и инструменты тестирования стратегий. Любую информацию о разработке торговых стратегий на языке MQL5 можно найти на официальном сайте MQL5.community. На этом же сайте в разделе Code Base могут быть...
 
Ihor Herasko:

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

Нет. В индикаторе же лишь 2 буфера сейчас. Индексы буферные 0 и 1. Конечно, они в индикаторе присутствуют. Это можно увидеть невооружённым глазом в прикрепленном файле (индикаторе)


Ihor Herasko:

P. S. А почему тема в разделе для MQL4? Думаю, стоит перенести в раздел для MQL5.

Я тоже об этом сегодня подумал. Но не хотел дёргать модераторов ради этого.

Файлы:
 
Aleksey Mavrin:

Виктор, ну вы же продолжаете создавать индикатор непосредственно перед обращением к нему. 

Надо заранее в ОнИнит все что нужно создать, а потом обращаться. Скорее всего не успевает.

@Aleksey Mavrin вы правы в этом. Учту. Но, в целом, на сложившуюся ситуацию перенос инициализацию в OnInit() ничего не дало. Я написал тестовый бот, чтобы протестироватькак читаются данные с моего индюка. Вот он:

#property copyright "hoz"
#property link      ""
#property version   "1.00"

int       candlePatternsHandle;
int       copied;
double    havingPattern[1];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
//---
  candlePatternsHandle = iCustom(_Symbol, _Period, "CandlePatterns");
  if (candlePatternsHandle == INVALID_HANDLE) {
    Sleep(5000);
    return INIT_FAILED;
  }
//---
   return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//---
   
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
//---
//  int res = CopyBuffer(candlePatternsHandle, 0, 1, 1, havingPattern);
//  Print(__FUNCTION__ + ":: _LastError = ", _LastError);
//  Print(__FUNCTION__ + ":: res = " + res);
//  Print(__FUNCTION__ + ":: havingPattern[0] = " + havingPattern[0]);

  for (int i = 0; i < 119; i++) {
    copied = CopyBuffer(candlePatternsHandle, 1, i, 1, havingPattern);
    Print(__FUNCTION__ + ":: copied = " + copied);
    if (havingPattern[0] != EMPTY_VALUE) {
      Print(__FUNCTION__ + ":: havingPattern[0] != EMPTY_VALUE");
      Print(__FUNCTION__ + ":: havingPattern[", + i + "] = " + DoubleToString(havingPattern[0]));
    }
  }

Так вот. Ничего не копиуется с буфера индикатора. Ни с 0-го, ни с 1-го индекса. Вот для первого я выше код и привёл. В журнале вижу следующее:

2020.06.11 21:05:23.191 2018.09.27 00:00:00   OnTick:: copied = -1
2020.06.11 21:05:26.664 2018.09.27 00:00:00   OnTick:: havingPattern[0] != EMPTY_VALUE
2020.06.11 21:05:27.745 2018.09.27 00:00:00   OnTick:: havingPattern[0] = 0.00000000
2020.06.11 21:05:30.898 2018.09.27 00:00:00   OnTick:: copied = -1
2020.06.11 21:05:36.988 2018.09.27 00:00:00   OnTick:: havingPattern[0] != EMPTY_VALUE
2020.06.11 21:05:38.101 2018.09.27 00:00:00   OnTick:: havingPattern[1] = 0.00000000
2020.06.11 21:05:43.085 2018.09.27 00:00:00   OnTick:: copied = -1
2020.06.11 21:05:45.060 2018.09.27 00:00:00   OnTick:: havingPattern[0] != EMPTY_VALUE
2020.06.11 21:07:32.705 2018.09.27 00:00:00   OnTick:: havingPattern[2] = 0.00000000
2020.06.11 21:07:33.290 2018.09.27 00:00:00   OnTick:: copied = -1
2020.06.11 21:07:33.290 2018.09.27 00:00:00   OnTick:: havingPattern[0] != EMPTY_VALUE
2020.06.11 21:07:33.290 2018.09.27 00:00:00   OnTick:: havingPattern[3] = 0.00000000
2020.06.11 21:07:34.885 2018.09.27 00:00:00   OnTick:: copied = -1
2020.06.11 21:07:34.885 2018.09.27 00:00:00   OnTick:: havingPattern[0] != EMPTY_VALUE
2020.06.11 21:07:34.885 2018.09.27 00:00:00   OnTick:: havingPattern[4] = 0.00000000

Неужели что-то с индикатором? Что может на это влиять? Индикатор же элементарный..

Aleksey Mavrin
Aleksey Mavrin
  • www.mql5.com
Добавил опрос Вернуть старую подсветку текущих скобок? Добавил тему Bid не совпадает с Close[0] Подскажите почему цены на графике и на тиковом графике могут перманентно отличаться? и Бид и Аск не совпадает, Бид не совпадает с Close[0].  У большинства брокеров и счетов совпадает, но почему возможно такое не совпадение в принципе? Разве на...
 
Виктор Демихов:

@Aleksey Mavrin вы правы в этом. Учту. Но, в целом, на сложившуюся ситуацию перенос инициализацию в OnInit() ничего не дало. Я написал тестовый бот, чтобы протестироватькак читаются данные с моего индюка. Вот он:

Так вот. Ничего не копиуется с буфера индикатора. Ни с -го, ни с 1-го индекса. Вот для первого я выше код и привёл. В журнале вижу следующее:

Неужели что-то с индикатором? Что может на это влиять? Индикатор же элементарный..

Уже интересно) вы бы сделали задержку, чтобы расчеты все точно он провёл, и ошибку на каждой итерации выводили. Позже протестю.

Ещё смущает что в массиве точный 0.0, хотя он же им не инициализирован, а это не 4-ка, там вроде как обычно мусор.

 
Виктор Демихов:

@Aleksey Mavrin вы правы в этом. Учту. Но, в целом, на сложившуюся ситуацию перенос инициализацию в OnInit() ничего не дало. Я написал тестовый бот, чтобы протестироватькак читаются данные с моего индюка. Вот он:

Так вот. Ничего не копиуется с буфера индикатора. Ни с -го, ни с 1-го индекса. Вот для первого я выше код и привёл. В журнале вижу следующее:

Неужели что-то с индикатором? Что может на это влиять? Индикатор же элементарный..

А как вы хотите поменять в этом цикле

  for (int i = 0; i < 119; i++) {
    copied = CopyBuffer(candlePatternsHandle, 1, i, 1, havingPattern);
    Print(__FUNCTION__ + ":: copied = " + copied);
    if (havingPattern[0] != EMPTY_VALUE) {
      Print(__FUNCTION__ + ":: havingPattern[0] != EMPTY_VALUE");
      Print(__FUNCTION__ + ":: havingPattern[", + i + "] = " + DoubleToString(havingPattern[0]));
    }

значение массива в нулевом индексе???

ps; извините, не поменять, а прочесть иное значение, чем оно есть там.

 
Alexey Viktorov:

А как вы хотите поменять в этом цикле

значение массива в нулевом индексе???

Так а разница какая? Я для теста создал массив размерностью 1 элемент, чтобы на каждой итерации писать в этот первый элемент массива т.е. на 0-ой индекс то, что считаю.

 Но суть в том, что ничего не считывается. Вот это самый интересный момент..

Документация по MQL5: Основы языка / Переменные
Документация по MQL5: Основы языка / Переменные
  • www.mql5.com
Переменные должны быть объявлены перед их использованием. Для идентификации переменных используются уникальные имена. Описания переменных используются для их определения и объявления типов. Описание не является оператором. Индексом массива может быть только целое число. Допускаются не более чем четырехмерные массивы. Нумерация элементов массива...
 
Aleksey Mavrin:

Уже интересно) вы бы сделали задержку, чтобы расчеты все точно он провёл, и ошибку на каждой итерации выводили. Позже протестю.

Ещё смущает что в массиве точный 0.0, хотя он же им не инициализирован, а это не 4-ка, там вроде как обычно мусор.

В общем-то, я придумал чутка другую проверку. Чтобы было проще проверить только что я накидал скрипт следующего содержания:

//+------------------------------------------------------------------+
//|                                                      forOnce.mq5 |
//|                                                              hoz |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "hoz"
#property link      ""
#property version   "1.00"

int       candlePatternsHandle = -1;
int       copied;
double    havingPattern[1];

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart() {
  candlePatternsHandle = iCustom(_Symbol, _Period, "CandlePatterns");
  Print(__FUNCTION__ + ":: _candlePatternsHandle = " + candlePatternsHandle);
  while (candlePatternsHandle < 0) {
    Print(__FUNCTION__ + ":: candlePatternsHandle = " + candlePatternsHandle);
    Sleep(5000);
  }
  
  for (int i = 0; i < 5; i++) {
  copied = CopyBuffer(candlePatternsHandle, 1, i, 1, havingPattern);
  Print(__FUNCTION__ + ":: copied = " + copied);
//    Print(__FUNCTION__ + ":: havingPattern[" + i + "] = " + havingPattern[0] + " ; i = " + i);
    if (havingPattern[0] != EMPTY_VALUE) {
//      Print(__FUNCTION__ + ":: havingPattern[0] != EMPTY_VALUE");
//      Print(__FUNCTION__ + ":: havingPattern[", + i + "] = " + DoubleToString(havingPattern[0]));
    }
  }

}

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

2020.06.12 20:53:58.161 forOnce (GBPUSD,W1)     OnStart:: _candlePatternsHandle = 10
2020.06.12 20:53:58.261 forOnce (GBPUSD,W1)     OnStart:: copied = -1
2020.06.12 20:53:58.261 forOnce (GBPUSD,W1)     OnStart:: copied = -1
2020.06.12 20:53:58.261 forOnce (GBPUSD,W1)     OnStart:: copied = -1
2020.06.12 20:53:58.261 forOnce (GBPUSD,W1)     OnStart:: copied = -1
2020.06.12 20:53:58.261 forOnce (GBPUSD,W1)     OnStart:: copied = -1

Если замению 1, на 0 т.е. хочу получить значение 0-го буфера то всё получается:

2020.06.12 20:56:48.967 forOnce (GBPUSD,W1)     OnStart:: _candlePatternsHandle = 10
2020.06.12 20:56:49.068 forOnce (GBPUSD,W1)     OnStart:: copied = 1
2020.06.12 20:56:49.068 forOnce (GBPUSD,W1)     OnStart:: copied = 1
2020.06.12 20:56:49.068 forOnce (GBPUSD,W1)     OnStart:: copied = 1
2020.06.12 20:56:49.068 forOnce (GBPUSD,W1)     OnStart:: copied = 1
2020.06.12 20:56:49.068 forOnce (GBPUSD,W1)     OnStart:: copied = 1

Кстати, когда я получаю данные с 0-го буфера, то всё чётко. Находится нужный бар, с паттерном, который отображает индикатор. Принтуется цена открытия этого бара (если расскоментирую в скрипте строку для этого). По сути, все мысли сошлись на том, что что-то не то лишь с функцией CopyBuffer(), либо с индикатором. С функцией CopyBuffer(), навряд ли, что-то не то т.к. ей пользуются все и не первый год. Значит что-то с индюком.

 Но интересно то, что оба буфера, по сути, написаны чуть-ли не копипастом один от другого с изменением одного лишь условия. Вот что интересно. Как проверить этот момент очень инетресно..

Скрипт и индикатор, у которого отключил отрисовку и закинул все включения в него прикрепляю. Если удобнее, могу приложить в библиотеками. Они компактные. Но код читается тогда удобнее т.к. нет лишнего в контексте логики.

По сути, я выложил индикатор и скрипт, которым можно считать данные из бферов этого индикатора. Но данные читаютя только из 1 буфера (0-го индекса). Другой буфер не считыватся. Вот это, на самом деле, интересно. Создаётся впечатление, что терминал гонит. У меня он портабельно запускается. Код уже лопатил ни один раз.

Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
  • www.mql5.com
Отсчет элементов копируемых данных (индикаторный буфер с индексом buffer_num) от стартовой позиции ведется от настоящего к прошлому, то есть стартовая позиция, равная 0, означает текущий бар (значение индикатора для текущего бара). При копировании заранее неизвестного количества данных в качестве массива-приемника buffer[] желательно...
Файлы:
Причина обращения: