p.s. единственное, мне бы хотелось получить аргументированное пояснение -- почему Артём использует в mql5 -- индексацию буферных массивов как mql4 -- но думаю, что получу ответ в стиле "мне так удобно" -- хотя, Артём говорит, что делал пояснения на этот счёт -- если делал, то полезно бы привести ссылку на его такое пояснение.
я отвечаю так, как я понял твой вопрос -- так понимаю, я твой вопрос не понял?
и потом -- для меня эта тема себя исчерпала -- слишком много времени мной потрачено на информационно пустое для меня обсуждение.
я не использую схему Артёма -- как по мне, его схема устаревшая -- я использую схему с индексацией буферных массивов как mql5 (от истории к текущему бару) -- я даже в индикаторах mql4 использую индексацию как в mql5.
Ну так ведь сам решил поучаствовать. Единственно в чём я с тобой согласен, так это не надо никому ничего навязывать. Если ты считаешь оправданным поиск бара на котором оборвалась связь, так и считай его. На мой взгляд это совсем никчёмное занятие. Прибавилось баров больше чем 1, пересчитали весь индикатор и все дела.
А если связь оборвалась на середине бара и close не действительно, объём не соответствует… Его ведь надо пересчитать… А в prev_calculated этот бар уже считался, когда он был последним, текущим.
А вот кстати… Представь ситуацию, что бары прибавились не только в конце истории. Не только самые правые, а есть ещё и в середине. Да, если работать на компе IBM 386 то конечно……………
p.s. единственное, мне бы хотелось получить аргументированное пояснение -- почему Артём использует в mql5 -- индексацию буферных массивов как mql4 -- но думаю, что получу ответ в стиле "мне так удобно" -- хотя, Артём говорит, что делал пояснения на этот счёт -- если делал, то полезно бы привести ссылку на его такое пояснение.
Просто не хочет вникать в другие варианты, не хватает времени. И это обсуждение новичкам даст гораздо больше чем все примеры в CodeBase. Так-что твоё время потрачено не зря.
А вот кстати… Представь ситуацию, что бары прибавились не только в конце истории. Не только самые правые, а есть ещё и в середине. Да, если работать на компе IBM 386 то конечно……………
этот момент тестировал -- при расширении истории влево (доливка) -- сам движок МТ сбрасывает prev_calculated в ноль -- т.е. если в индикаторе схема движения по барам корректная -- то она корректно отработает такую ситуацию.
этот момент тестировал -- при расширении истории влево (доливка) -- сам движок МТ сбрасывает prev_calculated в ноль -- т.е. если в индикаторе схема движения по барам корректная -- то она корректно отработает такую ситуацию.
И это не зависит от направления индексации принятой программистом. Так-что никаких проблем.
Просто не хочет вникать в другие варианты, не хватает времени. И это обсуждение новичкам даст гораздо больше чем все примеры в CodeBase. Так-что твоё время потрачено не зря.
если не вникать в используемые базовые схемы -- то со временем количество превратится в такое количество -- которое гарантированно обесценит всё ранее написанное.
если не вникать -- то количество никогда не превратится в качество.
"зачем заморачиваться", "зачем вникать, итак работает" -- это когда количество превращается только в бестолковое количество.
limit =10 -- и надо отнять 1, чтобы не был выход за пределы массива в цикле for(int i=limit; i>=0; i--) -- идёт перерасчёт всей истории от бара 9 до 0
ситуация В -- текущий бар
rates_total =10
prev_calculated =10
limit =0 -- идёт перерасчёт нового бара
ситуация С -- новый бар -- бары: 10 9 8 7 6 5 4 3 2 [1 0]
rates_total =11
prev_calculated =10 -- остановились на баре 1
limit =1 -- идёт перерасчёт только что закрытого бара 1 и нового бара 0
ситуация D -- отсутствовала связь бары: 10 9 8 7 [6 5 4 3 2 1 0]
rates_total =11
prev_calculated =5 -- остановились на баре 6
limit =11-5 =6 -- отнимается 1 по if(limit>1) -- идёт перерасчёт с бара 5, "закрытый" бар 6 не перерасчитывается, а должен был, чтобы отработать его закрытие на манер ситуации С
Вот индикатор:
//+------------------------------------------------------------------+//| TestLimit.mq5 |//| Copyright 2024, MetaQuotes Ltd. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2024, MetaQuotes Ltd."#property link"https://www.mql5.com"#property version"1.00"#property indicator_chart_window#property indicator_buffers1#property indicator_plots1//--- plot Label1#property indicator_label1"Test"#property indicator_type1DRAW_LINE#property indicator_color1clrRed#property indicator_style1STYLE_SOLID#property indicator_width11//--- indicator buffersdouble Buffer[];
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- indicator buffers mappingSetIndexBuffer(0,Buffer,INDICATOR_DATA);
ArraySetAsSeries(Buffer,true);
//---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[])
{
//---ArraySetAsSeries(time,true);
ArraySetAsSeries(close,true);
string tm=TimeToString(time[0]);
int limit=rates_total-prev_calculated;
/*
if(limit==0)
{
Расчёт каждого тика на текущем нулевом баре
}
*///--- Первый запуск, либо изменения в историиif(limit>1)
{
limit=rates_total-1;
PrintFormat("%s: Обрабатываем условие if(limit>1) { инициализация буфера и полный перерасчёт индикатора (%d баров) }",tm,limit);
ArrayInitialize(Buffer,EMPTY_VALUE);
}
if(limit>=1)
{
string x=(limit==1 ? "Новый бар" : "Первый запуск или изменения в истории");
PrintFormat("%s: %s. rates_total=%d, prev_calculated=%d, limit=%d. Считаем от %d до 0",tm,x,rates_total,prev_calculated,limit,limit);
}
//--- Цикл от начала истории до текущего времениfor(int i=limit;i>=0;i--)
{
Buffer[i]=close[i];
}
//--- return value of prev_calculated for next callreturn(rates_total);
}
//+------------------------------------------------------------------+
Вот тест:
В 05:07 по серверному времени запустил индикатор (далее все времена по этому же времени),
После открытия нового бара в 05:11 отключил интернет
В 05:19 интернет подключил обратно.
Результаты теста индикатора в журнале:
2024.10.0705:07: Обрабатываем условие if(limit>1) { инициализация буфера и полный перерасчёт индикатора (250002 баров) }
2024.10.0705:07: Первый запуск или изменения в истории. rates_total=250003, prev_calculated=0, limit=250002. Считаем от 250002 до 02024.10.0705:08: Новый бар. rates_total=250004, prev_calculated=250003, limit=1. Считаем от 1 до 02024.10.0705:09: Новый бар. rates_total=250005, prev_calculated=250004, limit=1. Считаем от 1 до 02024.10.0705:10: Новый бар. rates_total=250006, prev_calculated=250005, limit=1. Считаем от 1 до 02024.10.0705:11: Новый бар. rates_total=250007, prev_calculated=250006, limit=1. Считаем от 1 до 02024.10.0705:19: Обрабатываем условие if(limit>1) { инициализация буфера и полный перерасчёт индикатора (249999 баров) }
2024.10.0705:19: Первый запуск или изменения в истории. rates_total=250000, prev_calculated=0, limit=249999. Считаем от 249999 до 02024.10.0705:20: Новый бар. rates_total=250001, prev_calculated=250000, limit=1. Считаем от 1 до 0
Как видим, после обрыва связи prev_calculated сбрасывается в ноль. Поэтому самый быстрый способ - пересчитать всю историю, чем запоминать прошлый prev_calculated, определять именно обрыв связи (ведь бары могут быть пропущены из-за редких тиков), восстанавливать текущее (нулевое после восстановления связи) значение prev_calculated из ранее запомненного и высчитывать количество пропущенных баров.
Как видим, после обрыва связи prev_calculated сбрасывается в ноль. Поэтому самый быстрый способ - пересчитать всю историю, чем запоминать прошлый prev_calculated, определять именно обрыв связи (ведь бары могут быть пропущены из-за редких тиков), восстанавливать текущее (нулевое после восстановления связи) значение prev_calculated из ранее запомненного и высчитывать количество пропущенных баров.
Алгоритм работает эффективно.
твой тест не полный -- ты пишешь "запоминать прошлый prev_calculated, определять именно обрыв связи" -- такую отработку не позволит сделать сам движок терминала.
prev_calculated сбрасывает в ноль движок терминала -- при отклонении rates_total в больше или меньше хотя больше чем на 1 бар от предыдущего -- движок терминала prev_calculated сбрасывает в ноль.
усложнил тест и добавил времязатратный расчёт -- чтобы выйти за пределы нескольких баров М1.
поведение движка терминала следующее -- он не перескакивает и не доливает бары -- он отрабатывает бар за баром без пропусков.
-- на картинке -- видно, что текущее время :48 -- а отрабатывает движок последовательно бар за баром и пока только :44 бар
т.е. движок терминала не отрабатывает актуальный текущий бар
вывод: корректней делать проверку не на if(limit>1) -- а на if(prev_calculate==0)
-- т.к. алгоритм должен делать естественную отработку состояний -- а не искривлять отработку состояний -- движок сам упростит те состояния, которые ему надо упростить
Ладно. Такое пороговое состояние в стиле "индикатор работает, но один бар считает за пять минут и что же при этом делает движок терминала.., а если ещё и отвёрткой ковырнуть..." обсуждать уже не интересно. Кто-то говорил ещё о морганиях для клиентов.
Знаю, сейчас начнёшь о "чистоте экспериментов". Продолжай без меня. Ты никогда не признаёшь ничего за собой. Я, к сожалению, об этом забыл.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
p.s. единственное, мне бы хотелось получить аргументированное пояснение -- почему Артём использует в mql5 -- индексацию буферных массивов как mql4 -- но думаю, что получу ответ в стиле "мне так удобно" -- хотя, Артём говорит, что делал пояснения на этот счёт -- если делал, то полезно бы привести ссылку на его такое пояснение.
я отвечаю так, как я понял твой вопрос -- так понимаю, я твой вопрос не понял?
и потом -- для меня эта тема себя исчерпала -- слишком много времени мной потрачено на информационно пустое для меня обсуждение.
я не использую схему Артёма -- как по мне, его схема устаревшая -- я использую схему с индексацией буферных массивов как mql5 (от истории к текущему бару) -- я даже в индикаторах mql4 использую индексацию как в mql5.
Ну так ведь сам решил поучаствовать. Единственно в чём я с тобой согласен, так это не надо никому ничего навязывать. Если ты считаешь оправданным поиск бара на котором оборвалась связь, так и считай его. На мой взгляд это совсем никчёмное занятие. Прибавилось баров больше чем 1, пересчитали весь индикатор и все дела.
А если связь оборвалась на середине бара и close не действительно, объём не соответствует… Его ведь надо пересчитать… А в prev_calculated этот бар уже считался, когда он был последним, текущим.
А вот кстати… Представь ситуацию, что бары прибавились не только в конце истории. Не только самые правые, а есть ещё и в середине. Да, если работать на компе IBM 386 то конечно……………
p.s. единственное, мне бы хотелось получить аргументированное пояснение -- почему Артём использует в mql5 -- индексацию буферных массивов как mql4 -- но думаю, что получу ответ в стиле "мне так удобно" -- хотя, Артём говорит, что делал пояснения на этот счёт -- если делал, то полезно бы привести ссылку на его такое пояснение.
Просто не хочет вникать в другие варианты, не хватает времени. И это обсуждение новичкам даст гораздо больше чем все примеры в CodeBase. Так-что твоё время потрачено не зря.
А вот кстати… Представь ситуацию, что бары прибавились не только в конце истории. Не только самые правые, а есть ещё и в середине. Да, если работать на компе IBM 386 то конечно……………
этот момент тестировал -- при расширении истории влево (доливка) -- сам движок МТ сбрасывает prev_calculated в ноль -- т.е. если в индикаторе схема движения по барам корректная -- то она корректно отработает такую ситуацию.
этот момент тестировал -- при расширении истории влево (доливка) -- сам движок МТ сбрасывает prev_calculated в ноль -- т.е. если в индикаторе схема движения по барам корректная -- то она корректно отработает такую ситуацию.
И это не зависит от направления индексации принятой программистом. Так-что никаких проблем.
Просто не хочет вникать в другие варианты, не хватает времени. И это обсуждение новичкам даст гораздо больше чем все примеры в CodeBase. Так-что твоё время потрачено не зря.
если не вникать в используемые базовые схемы -- то со временем количество превратится в такое количество -- которое гарантированно обесценит всё ранее написанное.
если не вникать -- то количество никогда не превратится в качество.
"зачем заморачиваться", "зачем вникать, итак работает" -- это когда количество превращается только в бестолковое количество.
И это не зависит от направления индексации принятой программистом. Так-что никаких проблем.
да, от направления индексации это не зависит -- зависит от корректной отработки prev_calculated.
направление индексации влияет только на алгоритм анализа баров.
потом исправил своё пояснение -- пояснил, что ситуацию D твой алгоритм вообще не отрабатывает.
Итак. Вот утверждения:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Могли бы вы рассказать о случае, когда участник форума оказался полезным в вашей работе, и можете ли вы описать это подробно?
Andrey F. Zelinsky, 2024.10.05 13:53
эта схема требует доработки -- я бы эту схему в реальности не использовал -- проблему схемы выделил желтым -- ну, а вопрос про отнимание 1 подчеркнул.
рассмотрим четыре примера.
пусть есть 10 баров -- 9 8 7 6 5 4 3 2 1 0
ситуация А -- начало расчёта
rates_total =10
prev_calculated =0
limit =10 -- и надо отнять 1, чтобы не был выход за пределы массива в цикле for(int i=limit; i>=0; i--) -- идёт перерасчёт всей истории от бара 9 до 0
ситуация В -- текущий бар
rates_total =10
prev_calculated =10
limit =0 -- идёт перерасчёт нового бара
ситуация С -- новый бар -- бары: 10 9 8 7 6 5 4 3 2 [1 0]
rates_total =11
prev_calculated =10 -- остановились на баре 1
limit =1 -- идёт перерасчёт только что закрытого бара 1 и нового бара 0
ситуация D -- отсутствовала связь бары: 10 9 8 7 [6 5 4 3 2 1 0]
rates_total =11
prev_calculated =5 -- остановились на баре 6
limit =11-5 =6 -- отнимается 1 по if(limit>1) -- идёт перерасчёт с бара 5, "закрытый" бар 6 не перерасчитывается, а должен был, чтобы отработать его закрытие на манер ситуации С
Вот индикатор:
Вот тест:
Результаты теста индикатора в журнале:
Как видим, после обрыва связи prev_calculated сбрасывается в ноль. Поэтому самый быстрый способ - пересчитать всю историю, чем запоминать прошлый prev_calculated, определять именно обрыв связи (ведь бары могут быть пропущены из-за редких тиков), восстанавливать текущее (нулевое после восстановления связи) значение prev_calculated из ранее запомненного и высчитывать количество пропущенных баров.
Алгоритм работает эффективно.
Как видим, после обрыва связи prev_calculated сбрасывается в ноль. Поэтому самый быстрый способ - пересчитать всю историю, чем запоминать прошлый prev_calculated, определять именно обрыв связи (ведь бары могут быть пропущены из-за редких тиков), восстанавливать текущее (нулевое после восстановления связи) значение prev_calculated из ранее запомненного и высчитывать количество пропущенных баров.
Алгоритм работает эффективно.
твой тест не полный -- ты пишешь "запоминать прошлый prev_calculated, определять именно обрыв связи" -- такую отработку не позволит сделать сам движок терминала.
prev_calculated сбрасывает в ноль движок терминала -- при отклонении rates_total в больше или меньше хотя больше чем на 1 бар от предыдущего -- движок терминала prev_calculated сбрасывает в ноль.
усложнил тест и добавил времязатратный расчёт -- чтобы выйти за пределы нескольких баров М1.
поведение движка терминала следующее -- он не перескакивает и не доливает бары -- он отрабатывает бар за баром без пропусков.
-- на картинке -- видно, что текущее время :48 -- а отрабатывает движок последовательно бар за баром и пока только :44 бар
т.е. движок терминала не отрабатывает актуальный текущий бар
вывод: корректней делать проверку не на if(limit>1) -- а на if(prev_calculate==0)
-- т.к. алгоритм должен делать естественную отработку состояний -- а не искривлять отработку состояний -- движок сам упростит те состояния, которые ему надо упростить
на картинке -- видно
Ладно. Такое пороговое состояние в стиле "индикатор работает, но один бар считает за пять минут и что же при этом делает движок терминала.., а если ещё и отвёрткой ковырнуть..." обсуждать уже не интересно. Кто-то говорил ещё о морганиях для клиентов.
Знаю, сейчас начнёшь о "чистоте экспериментов". Продолжай без меня. Ты никогда не признаёшь ничего за собой. Я, к сожалению, об этом забыл.