MT4 iMAOnArray и iBandsOnArray влияние количества элементов на расчёты - страница 6

 

Я не зря предложил тебе калькулятор или Excell. Это помогает понять как работает эта херня. Использовать количество элементов для расчёта отличное от нуля возможно только имея уже готовый массив. Допустим есть массив 1000 элементов, а надо среднюю посчитать только для 100 последних элементов. И тут возникает два варианта, скоприровать эти 100 элементов в пользовательский массив и по нему пересчитать или используя цикл от 100 до 0 использовать тот, готовый массив и количество элементов ставить уже не 0, а 100.

Но тут возникает проблема с изменением размера массива, что неизбежно в индикаторах...

И опять-же я говорил о других способах ограничить количество элементов для расчёта. Ну поставь условие считать iMAOnArray() только if(rates_total-i >= rates_total-100); и будут пересчитаны только последние 100 баров и при поступлении нового бара всё будет нормально.

int i, limit;
   limit = prev_calculated == 0 ? rates_total-1 : rates_total-prev_calculated;

   for(i = limit; i >= 0; i--)
     {
      Buffer[i]=open[i];
      if(rates_total-i >= rates_total-100)
      BufferMA[i] = NormalizeDouble(iMAOnArray(Buffer, 0, 5, 0, MODE_LWMA, i), _Digits);
      
     }

return(rates_total);


 
Alexey Viktorov:

Я не зря предложил тебе калькулятор или Excell. Это помогает понять как работает эта херня. Использовать количество элементов для расчёта отличное от нуля возможно только имея уже готовый массив. Допустим есть массив 1000 элементов, а надо среднюю посчитать только для 100 последних элементов. И тут возникает два варианта, скоприровать эти 100 элементов в пользовательский массив и по нему пересчитать или используя цикл от 100 до 0 использовать тот, готовый массив и количество элементов ставить уже не 0, а 100.

Но тут возникает проблема с изменением размера массива, что неизбежно в индикаторах...

И опять-же я говорил о других способах ограничить количество элементов для расчёта. Ну поставь условие считать iMAOnArray() только if(rates_total-prev_calculated-i >= 100); и будут пересчитаны только последние 100 баров и при поступлении нового бара всё будет нормально.


Скажите вы программист или занимаетесь этим как хобби, ну или по необходимости? Мне не нужен excel или лист бумаги, чтобы понимать как это работает, да и Барабашка продемонстрировал все "трудности" на скрине ранее. Давайте по порядку.

1. iMAOnArray (как и iBandsOnArray) может работать в двух вариантах, считать весь массив и делать это правильно (но имеет тормоза при первичном расчёте) или считать часть массива, но делать это только для начальных элементов не смотря на то, что смещение задаётся для конечных. То есть как бы я не пытался ограничить расчёт барами мне всё равно нужно посчитать или весь массив (то есть исходный вариант "торможения"), или придумывать вариант похожий на ваш с копированием буфера и перерасчёта всех элементов этого буфера, что, как описано в моих сообщениях ранее, не даёт правильного результата для сложных методов сглаживания и кроме этого в общем итоге увеличивает время обработки данных.

2. Описанная вами проблема в индикаторах с изменением размера массива возникает лишь в том случае, если массив не является одним из буферов индикатора, то есть описанные вами "танцы с бубном" тоже имеют в итоге отрицательный эффект, т.к. возвращаясь к первичному исходному коду проблема была только лишь в медленном расчёте и только на первом этапе.

3. Предложенный вами вариант с пересчётом только части массивов по 100 (N) баров, даёт опять-таки потерю общей производительности и ненужные заморочки реализации с копированием массивов или ненужный пересчёт. Кроме того на вашем скрине и в коде выше все расчёты произведены (подозреваю где-то во внутреннем массиве, скорее всего из-за этого и возникают первичные тормоза), в противном случае при данном виде сглаживания первые заполненные результаты бы отличались, а вы просто не заполнили ими массив буфера. Потому как 0 в параметре размера массива для расчёта функции явно указывает ей, что нужно считать все данные, в этом и загвоздка.

Итог вижу только один - использовать свою функцию, которая будет работать именно как должна и позволит не перерасчитывать все данные (их N-ную часть) с приходом нового бара, а считать только лишь его, тем более, что такая функция усреднения у меня есть и используется во многих моих продуктах. Вопрос этой темы форума был, как можно "победить" именно штатные функции МТ4, при этом не ухудшая скорость обработки и результат. Написать аналогичную функцию и для лент боллинджера будет решением второй задачи, т.к. средняя линия - по сути скользящая, а для неё уже есть функция, ну и если верить сообщению выше, то "стандартное отклонение" на массив рассчитывается без тормозов, или как запасной вариант написать свой расчёт отклонения, тем более что формулы расчёта доступны всем здесь в документации.

 

Так много буковок... И всё направлено исключительно на несогласие с предложенным вариантом.

Спасибо за идею, я хоть разобрался как это работает, а-то за ненадобностью и не вникал в тонкости этих функций.

Не нравится пользуйся самописными.

 
Alexey Viktorov:

