Алгоритм работы EMA и SMMA

 

Всем привет!

Прошу помочь мне найти ошибку.

Необходим алгоритм расчета EMA.

int start()
{
  int iPeriod = 5;
  Print("iMA (ema) = \'"+DoubleToStr(NormalizeDouble(iMA(NULL, 0, iPeriod, 0, MODE_EMA, 0, 0), Digits), Digits)+
        "\', GetEMA = \'"+DoubleToStr(NormalizeDouble(GetEMA(iPeriod), Digits), Digits)+"\'.");
}

double GetEMA(int iPeriod)
{
  double dResult = 0.0;
  if (iPeriod) {
    double k = 2.0 / (iPeriod + 1);
    int iPos = iPeriod - 1;
    dResult = iClose(NULL, 0, iPos);
    
    iPos--;
    while (iPos >= 0) {
      dResult = iClose(NULL, 0, iPos)*k + dResult*(1-k);
      iPos--;
    }
  }
  return (dResult);
}

Если данный код прогнать на тайм-фрейме в месяц, видны расхождения.

Поясните, что я не так сделал.


Также буду очень благодарен за алгоритм вычисления SMMA.

Спасибо!


P.S. В исходниках терминала смотрел, не разобрался, чего я неправильно интерпретировал.

 
Для расчета ЕМА нужно баров раз в 10 больше, чем период МА. SMMA это МА Wilders'а - идентична EMA с периодом Period*2-1
 

Вот тут еще скриптик, демонстрирующий идентичность ЕМА и SMMA с соответствующими параметрами.

 

Mathemat, Integer

Спасибо за ответы!

"...демонстрирующий идентичность ЕМА и SMMA..."

Расчитывать SMMA не буду.

Integer

Не смогли бы вы пояснить мысль относительно количества баров? Желательно, в примере алгоритма?

 

Цитата из "Статьи по MQL4": "Построение средней (окончание).":

Часто бывают индикаторы, когда текущее значение индикатора зависит от предыдущего значения и текущей цены. Можно записать этот так: F[i]=F[i+1]*a+Price[i]*b, где a и b - коэффициенты, обычно меньше 1. Иногда требуют, чтобы a+b=1. Тогда F[i]=F[i+1]*(1-b)+Price[i]*b . Чем меньше коэффициент b, тем меньше реагирует индикатор на изменение цен и больше зависит от предыдущего значения индикатора. Для экспоненциальной скользящей средней(ЭСС) коэффициент b=2/(1+PeriodMA).

Далее:

В самом начале, когда мы рассчитываем индикатор в первый раз, у нас нет предыдущего значения индикатора. Нам негде взять предыдущее значение и нам придется делать какое-то допущение. Первый вариант – принять соглашение, что для бара с индексом Bars-1 значение индикатора равно значению цены на этом баре (High, Open, Close или другая ценовая константа, например, {High+Low+Close}/3.0 ), а дальше рассчитывать по алгоритму.

Следом:

Первый вариант реализован в пользовательском индикаторе Moving Averages.mq4, который идет в составе дистрибутива MetaTrader4 и находится в папке MetaTrader 4expertssamplesindicators .

Я не могу понять, что делаю не так? Приведенный мной алгоритм в точности соответствует принципу вычисления.

Почему в таком случае функция iMA с аналогичными параметрами выдает отличное от моего значение?

Либо я допустил ошибку, либо функция iMA работает нестандартному алгоритму.

Профи, пожалуйста, откликнетесь! Написание МТС приостановлено до решение этого вопроса.

 
voix_kas >>:

EMA можно представить, как нерекурсивный фильтр.


