позабавило... и улыбнуло...
Ты на правильном пути, Mathemat, большие ученые не опускались до всякой прикладухи. :-)
А, вообще, красиво.
"Скрипт абсолютно бесполезен для торговли" ...большие ученые не опускались до всякой прикладухи. :-)
"Скрипт абсолютно бесполезен для торговли" ...большие ученые не опускались до всякой прикладухи. :-)
Так что ваш вывод о схожести EMA и SMMA можно считать ошибочным.
Кстати, путаница с описанием и реализацией еще имеет место быть в индикаторе ADX, поскольку упущен очень важный момент в том, что все сглаживания в этом индикаторе проводятся с помощью средней Вайлдера (Wilder), т.е. при помощи ЕМА с периодом 2*N-1. Именно по этой причине значения индикатора в МТ не совпадают со значениями в других торговых платформах при одинаковых периодах.
Ниже привожу индикатор с правильной реализацией алгоритма SMMA.
//+------------------------------------------------------------------+ //| Custom Moving Average_v1.mq4 | //| Copyright © 2004, MetaQuotes Software Corp. | //| https://www.metaquotes.net/ | //| Revised by Igorad, E-mail: igorad2003@yahoo.co.uk | //+------------------------------------------------------------------+ #property copyright "Copyright © 2004, MetaQuotes Software Corp." #property link "https://www.metaquotes.net/" #property indicator_chart_window #property indicator_buffers 1 #property indicator_color1 Red //---- indicator parameters extern int Price=0; extern int MA_Period=14; extern int MA_Shift=0; extern int MA_Method=2; //---- indicator buffers double ExtMapBuffer[]; //---- int ExtCountedBars=0; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { int draw_begin; string short_name; //---- drawing settings SetIndexStyle(0,DRAW_LINE); SetIndexShift(0,MA_Shift); IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)); if(MA_Period<2) MA_Period=13; draw_begin=MA_Period-1; //---- indicator short name switch(MA_Method) { case 1 : short_name="EMA("; draw_begin=0; break; case 2 : short_name="SMMA("; break; case 3 : short_name="LWMA("; break; default : MA_Method=0; short_name="SMA("; } IndicatorShortName(short_name+MA_Period+")"); SetIndexDrawBegin(0,draw_begin); //---- indicator buffers mapping SetIndexBuffer(0,ExtMapBuffer); //---- initialization done return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { if(Bars<=MA_Period) return(0); ExtCountedBars=IndicatorCounted(); //---- check for possible errors if (ExtCountedBars<0) return(-1); //---- last counted bar will be recounted if (ExtCountedBars>0) ExtCountedBars--; //---- switch(MA_Method) { case 0 : sma(); break; case 1 : ema(); break; case 2 : smma(); break; case 3 : lwma(); } //---- done return(0); } //+------------------------------------------------------------------+ //| Simple Moving Average | //+------------------------------------------------------------------+ void sma() { double sum=0; int i,pos=Bars-ExtCountedBars-1; //---- initial accumulation if(pos<MA_Period) pos=MA_Period; for(i=1;i<MA_Period;i++,pos--) sum+=iMA(NULL,0,1,0,0,Price,pos); //---- main calculation loop while(pos>=0) { sum+=iMA(NULL,0,1,0,0,Price,pos); ExtMapBuffer[pos]=sum/MA_Period; sum-=iMA(NULL,0,1,0,0,Price,pos+MA_Period-1); pos--; } //---- zero initial bars if(ExtCountedBars<1) for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0; } //+------------------------------------------------------------------+ //| Exponential Moving Average | //+------------------------------------------------------------------+ void ema() { double pr=2.0/(MA_Period+1); int pos=Bars-2; if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1; //---- main calculation loop while(pos>=0) { if(pos==Bars-2) ExtMapBuffer[pos+1]=iMA(NULL,0,1,0,0,Price,pos+1); ExtMapBuffer[pos]=iMA(NULL,0,1,0,0,Price,pos)*pr+ExtMapBuffer[pos+1]*(1-pr); pos--; } } //+------------------------------------------------------------------+ //| Smoothed Moving Average | //+------------------------------------------------------------------+ void smma() { double sum=0; int i,k,pos=Bars-ExtCountedBars+1; //---- main calculation loop pos=Bars-MA_Period; if(pos>Bars-ExtCountedBars) pos=Bars-ExtCountedBars; while(pos>=0) { if(pos==Bars-MA_Period) { //---- initial accumulation sum=0; for(i=0;i<MA_Period;i++) sum+=iMA(NULL,0,1,0,0,Price,pos+i); ExtMapBuffer[pos]=sum/MA_Period; } else { sum=0; for(i=0;i<MA_Period;i++) sum+=iMA(NULL,0,1,0,0,Price,pos+i+1); ExtMapBuffer[pos]=(sum - ExtMapBuffer[pos+1] + iMA(NULL,0,1,0,0,Price,pos))/MA_Period; } pos--; } } //+------------------------------------------------------------------+ //| Linear Weighted Moving Average | //+------------------------------------------------------------------+ void lwma() { double sum=0.0,lsum=0.0; double price; int i,weight=0,pos=Bars-ExtCountedBars-1; //---- initial accumulation if(pos<MA_Period) pos=MA_Period; for(i=1;i<=MA_Period;i++,pos--) { price=iMA(NULL,0,1,0,0,Price,pos); sum+=price*i; lsum+=price; weight+=i; } //---- main calculation loop pos++; i=pos+MA_Period; while(pos>=0) { ExtMapBuffer[pos]=sum/weight; if(pos==0) break; pos--; i--; price=iMA(NULL,0,1,0,0,Price,pos); sum=sum-lsum+price*MA_Period; lsum-=iMA(NULL,0,1,0,0,Price,i); lsum+=price; } //---- zero initial bars if(ExtCountedBars<1) for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0; } //+------------------------------------------------------------------+При этом RSI, в теории использующее такое же сглаживание Вайлдера, в МТ реализовано правильно.
Все бы хорошо, но смею заметить, что алгоритм расчета SMMA неверный. Описание алгоритма в документации приведено верное, а расчет сам в индикаторе проделан неверно. SMMA в теории больше напоминает слегка сглаженную SMA, поскольку в расчетах отталкивается от себя самой на предыдущем баре.
Так что ваш вывод о схожести EMA и SMMA можно считать ошибочным.
igorad, говоря откровенно, я не особенно внимательно смотрел на реализацию алгоритма SMMA в кастомном индюкаторе Moving Average. Я ориентировался только на его описание на сайте, вот здесь: https://www.metatrader5.com/ru/terminal/help/indicators/trend_indicators/ma , и полагался на его верность.
Свой вывод могу строго аргументировать с помощью простой арифметики и не считаю ошибочным. Особо хочу подчеркнуть, что это не схожесть, а полная идентичность. Разница обусловлена только разными инициализациями, и, как и полагается для фильтров этого вида, стремится к нулю при стремлении начального индекса скользящего окна к бесконечности.
P.S. Математическое доказательство готов привести, как только ты его потребуешь. Оно совсем простое. Можешь убедиться в этом самостоятельно, расписав формулы, приведенные по ссылке выше.
формула средней Вайлдера: MA = MA[1] + 1/N*(P - MA[1])
после преобразований получаем MA = (MA[1]*(N-1) +P)/N
А вот строки из кода, которые отвечают за это:
else sum=ExtMapBuffer[pos+1]*(MA_Period-1)+Close[pos]; ExtMapBuffer[pos]=sum/MA_Period;Поэтому вы и получили полное совпадение ЕМА с периодом 2*N-1 и так называемой SMMA, поскольку
коэффициент 1/N можно преобразовать к виду 2/((2*N-1)+1).
1. Ты сам же говоришь, что описание алгоритма в документации - верное. А я говорю, что именно из этого алгоритма (по формулам, а не по коду, реализованному в МТ) я вывел тождество рекуррентных формул для EMA(2N-1) и SMMA(N). Только вот в формуле
SMMA (i) = (SUM1 - SMMA (i - 1) + CLOSE (i)) / Nесть неточность: надо в общем виде заменить SUM1 на SUM(i - 1), что косвенно подтверждается нижеприведенными пояснениями. Тогда дальше все очевидно:
Теперь ясно, что при правильном подборе N наша формула идентична рекуррентной для EMA с некоторым периодом.SMMA (i) = (SUM (i - 1) - SMMA (i - 1) + CLOSE (i)) / N = = ( (N - 1) * SMMA (i - 1) + CLOSE (i)) / N = = (1 - 1/N) * SMMA (i - 1) + 1/N * CLOSE (i)
2. Только что ты доказал то же самое, но уже теперь исходя из метаквотовского кода.
3. Тем не менее ты настаиваешь на том, что твоя ревизия SMMA - единственно верная. Я наложил на чарт твой индюкатор с теми же значениями периодов, т.е. SMMA(80) и EMA(159), и они очень сильно отличаются друг от друга.
4. Вот еще: https://www.mql5.com/en/forum/46462 . Ты согласен с такой формулой?
Так где же истина? Где ты брал единственно верное определение SMMA?
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
EMA и SMMA идентичны:
Этот крошечный скрипт наглядно демонстрирует идентичность двух распространенных мувингов
Author: Sceptic Philozoff