Так много буковок... И всё направлено исключительно на несогласие с предложенным вариантом.

Спасибо за идею, я хоть разобрался как это работает, а-то за ненадобностью и не вникал в тонкости этих функций.

Не нравится пользуйся самописными.

Ну почему на несогласие, на объяснение, почему так не стоит делать, т.к. написать код привязанный к тормозящим функциям или код создающий дополнительные циклы копирования - это не всегда правильный вариант, хотя, иногда, и менее трудоёмкий :)
И дело тут не в "нравится"/"не нравится", а в том, что функции работают не совсем, как нужно, ведь по сути создание аналогов - это как изобретение велосипеда, но в данном конкретном варианте без этого обойтись не получается.

Для себя выводы я сделал несколько страниц назад, но ваш путь, возможно поможет кому-то понять, что данная ситуация тут уже разбиралась, и что нужно делать, чтобы решить эту задачу , потому и так много буковок :)

 

В последнем варианте никакого копирования или дополнительных циклов нет. И метод расчёта MODE_LWMA о невозможности правильного пересчёта которого вы с Дмитрием говорили раньше.

Посмотри на код и скрин. На скрине МА период 5 как и в коде, по open, метод MODE_LWMA и обрати внимание на количество посчитанных баров, на совпадение значений индикатора МА и индикатора с функцией iMAOnArray() в подвале. Пересчитать все бары или пересчитать только 100 штук затраты по времени существенно отличаются. Если изменений не будет значит тормоза в других вычислениях.

 
Полный абзац!
 
Sergey Efimenko:

Скажите вы программист или занимаетесь этим как хобби, ну или по необходимости?...

Раньше, он сам начинал верещать, что он не программист, а любитель и поэтому ему можно загонять.
 
Alexey Viktorov:

В последнем варианте никакого копирования или дополнительных циклов нет. И метод расчёта MODE_LWMA о невозможности правильного пересчёта которого вы с Дмитрием говорили раньше.

Посмотри на код и скрин. На скрине МА период 5 как и в коде, по open, метод MODE_LWMA и обрати внимание на количество посчитанных баров, на совпадение значений индикатора МА и индикатора с функцией iMAOnArray() в подвале. Пересчитать все бары или пересчитать только 100 штук затраты по времени существенно отличаются. Если изменений не будет значит тормоза в других вычислениях.

Последний вариант по сути ничем не отличается от оригинала. Как уже писал при размере массива 0, он всё равно считается целиком. Первым же моим решением по уменьшению времени расчёта, ещё до создания темы на форуме, как это обычно и делают для оптимизации в советнике, где не нужен расчёт всех значений, был именно такой вариант, ограничить число баров, но на производительность, к сожалению, это никак не повлияло, потом я стал экспериментировать с длинной массива для iMAOnArray и тут-то и понял всю сложность ситуации. Вот тогда и только тогда, перепробовав практически все простые варианты, в том числе и со сменой индексации массивов для разных комбинаций, я создал эту тему. Ну а потом, пошли ответы, некоторые из них подтверждали, что у других также были попытки и все приходили к созданию своей функции. Поэтому я и спросил у вас код, изначально зная, что получится :) Без обид :) Может быть кто-то из пользователей перешагнёт эти "грабли" почитав эту тему. :)
 
Dmitry Fedoseev:
Раньше, он сам начинал верещать, что он не программист, а любитель и поэтому ему можно загонять.

Это скорее был риторический вопрос :)

PS Господа, давайте будем терпимее друг к другу. В конечном итоге мы ведь все тут собрались с одной целью - "обуть" рынок. :) Так и давайте идти к этой цели не отвлекаясь. У каждого из нас есть свои сложности, и особенности восприятия, но только в спорах рождаются истины, хотя как говаривал вроде бы Наполеон: "Спорить, зная, что ты не прав - глупо, спорить, зная, что ты прав подло. Поэтому я никогда не спорю."

 
Sergey Efimenko:
Последний вариант по сути ничем не отличается от оригинала. Как уже писал при размере массива 0, он всё равно считается целиком. Первым же моим решением по уменьшению времени расчёта, ещё до создания темы на форуме, как это обычно и делают для оптимизации в советнике, где не нужен расчёт всех значений, был именно такой вариант, ограничить число баров, но на производительность, к сожалению, это никак не повлияло, потом я стал экспериментировать с длинной массива для iMAOnArray и тут-то и понял всю сложность ситуации. Вот тогда и только тогда, перепробовав практически все простые варианты, в том числе и со сменой индексации массивов для разных комбинаций, я создал эту тему. Ну а потом, пошли ответы, некоторые из них подтверждали, что у других также были попытки и все приходили к созданию своей функции. Поэтому я и спросил у вас код, изначально зная, что получится :) Без обид :) Может быть кто-то из пользователей перешагнёт эти "грабли" почитав эту тему. :)

Ты хочешь сказать что после if(rates_total-i >= rates_total-100);, когда осталось только 100 баров для расчёта функция iMAOnArray() сначала пересчитывает ВЕСЬ массив?

Причина обращения: