Ситуация следующая: Индикатор запускается и пытается получить данные с большего таймфрейма того же символа. Я пока не поднимаю тему получения хэндлов индикаторов. Нужно хотя бы получить историю функциями Bars, iBarsShift и т.д. В момент запуска индикатора эти данные могут быть не рассчитаны. При этом использование стандартного примера проверки (из описания функции Bars()) не возможно по причине запрета на использование Sleep(). Индикатор не будет ждать подгрузки истории, чтобы не тормозить общий поток. Документация рекомендует в этом случае использовать проверку в процедурах-обработчиках событий (OnTimer, OnCalculate и т.д.) В нижеприведенном примере я так и сделал. Индикатор ждет прихода следующего тика, а в это время подкачивается история. Но что делать, когда индикатор запускается в нерабочее время или же когда тики не возможно получить по другим причинам (например, по фьючерсам с истекшим сроком исполнения). Особенно часто такая проблема возникает при старте терминала. С приходом тика история подкачивается. А если тик не придет в разумное время?
Вот тут и нужны какие-то костыли для решения этой проблемы. Как вариант - создать принудительный вызов процедур OnInit или OnCalculate из таймера (кстати, как это сделать?). Поделитесь опытом, как вы решали данную задачу. Текст шаблона индикатора с проверками прилагаю.
Прошу обратить особое внимание на его работу при старте терминала. И еще раз напоминаю - речь идет о получении данных индикатором, а не экспертом. Там проще.
Заранее спасибо.
Класс скачивает историю необходимого размера необходимого символа необходимого ТФ. Создает массивы (close, open, low, high, time) и поддерживает в актуальном состоянии. Для этого необходимы только три строчки: создать экземпляр класса, в таймере необходимо вставить Timer(), а в OnCalculate или OnTick необходимо вставить NewTick(). Всё.
Пример индикатора с этим классом. В отдельном окне выводит цену close любого символа и тф.
#property indicator_separate_window#property indicator_buffers1#property indicator_plots1//--- plot OtherTF#property indicator_label1"OtherTF"#property indicator_type1DRAW_LINE#property indicator_color1clrViolet#property indicator_style1STYLE_SOLID#property indicator_width11#include <LoadHistory.mqh>
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+inputstring NewSymbol=""; // Какой символ? Если пусто, то текущийinputENUM_TIMEFRAMES TF=PERIOD_H1; // Какой ТаймФрейм отображаем?inputint N=10000; // Какой размер истории необходим?CLoadHistory H(NewSymbol,TF,N);double OtherTFBuffer[];
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+intOnInit()
{
SetIndexBuffer(0,OtherTFBuffer,INDICATOR_DATA);
IndicatorSetString(INDICATOR_SHORTNAME,H.Symb()+"("+StringSubstr(EnumToString(TF),7)+")");
ArrayInitialize(OtherTFBuffer,EMPTY_VALUE);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
H.NewTick();staticint preN=0;
if(H.Sync())
{
if(preN!=H.Size() || prev_calculated!=rates_total)
{
ArrayInitialize(OtherTFBuffer,EMPTY_VALUE);
int total=ArrayCopy(OtherTFBuffer,H.close,rates_total-H.Size(),0,H.Size());
}
else OtherTFBuffer[rates_total-1]=H.close[H.Size()-1];
preN=H.Size();
}
return(rates_total);
}
//+------------------------------------------------------------------+//| Timer function |//+------------------------------------------------------------------+voidOnTimer()
{
H.Timer();
}
Класс скачивает историю необходимого размера необходимого символа необходимого ТФ. Создает массивы (close, open, low, high, time) и поддерживает в актуальном состоянии. Для этого необходимы только три строчки: создать экземпляр класса, в таймере необходимо вставить Timer(), а в OnCalculate или OnTick необходимо вставить NewTick(). Всё.
Нет, описываемую мной проблему он не решает, при запуске терминала с несколькими индикаторами, использующими одинаковые тайм-серии, точно так же зависает при загрузке истории с сообщением "Loading of history: 0.04%".
Допускаю, что мог ошибиться где-то при подключении (пришлось немного подправить класс для возможности использования массива объектов), но вряд ли. Еще проверю.
Нет, описываемую мной проблему он не решает, при запуске терминала с несколькими индикаторами, использующими одинаковые тайм-серии, точно так же зависает при загрузке истории с сообщением "Loading of history: 0.04%".
Допускаю, что мог ошибиться где-то при подключении (пришлось немного подправить класс для возможности использования массива объектов), но вряд ли. Еще проверю.
Зависание происходит только с несколькими индикаторами или с одним тоже?
У меня была ситуация, когда нужно было получать данные с других символов, а в общем случае и с разных таймфреймов в МТ5. Т.е. индикатор работает на eurusd и нужны значения rsi с audusd, cadnzd b и т.п. Это было полным кошмаром ( Задачу я решил, но не уверен, что смогу нормально вырезать решение из коммерческого индикатора.
Нашел у себя библиотечный файл, который я сделал несколько лет назад из скрипта, который скачал где то здесь. Где - не помню ((
1. в папке терминала очистил все в symbols, ticks, history
2. перезапустил терминал
3. терминал начал грузить историю текущего графика, но такое ощущение, что как-то заблочил отрисовку индикатора, т.к. индикатору вернулись данные и они синхронизированы по барам, просто не отрисовываются
добавил в метод getSyncQuotes для проверки сколько баров доступно в истории и закончилась ли трансформация тиков в бары текущего таймфрейма
2018.07.1415:38:31.564 Movings (GOOG,H1) CALC 208208 // first call for OnCalculate, number of bars in indicator buffer is 2082018.07.1415:38:31.571 Movings (GOOG,H1) AMZN 00 // AMZN is not synced2018.07.1415:38:31.571 Movings (GOOG,H1) Synchronization : AMZN, Position : 0, Depth : 1500 // wait for sync on the next tick2018.07.1415:38:31.670 Movings (GOOG,H1) CALC 417417 // OnCalculate called second time, number of bars in indicator buffer is 417
2018.07.1415:38:31.670 Movings (GOOG,H1) AMZN 2081 2018.07.1415:38:31.670 Movings (GOOG,H1) GOOG 4171 // AMZN and GOOG are synced and have 208 & 417 bars respectively2018.07.1415:38:31.733 Movings (GOOG,H1) CALC 627627 2018.07.1415:38:31.733 Movings (GOOG,H1) AMZN 20812018.07.1415:38:31.733 Movings (GOOG,H1) GOOG 62712018.07.1415:38:31.794 Movings (GOOG,H1) CALC 8378372018.07.1415:38:31.794 Movings (GOOG,H1) AMZN 20812018.07.1415:38:31.794 Movings (GOOG,H1) GOOG 83712018.07.1415:38:31.868 Movings (GOOG,H1) CALC 104610462018.07.1415:38:31.868 Movings (GOOG,H1) AMZN 20812018.07.1415:38:31.868 Movings (GOOG,H1) GOOG 104612018.07.1415:38:31.964 Movings (GOOG,H1) CALC 125412542018.07.1415:38:31.964 Movings (GOOG,H1) AMZN 20812018.07.1415:38:31.964 Movings (GOOG,H1) GOOG 125412018.07.1415:38:32.044 Movings (GOOG,H1) CALC 146414642018.07.1415:38:32.044 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.044 Movings (GOOG,H1) GOOG 146412018.07.1415:38:32.114 Movings (GOOG,H1) CALC 167416742018.07.1415:38:32.114 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.114 Movings (GOOG,H1) GOOG 167412018.07.1415:38:32.209 Movings (GOOG,H1) CALC 188218822018.07.1415:38:32.209 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.209 Movings (GOOG,H1) GOOG 188212018.07.1415:38:32.282 Movings (GOOG,H1) CALC 209220922018.07.1415:38:32.282 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.282 Movings (GOOG,H1) GOOG 209212018.07.1415:38:32.358 Movings (GOOG,H1) CALC 230223022018.07.1415:38:32.358 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.358 Movings (GOOG,H1) GOOG 230212018.07.1415:38:32.430 Movings (GOOG,H1) CALC 251225122018.07.1415:38:32.430 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.430 Movings (GOOG,H1) GOOG 251212018.07.1415:38:32.518 Movings (GOOG,H1) CALC 288128812018.07.1415:38:32.518 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.518 Movings (GOOG,H1) GOOG 288112018.07.1415:38:32.559 Movings (GOOG,H1) TIMER 28812881 // the only call of OnTimer is here, indicator thinks that history is ready and DISABLES it2018.07.1415:38:32.559 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.559 Movings (GOOG,H1) GOOG 288112018.07.1415:38:32.599 Movings (GOOG,H1) CALC 324732472018.07.1415:38:32.599 Movings (GOOG,H1) AMZN 20812018.07.1415:38:32.599 Movings (GOOG,H1) GOOG 324712018.07.1415:38:32.695 Movings (GOOG,H1) CALC 362536252018.07.1415:38:32.699 Movings (GOOG,H1) AMZN 62712018.07.1415:38:32.699 Movings (GOOG,H1) GOOG 362512018.07.1415:38:32.827 Movings (GOOG,H1) CALC 396839682018.07.1415:38:32.857 Movings (GOOG,H1) AMZN 012018.07.1415:38:32.857 Movings (GOOG,H1) Synchronization : AMZN, Position : 0, Depth : 2 // new bars has come, so we sync only 2 last bars instead of 15002018.07.1415:38:33.058 Movings (GOOG,H1) CALC 429942992018.07.1415:38:33.058 Movings (GOOG,H1) AMZN 125512018.07.1415:38:33.058 Movings (GOOG,H1) GOOG 429912018.07.1415:38:33.176 Movings (GOOG,H1) CALC 465246522018.07.1415:38:33.180 Movings (GOOG,H1) AMZN 01 // new bar for AMZN is not ready, wait for syncing2018.07.1415:38:33.180 Movings (GOOG,H1) Synchronization : AMZN, Position : 0, Depth : 22018.07.1415:38:33.326 Movings (GOOG,H1) CALC 509050902018.07.1415:38:33.341 Movings (GOOG,H1) AMZN 012018.07.1415:38:33.341 Movings (GOOG,H1) Synchronization : AMZN, Position : 0, Depth : 22018.07.1415:38:33.640 Movings (GOOG,H1) CALC 577157712018.07.1415:38:33.640 Movings (GOOG,H1) AMZN 284912018.07.1415:38:33.640 Movings (GOOG,H1) GOOG 577112018.07.1415:38:34.006 Movings (GOOG,H1) CALC 645464542018.07.1415:38:34.006 Movings (GOOG,H1) AMZN 362412018.07.1415:38:34.006 Movings (GOOG,H1) GOOG 645412018.07.1415:38:34.620 Movings (GOOG,H1) CALC 713471342018.07.1415:38:34.620 Movings (GOOG,H1) AMZN 497212018.07.1415:38:34.620 Movings (GOOG,H1) GOOG 713412018.07.1415:38:35.003 Movings (GOOG,H1) CALC 77157715 2018.07.1415:38:35.003 Movings (GOOG,H1) AMZN 502412018.07.1415:38:35.003 Movings (GOOG,H1) GOOG 77151
то есть в индикаторе нет метода, который бы сказал, что что-то не так и основной чарт еще не готов, а без основного чарта индикатор может рисовать некорректно, единственный вариант, который вижу - в таймере проверять количество индикаторных буферов между тиками, если оно не меняется, то основной чарт загружен и можно грузить индикатор
Похоже, что это он неправильно насчитал по ходу появления новых баров. После загрузки новой версии и компиляции картинка совпала с той, что после перезаггрузки терминала:
Возможно, из-за того, что я поменял в двух местах PERIOD_CURRENT на PERID_M1?
только что запустил приаттаченный Movings.ex5
Супер, буду пилить. Благодарю за конструктив!
Заранее спасибо.
Класс скачивает историю необходимого размера необходимого символа необходимого ТФ. Создает массивы (close, open, low, high, time) и поддерживает в актуальном состоянии.
Для этого необходимы только три строчки: создать экземпляр класса, в таймере необходимо вставить Timer(), а в OnCalculate или OnTick необходимо вставить NewTick(). Всё.
Пример индикатора с этим классом. В отдельном окне выводит цену close любого символа и тф.
Класс скачивает историю необходимого размера необходимого символа необходимого ТФ. Создает массивы (close, open, low, high, time) и поддерживает в актуальном состоянии.
Для этого необходимы только три строчки: создать экземпляр класса, в таймере необходимо вставить Timer(), а в OnCalculate или OnTick необходимо вставить NewTick(). Всё.
Нет, описываемую мной проблему он не решает, при запуске терминала с несколькими индикаторами, использующими одинаковые тайм-серии, точно так же зависает при загрузке истории с сообщением "Loading of history: 0.04%".
Допускаю, что мог ошибиться где-то при подключении (пришлось немного подправить класс для возможности использования массива объектов), но вряд ли. Еще проверю.
Нет, описываемую мной проблему он не решает, при запуске терминала с несколькими индикаторами, использующими одинаковые тайм-серии, точно так же зависает при загрузке истории с сообщением "Loading of history: 0.04%".
Допускаю, что мог ошибиться где-то при подключении (пришлось немного подправить класс для возможности использования массива объектов), но вряд ли. Еще проверю.
Зависание происходит только с несколькими индикаторами или с одним тоже?
Зависание происходит только с несколькими индикаторами или с одним тоже?
С одним тоже. Использующим 5 чужих тайм-серий.
У меня была ситуация, когда нужно было получать данные с других символов, а в общем случае и с разных таймфреймов в МТ5. Т.е. индикатор работает на eurusd и нужны значения rsi с audusd, cadnzd b и т.п. Это было полным кошмаром ( Задачу я решил, но не уверен, что смогу нормально вырезать решение из коммерческого индикатора.
Нашел у себя библиотечный файл, который я сделал несколько лет назад из скрипта, который скачал где то здесь. Где - не помню ((
Как раз на тему синхронизации.
только что запустил приаттаченный Movings.ex5
В пятницу запустил несколько копий с разными параметрами, действительно все корректно подгрузил и посчитал.
А сейчас перегрузил терминал и увидел вот такое: До перезагрузки:
После:
Явно что-то не так.
добавил в метод getSyncQuotes для проверки сколько баров доступно в истории и закончилась ли трансформация тиков в бары текущего таймфрейма
добавил в индикаторе проверку загружены ли индикаторные буферы
и вот принты с результатами
то есть в индикаторе нет метода, который бы сказал, что что-то не так и основной чарт еще не готов, а без основного чарта индикатор может рисовать некорректно, единственный вариант, который вижу - в таймере проверять количество индикаторных буферов между тиками, если оно не меняется, то основной чарт загружен и можно грузить индикатор
Похоже, что это он неправильно насчитал по ходу появления новых баров. После загрузки новой версии и компиляции картинка совпала с той, что после перезаггрузки терминала:
Возможно, из-за того, что я поменял в двух местах PERIOD_CURRENT на PERID_M1?