Погружаемся в особенности индикаторов MetaTrader 5 - страница 2

 

Непонятна логика срабатывания prev_calculated

 

Просто набрасываешь индикатор на график. Он работает нормально.

2010.05.14 00:47:03   11 (EURUSD,M5)      запуск № 1 Bars= 50000  time[0] = 2009.09.03 11:25:00  TimeCurrent= 2010.05.13 22:47:05  rates_total= 50670  prev_calculated= 50670

2010.05.14 00:47:02   11 (EURUSD,M5)      запуск № 0 Bars= 50000  time[0] = 2009.09.03 11:25:00  TimeCurrent= 2010.05.13 22:47:03  rates_total= 50670  prev_calculated= 0

 

Результат если закрыл терминал и открыл его снова

 

2010.05.14 00:48:09   11 (EURUSD,M5)      запуск № 2 Bars= 50000  time[0] = 2009.09.03 11:25:00  TimeCurrent= 2010.05.13 22:48:10  rates_total= 50670  prev_calculated= 50670

2010.05.14 00:48:06   11 (EURUSD,M5)      запуск № 1 Bars= 50000  time[0] = 2009.09.03 11:25:00  TimeCurrent= 2010.05.13 22:47:53  rates_total= 50670  prev_calculated= 0

2010.05.14 00:48:05   11 (EURUSD,M5)      запуск № 0 Bars= 50000  time[0] = 2009.09.03 11:25:00  TimeCurrent= 2010.05.13 22:47:53  rates_total= 50670  prev_calculated= 0

 

Индикатор запустился дважды. Причем оба раза вернул prev_calculated= 0

 

Поясните почему так происходит ?

Что нужно вставить в код что бы он работал одинаково ?

 

вот код индикатора 

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plot Line
#property indicator_label1  "Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  DarkBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- indicator buffers
double         LineBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,LineBuffer,INDICATOR_DATA);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 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;
   Print("запуск №",i++,"Bars=",Bars(_Symbol,_Period)," time[0] =",time[0]," TimeCurrent=",TimeCurrent()," rates_total=",rates_total," prev_calculated=", prev_calculated);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 
Prival:

Непонятна логика срабатывания prev_calculated

...

Поясните почему так происходит ?

Что нужно вставить в код что бы он работал одинаково ?

Вот ответ разработчика:

На самом деле иногда изменение входящих данных вызывает сброс prev_calculated в 0 (а фактически только новый тик не вызывает сброс prev_calculated). Т.е. не надо этого пугаться - если терминал решит, что история поменялась (например, синхронизировалась с сервером), то он сам сообщит индикатору о полном пересчете через prev_calculated.

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

 

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

 

Имеем индикатор, который для своих расчетов использует другие индикаторы.

В OnInit() создаем соответствующие хэндлы и в OnCalculated() ожидаем завершения обсчета всех "суб-индикаторов" с помощью    

if ( Bars(handle_symbol,handle_period)==BarsCalculated(handle) )

Ожидать while'ом нельзя, поскольку все индикаторы по одному и тому же символу обсчитываются в одном потоке, а значит можно попасть в deadlock, т.е. нужно выходить из OnCalculate() и ... ждать следующего тика в худшем случае до понедельника.

Остается только по OnTimer()? Но тогда это уже будет не индикатор, а непонятно что - рушится вся идеология.

Еще один непонятный момент - это пересчет нескольких баров "суб-индикатора", например, ZigZag. Отловить его и пересчитаться не представляется возможным.

 
yu-sha:

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

 

Имеем индикатор, который для своих расчетов использует другие индикаторы.

В OnInit() создаем соответствующие хэндлы и в OnCalculated() ожидаем завершения обсчета всех "суб-индикаторов" с помощью    

Ожидать while'ом нельзя, поскольку все индикаторы по одному и тому же символу обсчитываются в одном потоке, а значит можно попасть в deadlock, т.е. нужно выходить из OnCalculate() и ... ждать следующего тика в худшем случае до понедельника.

