Обсуждение статьи "Скользящая средняя на MQL5 с нуля: Просто и доступно"

 

Опубликована статья Скользящая средняя на MQL5 с нуля: Просто и доступно:

На простых примерах разберём принципы расчётов скользящих средних, узнаем о способах оптимизации расчётов индикаторов и, соответственно — скользящих средних.

Мы рассмотрели принципы расчётов основных типов скользящих средних, доступных в настройках стандартного индикатора Moving Average в клиентском терминале. Представленные в статье расчёты можно использовать как в индикаторах с оптимизацией расчётов (что также показано в статье), так и использовать представленные коды как самостоятельный расчёт средних значений последовательного набора данных в своих программах.

На рисунке выше показана разница между одинаковыми по периоду расчёта (10) скользящими средними, но разными по типу:

Красная - SMA, зелёная - EMA, золотистая - SMMA, синяя - LWMA.

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

Автор: Artyom Trishkin

 

Спасибо за хорошую статью. Но всё-же не могу не покритиковать. Такое у меня сегодня настроение.

В статье особое внимание уделено не столько кодированию, сколько формуле и оптимизации вычислений. Но на мой взгляд начинающим программистам, да и недавно начавшим, полезней будет обратить внимание на возможность применения разных операторов цикла. Хочу надеяться, что в следующих статьях будет это отражено. Ведь в MQL5 как минимум 3 оператора цикла. И любой из них можно использовать для построения индикатора.

 

полезная информация, сразу в одном месте,

и наконец-то i++ цикл

 

Хорошая статья для начинающих, показывающая код, лежащий в основе стандартных 4 средних MQ.

Также следует обсудить важность простой оптимизации и ее влияние, поскольку 99 % тиков происходит между сменой баров. Минимизация вычислений между каждой сменой баров обеспечит гораздо более высокую эффективность ценой небольшой сложности. Таким образом, вычисление базовых значений один раз при смене бара и сохранение значений приведет к значительному сокращению времени вычислений. Например, для SAM стандартный расчет для N периодов составляет:

Рассмотрим

double sm=0;

for(int bar=0;bar<N;bar++) sum+=Close[CurrentBar-bar];

SMA=sum/N;


против

static double partialsum;

double sum=0;


На изменении бара{

partialsum=0;

for(int bar=0;bar<N-1;bar++) partialsum+=Close[CurrentBar-bar];

partialsum/=(N-1);

}

SMA =partialsum+Close[CurrentBar]/N;

Если в периоде бара 1000 тиков и N=10, то эта оптимизация экономит около 90 000 вычислений sum+=Close[EndingBar-bar] для каждого бара. Если ваш график содержит 1 000 баров, то экономия составит более 90 миллионов ненужных вычислений. На современных процессорах эта экономия, полученная в данном примере, тривиальна и, вероятно, не заметна, со временем она будет увеличиваться по мере усложнения ваших программ в советниках.

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

 

Спасибо за статью, но не понятно почему после использования функции OnCalculate() я больше не могу использовать транзакционную функцию OrderSend(), я не знаю как автор решил эту проблему, мне остается только использовать индикаторы из стандартной библиотеки следующим образом:

#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Indicators\Trend.mqh>
CiMA ma;

//+------------------------------------------------------------------+
//| Функция запуска программы сценария &nbsp Функция запуска программы сценария
//+------------------------------------------------------------------+
int OnInit(){ 
    ma.DeleteFromChart(ChartID(), 0);
    ma.Create(_Symbol, PERIOD_CURRENT, 14, 0, MODE_SMA, PRICE_CLOSE);
    ma.AddToChart(PERIOD_CURRENT, 0);
    
    return INIT_SUCCEEDED; 
}

void OnTick(){ 
    ma.Refresh();
    double curMA = ma.Main(0);
    
    //Print("Текущее значение MA:", maValue);
}