Alexey Kozitsyn: А если просто пересчитать весь индикатор когда 0? По-моему, лучшее решение.
Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого
Alexander Puzanov: Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого
Человек употребляющий слово "костыль":
или лениться почитать документацию
или пока ещё не знает, как должно быть правильно.
Единственно правильное решение: при prev_calculate==0 пересчитывать индикатор.
Alexander Puzanov: Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого
Karputov Vladimir: А если история была подкачена, значит могут быть новые бары, которые были пропущены или не рассчитаны ранее - то есть показания индикатора уже будут неправильными.
Slawa:
Если prev_calculated=0, то это означает, что надо делать полный пересчёт. Все стандартные индикаторы полностью пересчитываются в данном случае.
Всё понятно, но увы, это всё не отменяет вот этого:
Alexander Puzanov:
Это всё полезно, но использовать по прямому назначению - показывать сколько 'обработано баров на предыдущем вызове' - prev_calculated нельзя
Индикаторы бывают разные, некоторым вообще бары не нужны для расчётов, другим нужны только живые тики, у третьих есть ограничение на глубину пересчёта - что там дальше в истории изменилось им пофиг, четвёртые отслеживают графические объекты итд. Навешанные на prev_calculated доп функции отслеживания изменений в истории им не нужно, нужно только это - 'обработано баров на предыдущем вызове'. Этого нет
В общем, ув программисты, не отвлекайте, пожалуйста, столяра от 'отлова события'
Alexey Kozitsyn: А если просто пересчитать весь индикатор когда 0? По-моему, лучшее решение.
Я-бы не сказал что это лучшее решение. Во всяком случае пока не лучшее.
Решил я написать индикатор регистрирующий текущую просадку на счёте, соответственно мне ничего в истории пересчитывать не надо. Первая строка выглядела сначала так.
if(prev_calculated == 0) return(rates_total);
Но после запуска обнаружил что буферы не пустые и не обнулённые. В буферах какая-то цена неизвестно откуда взявшаяся. Пришлось принудительно обнулять буферы... Дальше обнаружилась другая проблема. Именно та о которой идёт речь, prev_calculate обнуляется и индикатор пересчитывается, соответственно обнуляя все буферы до последнего бара. В общем пока бросил эту затею.
Я-бы не сказал что это лучшее решение. Во всяком случае пока не лучшее.
Решил я написать индикатор регистрирующий текущую просадку на счёте, соответственно мне ничего в истории пересчитывать не надо. Первая строка выглядела сначала так.
if(prev_calculated == 0) return(rates_total);
Но после запуска обнаружил что буферы не пустые и не обнулённые. В буферах какая-то цена неизвестно откуда взявшаяся. Пришлось принудительно обнулять буферы... Дальше обнаружилась другая проблема. Именно та о которой идёт речь, prev_calculate обнуляется и индикатор пересчитывается, соответственно обнуляя все буферы до последнего бара. В общем пока бросил эту затею.
"... какая-то цена неизвестно откуда взявшаяся ... " - это мусор НЕИНИЦИАЛИЗИРОВАННЫХ элементов массива индикаторного буфера. Как нужно поступать:
при prev_calculate==0 пройтись в цикле по всем элементам индикаторного буфера и назначить им значения. При этом нужно отслеживать ситуацию появления нового бара ( rates_total минус prev_calculate будет больше нуля) - при этом индикаторный буфер соответственно увеличивается и этот новый элемент тоже нужно проинициализировать.
Лучше объясни как избавиться от мусора ПРИ ПЕРВОМ запуске индикатора. Откуда этот мусор? Разве при связывании буфера с массивом не должно происходить инициализации? или именно при инициализации в массив попадает космический мусор??? Почему в mql4 такого мусора нет?
Приведи лучше пример как отсеять мусор от нормальных значений без использования посторонних дополнительных статических или глобальных переменных.
Никто никому ничего не должен. То есть в индикаторном буфере, после связывания, будет мусор, пока Вы самостоятельно не проинициализируете все элементы массива.
Добавлено:
Сейчас создам пример...
//+------------------------------------------------------------------+ //| prev_calculated.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright"Copyright 2016, MetaQuotes Software Corp." #property link"https://www.mql5.com" #property version"1.00" #property indicator_separate_window #property indicator_buffers1 #property indicator_plots1 #property indicator_type1 DRAW_LINE #property indicator_color1 clrGray #property indicator_label1 "prev_calculated" //---- buffers double ExtBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ intOnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA); //--- 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[]) { //--- if(prev_calculated==0) { //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории for(int i=0;i<rates_total;i++) ExtBuffer[i]=1.01; return(rates_total); } //--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара int limit=rates_total-prev_calculated+1; for(int i=rates_total-limit;i<rates_total;i++) { //--- визуализация пересчёта самого правого бара staticbool drive=false; if(!drive) ExtBuffer[i]=1.03; else ExtBuffer[i]=1.02; drive=!drive; } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Запустите его на M1. Будет видно, что пересчитывается только самый правый бар.
Никто никому ничего не должен. То есть в индикаторном буфере, после связывания, будет мусор, пока Вы самостоятельно не проинициализируете все элементы массива.
Добавлено:
Сейчас создам пример...
//+------------------------------------------------------------------+ //| prev_calculated.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright"Copyright 2016, MetaQuotes Software Corp." #property link"https://www.mql5.com" #property version"1.00" #property indicator_separate_window #property indicator_buffers1 #property indicator_plots1 #property indicator_type1 DRAW_LINE #property indicator_color1 clrGray #property indicator_label1 "prev_calculated" //---- buffers double ExtBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ intOnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA); //--- 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[]) { //--- if(prev_calculated==0) { //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории for(int i=0;i<rates_total;i++) ExtBuffer[i]=1.01; return(rates_total); } //--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара int limit=rates_total-prev_calculated+1; for(int i=rates_total-limit;i<rates_total;i++) { //--- визуализация пересчёта самого правого бара staticbool drive=false; if(!drive) ExtBuffer[i]=1.03; else ExtBuffer[i]=1.02; drive=!drive; } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Запустите его на M1. Будет видно, что пересчитывается только самый правый бар.
Потрясающая способность отвечать не на тот вопрос который задан...
Теперь объясни мне что произойдёт если:
1. Пересчиталось 100 баров, внесено в буферы от 0 по 99 включительно (давайте считать направление как таймсерию) значение 1.03
2. Вдруг подгрузилась история и prev_calculated стало равно 0
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
А если просто пересчитать весь индикатор когда 0? По-моему, лучшее решение.
:) Я так и делаю...
Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого
Человек употребляющий слово "костыль":
Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого
А если история была подкачена, значит могут быть новые бары, которые были пропущены или не рассчитаны ранее - то есть показания индикатора уже будут неправильными.
Если prev_calculated=0, то это означает, что надо делать полный пересчёт. Все стандартные индикаторы полностью пересчитываются в данном случае.
Всё понятно, но увы, это всё не отменяет вот этого:
Это всё полезно, но использовать по прямому назначению - показывать сколько 'обработано баров на предыдущем вызове' - prev_calculated нельзя
Индикаторы бывают разные, некоторым вообще бары не нужны для расчётов, другим нужны только живые тики, у третьих есть ограничение на глубину пересчёта - что там дальше в истории изменилось им пофиг, четвёртые отслеживают графические объекты итд. Навешанные на prev_calculated доп функции отслеживания изменений в истории им не нужно, нужно только это - 'обработано баров на предыдущем вызове'. Этого нет
В общем, ув программисты, не отвлекайте, пожалуйста, столяра от 'отлова события'
А если просто пересчитать весь индикатор когда 0? По-моему, лучшее решение.
Я-бы не сказал что это лучшее решение. Во всяком случае пока не лучшее.
Решил я написать индикатор регистрирующий текущую просадку на счёте, соответственно мне ничего в истории пересчитывать не надо. Первая строка выглядела сначала так.
Я-бы не сказал что это лучшее решение. Во всяком случае пока не лучшее.
Решил я написать индикатор регистрирующий текущую просадку на счёте, соответственно мне ничего в истории пересчитывать не надо. Первая строка выглядела сначала так.
"... какая-то цена неизвестно откуда взявшаяся ... " - это мусор НЕИНИЦИАЛИЗИРОВАННЫХ элементов массива индикаторного буфера. Как нужно поступать:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Ошибки, баги, вопросы
Alexey Viktorov, 2016.10.17 09:58
Сам-то понял что написал?
Лучше объясни как избавиться от мусора ПРИ ПЕРВОМ запуске индикатора. Откуда этот мусор? Разве при связывании буфера с массивом не должно происходить инициализации? или именно при инициализации в массив попадает космический мусор??? Почему в mql4 такого мусора нет?
Приведи лучше пример как отсеять мусор от нормальных значений без использования посторонних дополнительных статических или глобальных переменных.
Цитировать документацию все горазды.
Никто никому ничего не должен. То есть в индикаторном буфере, после связывания, будет мусор, пока Вы самостоятельно не проинициализируете все элементы массива.
Добавлено:
Сейчас создам пример...
//| prev_calculated.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGray
#property indicator_label1 "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
if(prev_calculated==0)
{
//--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
for(int i=0;i<rates_total;i++)
ExtBuffer[i]=1.01;
return(rates_total);
}
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
int limit=rates_total-prev_calculated+1;
for(int i=rates_total-limit;i<rates_total;i++)
{
//--- визуализация пересчёта самого правого бара
static bool drive=false;
if(!drive)
ExtBuffer[i]=1.03;
else
ExtBuffer[i]=1.02;
drive=!drive;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
Никто никому ничего не должен. То есть в индикаторном буфере, после связывания, будет мусор, пока Вы самостоятельно не проинициализируете все элементы массива.
Добавлено:
Сейчас создам пример...
//| prev_calculated.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGray
#property indicator_label1 "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
if(prev_calculated==0)
{
//--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
for(int i=0;i<rates_total;i++)
ExtBuffer[i]=1.01;
return(rates_total);
}
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
int limit=rates_total-prev_calculated+1;
for(int i=rates_total-limit;i<rates_total;i++)
{
//--- визуализация пересчёта самого правого бара
static bool drive=false;
if(!drive)
ExtBuffer[i]=1.03;
else
ExtBuffer[i]=1.02;
drive=!drive;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
Потрясающая способность отвечать не на тот вопрос который задан...
Теперь объясни мне что произойдёт если:
1. Пересчиталось 100 баров, внесено в буферы от 0 по 99 включительно (давайте считать направление как таймсерию) значение 1.03
2. Вдруг подгрузилась история и prev_calculated стало равно 0
С какого бара в индикаторе будет значение 1.03???