Один цикл по всем барам истории необходим. Но чтобы индикатор работал быстро, необходимо его писать таким образом, чтобы этот основной цикл был единственным. То есть, внутри этого цикла не должно быть дополнительных прогонок по истории.
И для этого необходимо рассчитывать и сохранять промежуточные данные. Тогда у Вас всё будет летать.
Простой пример нахождения максимума графика:
double max=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[]) { //вот ваш основной цикл if (counted_bars==0) {limit--; limit-=10;} else limit++; for(i=limit; i>=0; i--) { //и внутри него мы поддерживаем актуальное значение max if(high[i]-max>0) max=high[i]; }
А ведь многие в этом цикле будут ещё одним циклом искать максимум. Вот и будут тормоза.
использую такой шаблон для используемых индикаторов
ключевые моменты в данном случае
- расчет не чаще 1 раза в сек
- проверка на новый бар
- старт расчета с последних N баров ()
может поможет какой то вариант, городить конкретно даты для разных периодов не пробовал, мне достаточно N баров последних или просто эконом расчет
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double& price[]) { //--- пропускаем если прошло менее 1 сек // static uint LastOnCalculate = GetTickCount(); // if(GetTickCount() - LastOnCalculate < 1000) // return(rates_total); // LastOnCalculate = GetTickCount(); //--- проверим минимальный расчет баров и количество рассчитанных данных для запрашиваемого индикатора if(BarsCalculated(Handle_1)<rates_total || BarsCalculated(Handle_2)<rates_total || rates_total<min_rates_total) return(RESET);//--- //--- проверка на новый бар if(prev_calculated==rates_total) return(rates_total); //---- объявления локальных переменных int start, bar; //---- проверим прошлый расчет для пересчёта баров (смена графика, периода или компиляция) if(prev_calculated>rates_total || prev_calculated<=0) { //--- укажем бар первого расчет индикатора start=min_rates_total; // "0" -> D'1970.01.01 00:00'; //start=rates_total-3; // для теста, сколько от текущего бара //--- очистим буферы для начала работы //ArrayInitialize(Buffer1,EMPTY_VALUE); //ArrayInitialize(Buffer2,EMPTY_VALUE); } else start=prev_calculated; // стартовый номер для расчёта новых баров //--- индексация элементов в массивах, как в таймсериях ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); ArraySetAsSeries(WPR_Buffer,true); //--- if(CopyBuffer(Handle,0,1,1,Buffer1) <=0 || // Значение индикатора CopyBuffer(Handle,1,1,1,Buffer2) <=0) // 0-Up, 1-Dn { // убрать Print в релизе Print("Не удалось скопировать значения c Handle"); return(RESET); } //+------------------------------------------------------------------+ //| основной цикл расчёта индикатора | //+------------------------------------------------------------------+ for(bar=start; bar<rates_total && !IsStopped(); bar++) { Print("Color: ",Buffer1[0]," Value: ",Buffer2[0]); } //--- return value of prev_calculated for next call return(rates_total); }
А без OnCalculate() есть варианты обработки баров в истории, т.к. я так же вызываю функцию в OnTimer()
А без OnCalculate() есть варианты обработки баров в истории, т.к. я так же вызываю функцию в OnTimer()
Если речь об индикаторе, то никак. Индикатор обязан содержать обработчик OnCalculate(). Другое дело, что этот обработчик может быть пустым. Если обрабатываете в OnTimer, то достаточно повторить логику OnCalculate, создав свои переменные по типу rates_total и prev_calculated.
Есть какой нибудь быстрый цикл баров истории с ограничением отображения по дате а не по барам ?
У индикатора отображать объекты на графике не по всей истории а с определённой даты, например с начала 2020 года
а что мешает проверять заданную дату и не рисовать объекты если они младше.
еще - зачем вам рассчитывать всю историю и не показывать ее?
Считайте сразу сколько нужно 100-1000 последних баров.
зачем вам рассчитывать всю историю и не показывать ее?
Считайте сразу сколько нужно 100-1000 последних баров.
Не удобно по барам ограничивать
1000 баров на Н4 будет примерно к началу года, а М5 пару месяцев отрисует
Не удобно по барам ограничивать
1000 баров на Н4 будет примерно к началу года, а М5 пару месяцев отрисует
ну, как я понял вопрос в торможении графика из-за кучи объектов, а не из-за удобства даты.
Спрошу тогда по другому
Как для индикатора, безопасно и без лагов графика, пересчитывать все бары в истории на каждом тике и по типу первый старт
Т.е. при первом старте пересчитываются все бары в истории и далее добавляется новый бар, вот и нужно постоянно пересчитывать все бары в истории
void OnTimer(){ Signals(); } //--- void start(){ Signals(); } //--- void Signals() { int i,limit; int counted_bars=IndicatorCounted(); if (counted_bars<0) return; if (counted_bars>0) counted_bars--; limit = MathMin(Bars-counted_bars,Bars-1); if (counted_bars==0) {limit--; limit-=10;} else limit++; for(i=limit; i>=0; i--) {
Т.е. при первом старте пересчитываются все бары в истории и далее добавляется новый бар, вот и нужно постоянно пересчитывать все бары в истории
все написано, вникайте
все написано, вникайте
Спасибо большое, вы мне очень помогли, не ужели всё так просто, а я тут мучаюсь!!
Не понимаю, для чего вообще такие ответы давать, информативности ноль, просто так мимо проходил?
На форуме есть люди которые знают ответ на поставленный вопрос и есть которые не знают и задают эти вопросы, почему бы не помочь если знаешь решение, ведь сами же были такими однажды непосвящёнными. Все ответы в основном какими-то загадками, что ещё более усложняет восприятие поставленной задачи. Уверен на 100% что сами обращались за ответом на мучающий вас вопрос и ожидали более информативное решение с примером.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
У меня закачена история с 1999 года
Есть какой нибудь быстрый цикл баров истории с ограничением отображения по дате а не по барам ?
У индикатора отображать объекты на графике не по всей истории а с определённой даты, например с начала 2020 года
Или может есть быстрый цикл по всей истории но чтоб не тормозил график ?
Такой цикл не подходит, тяжело тащит
int i,limit; int counted_bars=IndicatorCounted(); if (counted_bars<0) return(-1); if (counted_bars>0) counted_bars--; limit = MathMin(Bars-counted_bars,Bars-1); if (counted_bars==0) {limit--; limit-=10;} else limit++; for(i=limit; i>=0; i--){