Остается только по OnTimer()? Но тогда это уже будет не индикатор, а непонятно что - рушится вся идеология.

Еще один непонятный момент - это пересчет нескольких баров "суб-индикатора", например, ZigZag. Отловить его и пересчитаться не представляется возможным.

 

Интересный ход мыслей! А все таки РАЗРАБОТЧИКИ, что-нибудь скажут?
 
yu-sha:

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

 

Имеем индикатор, который для своих расчетов использует другие индикаторы.

В OnInit() создаем соответствующие хэндлы и в OnCalculated() ожидаем завершения обсчета всех "суб-индикаторов" с помощью    

Ожидать while'ом нельзя, поскольку все индикаторы по одному и тому же символу обсчитываются в одном потоке, а значит можно попасть в deadlock, т.е. нужно выходить из OnCalculate() и ... ждать следующего тика в худшем случае до понедельника.


У Вас есть статистика - как часто BarsCalculated() возвращает -1 в индикаторе? исключаем случаи, когда сам обсчитываемый индикатор считается долго на каждом тике. Без такой статистики нет смысла ломать копья.
 
yu-sha:


Еще один непонятный момент - это пересчет нескольких баров "суб-индикатора", например, ZigZag. Отловить его и пересчитаться не представляется возможным.

Это о чем? О перерисовке вершин Зигзага? Так заведите себе дополнительный буфер, в котором храните хеш от всех индикаторных буферов. Изменился хеш - теребите сам индикатор Зигзаг, не изменился - что-нибудь другое теребите. Прям как малые дети.
 
Rosh:
Это о чем? О перерисовке вершин Зигзага? Так заведите себе дополнительный буфер, в котором храните хеш от всех индикаторных буферов. Изменился хеш - теребите сам индикатор Зигзаг, не изменился - что-нибудь другое теребите. Прям как малые дети.

 Хеш - это хорошая идея, спасибо

Rosh:
У Вас есть статистика - как часто BarsCalculated() возвращает -1 в индикаторе? исключаем случаи, когда сам обсчитываемый индикатор считается долго на каждом тике. Без такой статистики нет смысла ломать копья.

 Статистики нет - отказался от дальнейших экспериментов, поскольку терминал вел себя очень нестабильно при добавлении подобных индикаторов: рисовал линии через раз; отказывался загружаться,  если в шаблоне присутствовал индикатор...

Сейчас снова возникла необходимость создать подобный индикатор, поэтому подойду к этому более тщательно.

О результатах отпишусь 

 

Давно не работатал с индикаторами. Появился вопрос: а предусмотрена ли возможность создания трёхмерных графиков? Т.е. графиков, отражающих точки с координатами типа {Абсцисса; Ордината; Аппликата}. Или, может быть, имеются статьи (с готовыми функциями) о способах отражения трёхмерных объектов на плоском графике?

 
Yedelkin:

Давно не работатал с индикаторами. Появился вопрос: а предусмотрена ли возможность создания трёхмерных графиков? Т.е. графиков, отражающих точки с координатами типа {Абсцисса; Ордината; Аппликата}. Или, может быть, имеются статьи (с готовыми функциями) о способах отражения трёхмерных объектов на плоском графике?

Пока нет такой штатной возможности.

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

Хотя в индикаторах есть возможность создания графических объектов он не предназначен для тежелых математических расчетов. Для этих целей (расчеты и отрисовка) лучше подошел бы эксперт. 

Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика - Документация по MQL5
 
alexvd:

Пока нет такой штатной возможности.

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

Хотя в индикаторах есть возможность создания графических объектов он не предназначен для тежелых математических расчетов. Для этих целей (расчеты и отрисовка) лучше подошел бы эксперт. 

ОК, спасибо огромное за ответ и за советы! Не знал, что с помощью эксперта можно отрисовывать графику.
Причина обращения: