English 中文 Español Deutsch 日本語 Português
preview
Тестируем информативность разных типов скользящих средних

Тестируем информативность разных типов скользящих средних

MetaTrader 5Тестер | 7 декабря 2023, 11:49
1 142 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Введение

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

Для целей этой статьи мы создадим простое приложение для тестирования скользящих средних во встроенном тестере стратегий MetaTrader 5. Чтобы понять, на что нужно обратить внимание при изучении результатов тестирования, прочтите мою предыдущую статью "Понимание и эффективное использование тестера стратегий MQL5". В ней можно найти много полезного.

Мы рассмотрим следующие темы:

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

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

Тестирование системы на основе простой скользящей средней (SMA)

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

Для совершения торговых операций мы будем использовать следующие сигналы:


Сигнал на покупку:

Цена закрытия выше значения простой скользящей средней.

А также: предыдущая цена закрытия ниже предыдущего значения простой скользящей средней.

Сигнал на продажу:

Цена закрытия ниже значения простой скользящей средней.

А также: предыдущая цена закрытия выше предыдущего значения простой скользящей средней.

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

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

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

#include <Trade\Trade.mqh>

Создадим три пользовательских ввода для двойной переменной lotSize, переменной ENUM_TIMEFRAMES timeFrame и целочисленной переменной MAPeriod, которые будут изменены по желанию пользователя, установив для них значения по умолчанию:

input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;

Создайте две целочисленные переменные simpleMA и barTotal без присвоения, поскольку мы определим их позже в части OnInit().

int simpleMA;
int barsTotal;

Создадим trade как объект класса CTrade для быстрого доступа к торговым функциям.

CTrade trade;

В OnInit() определим simpleMA, используя функцию iMA, чтобы вернуть хэндл индикатора скользящей средней, и его параметры:

  • symbol - имя символа; для текущего символа - _Symbol
  • period - используемый таймфрейм. По умолчанию - 1 час
  • ma_period - период простого скользящего среднего. По умолчанию - 50
  • ma_shift - для сдвига по горизонтали используем 0 
  • applied_price - тип цены; для расчета простой скользящей средней используется цена закрытия.
simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);

И barsTotal с помощью функции iBars для возврата количества баров. Ее параметры:

  • symbol - символ. Текущий символ - (_Symbol)
  • timeframe - используемый таймфрейм. По умолчанию - 1 час
   barsTotal=iBars(_Symbol,timeFrame);

В OnTick() создадим два массива: один - для цен с использованием MqlRates для хранения информации о ценах, объемах и спреде, а другой — для простой скользящей средней:

   MqlRates priceArray[];
   double mySMAArray[];

Если установить флаг AS_SERIES для этих двух созданных массивов с помощью функции ArraySetAsSeries, его параметры будут следующими:

  • array[] - указать массив по ссылке
  • flag - указать направление индексации массива
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

Определение цен Ask и Bid после создания из них двух двойных переменных

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

Получаем исторические данные MqlRates с помощью функции CopyRates. Ее параметры:

  • symbol_name - имя символа
  • timeframe - таймфрейм
  • start_pos - начальная позиция
  • count - количество данных для копирования
  • rates_array[] - целевой массив для копирования
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

Получаем данных индикаторного буфера с помощью функции CopyBuffer. Ее параметры:

  • indicator_handle - хэндл индикатора, здесь - simpleMA
  • buffer_num - номер буфера индикатора, равен 0
  • start_pos - позиция начала расчета, 0 - текущая свеча
  • count - копируемый объем, равен 3
  • buffer[]: целевой массив, который нам нужно скопировать, то есть mySMAArray
CopyBuffer(simpleMA,0,0,3,mySMAArray);

Определим последнюю цену закрытия и значение простой скользящей средней той же свечи после создания двух двойных переменных этих двух значений.

   double lastClose=(priceArray[1].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);

Определим предыдущую цену закрытия и значение простой скользящей средней той же свечи после создания двух двойных переменных этих двух значений

   double prevClose=(priceArray[2].close);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

Создадим целочисленную переменную bars для сравнения с созданной переменной barsTotal

int bars=iBars(_Symbol,timeFrame);

Проверяем наличие нового бара путем проверки значения barsTotal, если он не равен bars.

if(barsTotal != bars)

Если значение barsTotal не равно bars, нам необходимо обновить значение BarsTotal, указав значение bars.

barsTotal=bars;

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

      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }

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

      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }

Затем мы скомпилируем код и увидим, что он скомпилирован без ошибок и предупреждений.

Ниже приведен весь код в одном блоке:

//+------------------------------------------------------------------+
//|                                                   SMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int simpleMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

Скомпилируем советник и запустим его на EURUSD, чтобы протестировать стратегию на истории. Период тестирования — с 1 января по 30 июня 2022 года, как и для всех упомянутых типов скользящих средних. Наши настройки для SMA будут следующими:

  • Размер лота: 1
  • Таймфрейм: 1 час
  • Период MA: 50

Результаты теста:

Результаты SMA

Нас особенно интересуют следующие показатели:

  • Чистая прибыль: 2700.30 (27%)
  • Относительная просадка по балансу: 37.07%
  • Относительная просадка по средствам: 41.76%
  • Профит-фактор: 1.10
  • Матожидание выигрыша: 12.68
  • Фактор восстановления: 0.45
  • Коэффициент Шарпа: 0.57

Адаптивная скользящая средняя (iAMA)

Адаптивная скользящая средняя (iAMA, а также KAMA) была разработана Перри Кауфманом. Основная идея заключается в уменьшении шума при движении цены. Она следует за движением цены, независимо от ее волатильности, и приспосабливается к нему. Это трендовый индикатор, поэтому его можно использовать для определения тренда и точек разворота.

Индикатор рассчитывается в несколько шагов.

Шаг первый: Расчет AMA или KAMA

Шаг 1

Шаг второй: Расчет коэффициента сглаживания (SC)

Шаг 2

Шаг третий: расчет коэффициента эффективности (ER)

Шаг 3

Теперь мы научились рассчитывать индикатор AMA вручную, но нам это не нужно, поскольку мы можем автоматически вставить его в MetaTrader 5, выбрав его из доступных готовых индикаторов. Пришло время создать торговую систему, которая сможет исполнять ордера на покупку и продажу на основе пересечения цены закрытия и индикатора AMA. Мы будем использовать следующие сигналы для нашей стратегии.

Сигнал на покупку:

Цена закрытия выше адаптивной скользящей средней.

А также: предыдущая цена закрытия ниже предыдущего значения адаптивной скользящей средней

Сигнал на продажу:

Цена закрытия ниже значения адаптивной скользящей средней.

А также: предыдущая цена закрытия выше предыдущего значения адаптивной скользящей средней

Ниже приведен полный код для создания этого типа торговой системы:

//+------------------------------------------------------------------+
//|                                                  iAMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
input int fastMAPeriod= 5;
input int slowMAPeriod= 100;
int adaptiveMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   adaptiveMA = iAMA(_Symbol, timeFrame, MAPeriod,fastMAPeriod,slowMAPeriod, 0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myAMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myAMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(adaptiveMA,0,0,3,myAMAArray);
   double lastClose=(priceArray[1].close);
   double AMAVal = NormalizeDouble(myAMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevAMAVal = NormalizeDouble(myAMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>AMAVal && prevClose<prevAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<AMAVal && prevClose>prevAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

Отличие этого кода заключается в использовании функции iAMA, которая возвращает хэндл индикатора адаптивного скользящего среднего. Его параметры:

  • symbol - имя символа; для текущего символа - _Symbol
  • period - используемый таймфрейм. По умолчанию - 1 час
  • ama_period - период адаптивной скользящей средней
  • fast_ma_period - период быстрой скользящей средней
  • slow_ma_period - период медленной скользящей средней
  • ama_shift - для сдвига по горизонтали используем 0
  • applied_price - тип цены, используемой для расчета; используем цену закрытия

Протестируем индикатор AMA на том же периоде, чтобы увидеть его результаты:

  • Размер лота =1
  • Таймфрейм = 1 час
  • MAperiod = 50
  • Быстрая MA = 5
  • Медленная MA = 100

Результаты:

Результаты АМА

Нас особенно интересуют следующие показатели:

  • Чистая прибыль: 3638.20 (36.39%)
  • Относительная просадка по балансу: 22.48%
  • Относительная просадка по средствам: 35.53%
  • Профит-фактор: 1.31
  • Матожидание выигрыша: 35.67
  • Фактор восстановления: 0.65
  • Коэффициент Шарпа: 0.86

Двойная экспоненциальная скользящая средняя (iDEMA)

Эта разновидность скользящей средней была разработана Патриком Маллоем. Основная цель этого индикатора — уменьшить отставание EMA, но сделать ее более чувствительной к движению рынка.

Этот индикатор можно использовать для определения тренда или поворотных точек тренда путем определения положения цен относительно этого скользящего среднего. Шаги расчета индикатора показаны ниже:

1. Расчет первой экспоненциальной скользящей средней (EMA)

EMA one = EMA n-го периода цены.

2. Расчет EMA из EMA one

EMA two = EMA из EMA one

3. Расчет DEMA

DEMA = (2 * EMA one) - EMA two

Нам не нужно выполнять эти расчеты вручную. Они нужны для лучшего понимания индикатора, но у нас этот индикатор такой же, как и у многих технических индикаторов в MetaTrader 5. Теперь нам нужно создать ту же торговую систему, которую мы создали ранее, но уже с использованием DEMA. Эта торговая система будет исполнять те же самые ордера на покупку и продажу на основе пересечения, но на этот раз это будет пересечение цены и индикатора DEMA.

Сигнал на покупку:

Цена закрытия выше значения двойной экспоненциальной скользящей средней

А также: предыдущая цена закрытия ниже предыдущего значения DEMA

Сигнал на продажу:

Цена закрытия ниже значения DEMA.

А также: предыдущая цена закрытия выше предыдущего значения DEMA

Ниже приведен полный код торговой системы с небольшой разницей в использовании функции iDEMA для возврата хэндла индикатора двойной экспоненциальной скользящей средней. Ее параметры:

  • symbol - имя символа; для текущего символа - (_Symbol)
  • period - используемый таймфрейм. По умолчанию - 1 час
  • ma_period - период усреднения скользящей средней. Значение по умолчанию - 50
  • ma_shift - укажем 0 для горизонтального сдвига, поскольку он не требуется
  • applied_price - тип цены; для расчета скользящей средней используется цена закрытия

Код представлен ниже:

//+------------------------------------------------------------------+
//|                                                 iDEMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int DEMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   DEMA = iDEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myDEMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myDEMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(DEMA,0,0,3,myDEMAArray);
   double lastClose=(priceArray[1].close);
   double DEMAVal = NormalizeDouble(myDEMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevDEMAVal = NormalizeDouble(myDEMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>DEMAVal && prevClose<prevDEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<DEMAVal && prevClose>prevDEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

После компиляции протестируем код на том же периоде, что и предыдущие. Настройки индикатора будут следующими:

  • Размер лота = 1
  • Таймфрейм = 1 час
  • Период MA = 50

После запуска теста получаем следующие результаты:

Результаты DEMA

Нас особенно интересуют следующие показатели:

  • Чистая прибыль: - 961.60 (- 9.62%)
  • Относительная просадка по балансу: 39.62%
  • Относительная просадка по средствам: 41.15%
  • Профит-фактор: 0.97
  • Матожидание выигрыша: - 3.12
  • Фактор восстановления: - 0.18
  • Коэффициент Шарпа: - 0.21

Тройная экспоненциальная скользящая средняя (iTEMA)

Этот тип скользящей средней был разработан Патриком Маллоем, чтобы сделать индикатор более чувствительным и подходящим для краткосрочной торговли. В индикаторе используются экспоненциальные скользящие средние с тройным, двойным и одинарным сглаживанием. Таким образом, этот индикатор будет ближе к цене, что сделает его более чувствительным. Так же, как мы использовали двойную экспоненциальную скользящую среднюю, мы можем применять TEMA таким же образом, в дополнение к ее более быстрой реакции на цену. Дополнительно ее можно использовать для определения тренда и поворотных точек или изменений тренда.

Ниже приведены шаги для расчета индикатора TEMA:

1. Расчет первой экспоненциальной скользящей средней (EMA)

EMA one = EMA n-го периода цены.

2. Расчет EMA из EMA one

EMA two = EMA из EMA one

3. Расчет EMA из EMA два

EMA three = EMA из EMA two

4. Расчет ТЕМА

DEMA = (3 * EMA one) - (3 * EMA two) + (EMA3)

Мы можем вставить этот индикатор из имеющихся готовых технических индикаторов в MetaTrader 5 без расчета вручную, после чего нам нужно создать нашу торговую систему с использованием этого индикатора TEMA, чтобы протестировать ее и сравнить ее результаты с другими типами. Ниже приведен полный код для создания этой торговой системы. Он похож на предыдущие с той разницей, что используется функция iTEMA для возврата хэндла индикатора Triple Exponential Moving Average, а ее параметры такие же, как мы упоминали в DEMA и SMA.

//+------------------------------------------------------------------+
//|                                                 iTEMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int TEMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   TEMA = iTEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myTEMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myTEMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(TEMA,0,0,3,myTEMAArray);
   double lastClose=(priceArray[1].close);
   double TEMAVal = NormalizeDouble(myTEMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevTEMAVal = NormalizeDouble(myTEMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>TEMAVal && prevClose<prevTEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<TEMAVal && prevClose>prevTEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

После компиляции и запуска этого программного обеспечения мы можем протестировать тот же период, чтобы сравнить его результаты с другими типами скользящих средних, а ниже приведены настройки или входные данные, которые будут использоваться, чтобы попытаться зафиксировать все параметры в этом процессе тестирования:

  • Размер лота = 1
  • Таймфрейм = 1 час
  • Период MA = 50

После запуска и завершения этого тестирования мы можем получить следующие результаты:

Результаты ТЕМА

Нас особенно интересуют следующие показатели:

  • Чистая прибыль: - 3973.10 (- 39.74%)
  • Относительная просадка по балансу: 63.98%
  • Относительная просадка по средствам: 66.06%
  • Профит-фактор: 0.90
  • Матожидание выигрыша: - 10.59
  • Фактор восстановления: - 0.52
  • Коэффициент Шарпа: - 0.83

Фрактальная адаптивная скользящая средняя (iFrAMA)

Этот тип скользящей средней был разработан Джоном Элерсом. Этот трендовый индикатор исходит из того, что рыночные цены являются фрактальными. Его также можно использовать для выявления трендов и поворотных моментов. Ниже показаны этапы его расчета:

FrAMA

Мы можем использовать готовый технический индикатор из набора в MetaTrader 5. Создадим уже знакомую торговую стратегию. Стратегия представляет собой пересечение цены и индикатора FrAMA. Когда цена пересекает уровень выше FrAMA, это будет сигналом на покупку, а когда цена пересекает уровень ниже FrAMA, это будет сигналом на продажу.

Сигнал на покупку:

Цена закрытия находится выше значения фрактальной адаптивной скользящей средней (FrAMA).

А также: предыдущая цена закрытия ниже предыдущего значения FrAMA

Сигнал на продажу:

Цена закрытия ниже значения FraMA.

А также: предыдущая цена закрытия выше предыдущего значения FrAMA

Ниже приведен полный код торговой системы с небольшой разницей в использовании функции (iFrAMA) для возврата хэндла фрактальной адаптивной скользящей средней. Ее параметры:

  • symbol - имя символа; для текущего символа - _Symbol
  • period - используемый таймфрейм. По умолчанию - 1 час
  • ma_period - период усреднения скользящей средней. Значение по умолчанию - 50
  • ma_shift - для сдвига по горизонтали используем 0 
  • applied_price - тип цены, используемой для расчета; используем цену закрытия
//+------------------------------------------------------------------+
//|                                                iFrAMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int FrAMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   FrAMA = iFrAMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myFrAMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myFrAMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(FrAMA,0,0,3,myFrAMAArray);
   double lastClose=(priceArray[1].close);
   double FrAMAVal = NormalizeDouble(myFrAMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevFrAMAVal = NormalizeDouble(myFrAMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>FrAMAVal && prevClose<prevFrAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<FrAMAVal && prevClose>prevFrAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

После компиляции кода и запуска советника протестируем стратегию с использованием индикатора FrAMA со следующими настройками:

  • Размер лота: 1
  • Таймфрейм: 1 час
  • Период MA: 50

Мы тестируем этот советник на том же периоде, что и все остальные упомянутые скользящие средние, и получаем следующие результаты:

Результаты FrAMA

Нас особенно интересуют следующие показатели:

  • Чистая прибыль: - 2993.70 (- 29.94%)
  • Относительная просадка по балансу: 73.28%
  • Относительная просадка по средствам: 74.81%
  • Профит-фактор: 0.93
  • Матожидание выигрыша: - 6.45
  • Фактор восстановления: - 0.33
  • Коэффициент Шарпа: - 0.46

Сравнение результатов с результатами SMA

Сравним результаты каждого упомянутого типа скользящей средней. Но каждая скользящая средняя может давать разные результаты, если мы ее оптимизируем и изменим периоды. Также скользящая средняя может давать разные результаты в зависимости от настроек и рыночных условий.

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

  • Чистая прибыль: чем выше, тем лучше
  • Просадка (DD): чем ниже, тем лучше
  • Профит-фактор: чем выше, тем лучше
  • Матожидание выигрыша: чем выше, тем лучше
  • Фактор восстановления: чем выше, тем лучше
  • Коэффициент Шарпа: чем выше, тем лучше

Сравним результаты простого скользящего среднего с другими типами скользящих средних на основе этих параметров с помощью следующей таблицы:

Параметр SMA AMA DEMA TEMA FrAMA
Чистая прибыль 2700.30 (27%) 3638.20 (36.39%) - 961.60 (- 9.62%) - 3973.10 (- 39.74%) - 2993.70 (- 29.94%)
Относительная просадка по балансу 37.07% 22.48% 39.62% 63.98% 73.28%
Относительная просадка по средствам  41.76% 35.53% 41.15% 66.06% 74.81%
Прибыльность 1.10 1.31 0.97 0.90 0.93
Матожидание выигрыша 12.68 35.67 - 3.12 - 10.59 - 6.45
Фактор восстановления 0.45 0.65 - 0.18 - 0.52 - 0.33
Коэффициент Шарпа 0.57 0.86 - 0.21 - 0.83 - 0.46

По результатам всех наших тестов у нас есть два типа с наилучшей производительностью в зависимости от настроек и периода тестирования. Это простая и адаптивная скользящие средние. Лучшей из них является адаптивная скользящая средняя. У нее наблюдается:

  • Самая высокая чистая прибыль
  • Самая низкая относительная просадка по балансу
  • Самая низкая относительная просадка по средствам
  • Лучший профит-фактор
  • Самое высокое математическое ожидание выигрыша
  • Высокий фактор восстановления
  • Высокий коэффициент Шарпа

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

Заключение

В этой статье мы рассмотрели результаты работы следующих типов скользящих средних:

  • Адаптивная скользящая средняя (AMA)
  • Двойная экспоненциальная скользящая средняя (DEMA)
  • Тройная экспоненциальная скользящая средняя (TEMA)
  • Фрактальная адаптивная скользящая средняя (FrAMA)

Мы создали торговые системы для каждого типа и сравнили их результаты с результатами простой скользящей средней. По результатам тестирования лучшие результаты дали простая и адаптивная скользящие средние. Наилучшие результаты показала адаптивная скользящая средняя (AMA). Чтобы определить победителя, мы проанализировали и сравнили следующие показатели:

  • Чистая прибыль
  • Просадка (DD)
  • Прибыльность
  • Матожидание выигрыша
  • Фактор восстановления
  • Коэффициент Шарпа

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

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

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/13130

Прикрепленные файлы |
SMA_System.mq5 (2.07 KB)
iAMA_System.mq5 (2.15 KB)
iDEMA_System.mq5 (2.06 KB)
iTEMA_System.mq5 (2.06 KB)
iFrAMA_System.mq5 (2.08 KB)
Популяционные алгоритмы оптимизации: Алгоритм имитации отжига (Simulated Annealing, SA). Часть I Популяционные алгоритмы оптимизации: Алгоритм имитации отжига (Simulated Annealing, SA). Часть I
Алгоритм имитации отжига (Simulated Annealing) является метаэвристикой, вдохновленной процессом отжига металлов. В нашей статье проведем тщательный анализ алгоритма и покажем, как многие распространенные представления и мифы, вокруг этого наиболее популярного и широко известного метода оптимизации, могут быть ошибочными и неполными. Анонс второй части статьи: "Встречайте собственный авторский алгоритм имитации изотропного отжига (Simulated Isotropic Annealing, SIA)!"
Теория категорий в MQL5 (Часть 16): Функторы с многослойными перцептронами Теория категорий в MQL5 (Часть 16): Функторы с многослойными перцептронами
Мы продолжаем рассматривать функторы и то, как их можно реализовать с помощью искусственных нейронных сетей. Мы временно оставим подход, который включал в себя прогнозирование волатильности, и попытаемся реализовать собственный класс сигналов для установки сигналов входа и выхода из позиции.
Цветные буферы в мультисимвольных мультипериодных индикаторах Цветные буферы в мультисимвольных мультипериодных индикаторах
В статье пересмотрим структуру индикаторного буфера в мультисимвольных мультипериодных индикаторах и организуем вывод на график цветных буферов этих индикаторов.
Создаем простой мультивалютный советник с использованием MQL5 (Часть 1): Сигналы на основе ADX в сочетании с Parabolic SAR Создаем простой мультивалютный советник с использованием MQL5 (Часть 1): Сигналы на основе ADX в сочетании с Parabolic SAR
Под мультивалютным советником в этой статье понимается советник, или торговый робот, который может торговать (открывать/закрывать ордера, управлять ордерами и т. д.) более чем одной парой символов с одного графика.