EMA5=0.333333333*Close[0] // 2*((n-1)^i)/((n+1)^(i+1)) n-период ма, i-бар
+0.222222222*Close[1]
+0.148148148*Close[2]
+0.098765432*Close[3]
+0.065843621*Close[4]
+0.043895748*Close[5]
+0.029263832*Close[6]
+0.019509221*Close[7]
+0.013006147*Close[8]
+0.008670765*Close[9]
+0.00578051*Close[10]
+0.003853673*Close[11]
+0.002569116*Close[12]
+0.001712744*Close[13]
+0.001141829*Close[14]
+0.000761219*Close[15]
+0.00050748*Close[16]
+0.00033832*Close[17]
+0.000225546*Close[18]
+0.000150364*Close[19]
+0.000100243*Close[20]
и т.д.

iPeriod баров явно не достаточно для расчета.

 

Swan

Либо я вас не понял, либо наоборот.

Попробую уточнить свой вопрос.

Имеется встроенная функция iMA().

Среди прочих параметров ей передается значение периода. Например, 14.

Результатом функции является некоторое усредненное значение.

Уважаемый Rosh в этой теме дал ссылку с описанием алгоритма расчета EMA.

Выдержки из статьи, а также исправленную ссылку на нее приведены выше.

Так вот, из нее следует, что:

при указании функции iMA периода, скажем, 14, усредненное значение расчитывается на основании именно 14-ти баров.

Воспроизведенной мной алгоритм показывает, что результирующие значения отличаются (в сравнении с iMA).

Собственно, у меня вопрос к общественности: что является правдой:

1. Либо алгоритм расчета, приведенный в статье, отличен от существующей функции iMA() (хотя, справедливости ради, надо отметить, что в статье (на официальном сайте Альпари) явное указание на соответствие с оной в МТ4).

2. Либо я некорректно воспроизвел алгоритм (код приложен выше).

Спасибо!

 
P.S. Если алгоритм отличен, к чему я склоняюсь, хотелось бы увидеть код оригинала (на алгоритм расчета инидкатора, пожалуйста, не ссылайтесь).
 
voix_kas >>:

Собственно, у меня вопрос к общественности: что является правдой:

{...}

Рецепт

.

1. Берете индикатор машек из метатрейдера

MetaTrader\experts\indicators\Moving Averages.mq4

и тупо кидаете на график рядом со встроенной машкой МТ.

смотрите что они одинаковые...

2. Лезете внутрь кода и ограничиваете кол-во баров,

на котором рассчитывается индикатор, скажем, тысячей...

Опять кидаете на график.

И бежите смотреть на 1000-й бар - там между встроенной 

и вашей машками действительно будут различия.

На глазок можете даже прикинуть, где отличия заканчиваются.

.

Если не на глазок - берете дельту МаСтандартная - МаСОграниченнымКолвомБаров

и смотрите чтобы она было либо 0 либо меньше, например, 0 . 000 000 000 1

 
voix_kas >>:

Выдержки из статьи, а также исправленную ссылку на нее приведены выше.

Так вот, из нее следует, что:

при указании функции iMA периода, скажем, 14, усредненное значение расчитывается на основании именно 14-ти баров.

Нет, не 14, это неверный вывод. 14 - это только основа для вычисления b, а также некий якорь для идентификации простой машки (SMA), аналогичной экспоненциальной, через формулу, связывающую b и 14. Но число используемых баров все равно бесконечно, т.к. формула рекуррентна. Посмотрите на стандартный алгоритм в комплекте терминала повнимательней.

 

jartmailru

Индикатор iMA(EMA) всегда считает от первого бара в истории (не превышая настройки "максимум баров на графике").

Функция iMA(EMA) считает от запрашиваемого бара.

Таким образом, равные значения у них будут только на самом первом* баре истории (* - с учетом периода).

На последующих барах (более поздних) у функции не будет вычисленного предыдушего элемента, и, в соответствии со "стандартом", она возьмет "тупо" цену этого бара (close, high,...).

"Природа" различия между значениями функции и индикатора мне понятна.

Я же говорю о другом.

Различие между значениями функции iMA и алгоритмом, код которого привел выше.

По идее, они должны давать одинаковые значения.

Если не понял вашей мысли, прошу извинить и попытаться донести мне ее другими словами. :)

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