Не "глючит", а показывает последний известный бар (необновленную историю).
Терминал отслеживает (и строит) только активные периоды.
Остальные нужно обновлять (подгружать) самостоятельно.
Остальные нужно обновлять (подгружать) самостоятельно.
Какой функций это делается?
Какой функций это делается?
так как это в OnCalculate, то достаточно добавить проверку
if (rates_total-prev_calculated>1) { //пересчитываем всё заново }
Какой функций это делается?
индикаторы не умеют самостоятельно подгружать историю, можно конечно через iTime / iClose ... любую ф-ицю запустить подкачку истории
но обычно это делают для мультитаймфреймовых индикаторов, в обычном индикаторе достаточно проверить prev_calculated ==0 - значит было или переключение ТФ или была подгрузка исторических данных
я использую вот такой свой шаблон индикатора:
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,limit; if(prev_calculated == 0) { limit = rates_total - 1; //--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории } else limit = rates_total - prev_calculated + 1; for(i = limit; i >= 0; i--) { //--- В этом цикле основные вычисления. Таким образом обрабатываться будет только "свежая" информация } return(rates_total);
так как это в OnCalculate, то достаточно добавить проверку
Спасибо!
я использую вот такой свой шаблон индикатора:
Спасибо!
Я смотрю свои код и вижу там проверку, но все портит функция которая пропускает один раз в час. Поскольку в алгоритме заложено изменение только по PERIOD_H1, то мне не надо чаще делать вычисления. Как в таком случае бы сделали вы?
ПС. В первом посте был сделан отдельный код для проверки, это из основного кода.
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 limit=0; if(rates_total<MaxBarsMod || MaxBarsMod==0) MaxBarsMod=rates_total; if(prev_calculated<rates_total && prev_calculated!=0) { MaxBarsMod+=rates_total-prev_calculated; } if(prev_calculated!=0) limit=MaxBarsMod-(rates_total-prev_calculated); else limit=0; //--- здесь все расчеты значений индикатора if(prev_calculated<rates_total && NewBar1H()) { } return(rates_total); } bool NewBar1H() {bool r;static datetime bar=0;if(bar==0) bar=TimeCurrent();if(bar==iTime(Symbol(),PERIOD_H1,0)) r=false; else { bar=iTime(Symbol(),PERIOD_H1,0); r=true; }return(r);}
...то мне не надо чаще делать вычисления.
если rates_total-prev_calculated>1 то это значит что произошло обновление истории, добавилось много новых баров, это значит что нужно пересчитать всё заново (все бары).
И эти новые бары могут появится где угодно, не обязательно в конце истории и последовательно.
Я смотрю свои код и вижу там проверку, но все портит функция которая пропускает один раз в час. Поскольку в алгоритме заложено изменение только по PERIOD_H1, то мне не надо чаще делать вычисления. Как в таком случае бы сделали вы?
примерно такой код, но не проверял как работать будет:
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,limit; static int lasthour=-1; if(prev_calculated==0) //--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории { limit=rates_total-1; lasthour=-1; } else limit=rates_total-prev_calculated+1; if(TimeHour(time[1])!=lasthour) //--- Проверяем изменился ли час последнего бара, если час такой как и был на предыдущем тике, то вернем только количество рассчитанных баров { lasthour=TimeHour(time[1]); } else return(prev_calculated); for(i=limit; i>=0; i--) //--- В этом цикле основные вычисления. Таким образом обрабатываться будет только "свежая" информация { } return(rates_total); }
Я смотрю свои код и вижу там проверку, но все портит функция которая пропускает один раз в час. Поскольку в алгоритме заложено изменение только по PERIOD_H1, то мне не надо чаще делать вычисления. Как в таком случае бы сделали вы?
ПС. В первом посте был сделан отдельный код для проверки, это из основного кода.
Два способа:
- Простой, но некошерный. Переместить проверку нового часового бара выше, до проверки prev_calculated.
- Правильный, но чуть более сложный. Перевести логику rates_total и prev_calculated на необходимый ТФ. В данном случае на Н1:
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Определение индекса бара, с которого необходимо производить перерасчет | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ int GetRecalcIndex() { int nTotal = iBars(NULL, m_eTF); int nLimit = nTotal - 1; // Первое отображение или произошла подкачка данных, т. е. на предыдущем тике баров было не на один бар меньше, как при нормальном развитии истории, а на два или более баров меньше if (m_nPrevCalculated < nTotal - 1) { // Какие-то действия по инициализации индикатора. Например, заполнение буферов индикатора значениями по умолчанию } // Нормальное развитие истории. Количество баров на текущем тике отличается от количества баров на предыдущем тике не больше, чем на один бар else nLimit = (MathMin(nTotal - m_nPrevCalculated, nTotal)); m_nPrevCalculated = nTotal; return nLimit; }
m_nPrevCalculated - собственная глобальная переменная, ничего общего с prev_calculated не имеет, хотя и выполняет ту же функцию.
m_eTF - ТФ, для которого производятся расчеты.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
В OnCalculate, при смене периода графика, Time[0] на первом тике иногда глючит. Кто вникал в эту проблему? Хватит дождаться 2 тика или надо уже сделать проверку по умнее, например Time[0] сравнивать с последним временем сервера?