English 中文 Español Deutsch 日本語 Português
Торговля по уровням ДиНаполи

Торговля по уровням ДиНаполи

MetaTrader 5Примеры | 29 ноября 2017, 08:13
9 943 3
Dmitriy Zabudskiy
Dmitriy Zabudskiy

Введение

На рынке, как и в жизни, всё постоянно меняется. То, что отлично работало еще вчера, сегодня показывает совсем неинтересные результаты. Но всё же остаются некоторые фундаментальные стратегии, которые со временем переживают косметические правки, но не меняют своей идеологической базы. Одна из них — "Уровни ДиНаполи", стратегия, названная в честь своего создателя. Она представляет собой урезанную реализацию линий Фибоначчи

Входные точки стратегии — уровни Фибоначчи 38.2% и 61.8%. За точки фиксации прибыли принимаются COP (Contracted Objective Point, подтянутая целевая точка) — 61.8%, OP (Objective Point, целевая точка) — 100%,  XOP (Expanded Objective Point, расширенная целевая точка) — 161.8%. Все расстояния указаны в процентах от длины тренда (см. рис.1).

Рис.1. "Уровни ДиНаполи" на паре EURUSD H4

Рис.1. Уровни ДиНаполи на паре EURUSD H4

На рисунке 1 уровни установлены при помощи инструментов Фибоначчи, входящих в стандартную поставку MetaTrader 5 — линий (красного цвета) и расширений (синего цвета) Фибоначчи. Также из рисунка можно понять, как откладываются уровни. Вертикальная линия, выделенная двумя стрелками, показывает уровень в 61.8%, который берётся от тренда (красная нисходящая линия) и отмечается вниз от максимальной цены отката, формируя уровень COP.

Есть четыре варианта входа в рынок: "Кусты", "Бонсай", "Сапер А" и "Сапер Б". Первые два вида наиболее агрессивны. Вход в рынок по ним происходит на первой коррекции. Два последних сценария предполагают открывать позицию на второй коррекции. Другие различия между этими вариантами заключаются в выставлении уровня Stop Loss. Подробное описание этих методик можно найти в статье "Торговая Система ДиНаполи", поэтому здесь углубляться в него не будем.

На вышеприведенном рисунке я хотел только показать классическую картину уровней ДиНаполи, тот самый фундамент стратегии. Мы видим, что удачнее всего можно было войти в рынок на уровне 61.8% (и здесь стоит красная ценовая метка), но этот уровень достигается не всегда. Поэтому некоторые трейдеры начинали активно продавать на 38.2%: об этом свидетельствует нисходящая свеча на 20:00. Такие входы более присущи агрессивной торговле по методу "Кусты". По нему трейдер устанавливает стоп на более высоком уровне, чем тот, на котором открыта позиция. Закрытие сделки произошло на уровне COP (61.8%). Оно отмечено на рисунке синей ценовой меткой.

Выглядит всё достаточно просто, но на практике описанные уровни срабатывают не всегда из-за частой смены трендов. Чтобы более четко определять тренд, автор стратегии предлагает в дополнение к уровням использовать индикаторы: скользящую среднюю (МА) и осциллятор Stochastic. На этом фундаменте я и предлагаю разработать профитную стратегию и реализовать её в советнике.


Формирование стратегии на стандартных инструментах MetaTrader 5

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

Постараюсь максимально просто и доступно объяснить стратегию, которая ляжет в основу нашего советника.

Рис.2. Уровни ДиНаполи со вспомогательными индикаторами EURUSD H4 (восходящий тренд)

Рис.2. Уровни ДиНаполи со вспомогательными индикаторами EURUSD H4 (восходящий тренд)

На рисунке 2 представлен график валютной пары EURUSD H4. На него нанесены уровни ДиНаполи, индикатор Stochastic (8,3,3) и две скользящие средние со сдвигом 5 и периодами 25 (красная) и 7 (синяя).

Начнём по порядку. На графике мы видим восходящий тренд, на который наложена сетка Фибоначчи с уровнями 23.6%, 38.2%, 50%, 61.8%. Уровней здесь больше, чем в классической реализации: практика показала, что цена может оттолкнуться от каждого из них. 

На откат (коррекцию) наложено расширение Фибоначчи: так появляются уровни COP и OP. Однако и в данном случае, и во всей стратегии в целом эти уровни несущественны. Здесь они рассчитаны исключительно для установки Take Profit (позже мы увидим это в коде).

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

  • Правило первое: вход по уровням ДиНаполи возможен с 23.6% по 61.8%. Это довольно широкий диапазон, поэтому мы должны перейти ко второй стадии анализа.

Следующий фильтр сигнала — индикатор Stochastic (с параметрами 8,3,3) с двумя уровнями — 30 и 70.

  • Правило второе: покупаем, когда сигнальная и главная линии индикатора Stochastic находятся под уровнем 30, и продаем, когда они выше уровня 70.

Теперь нужно определить тренд. Для этого используем скользящую среднюю (сдвиг 5, период 25). Получается, что покупка возможна, когда цена находится выше линии тренда, а продажа — она когда ниже. Но это достаточно большой диапазон, и чтобы его сократить, вводим ещё одну скользящую среднюю (сдвиг 5, период 7). Но даже с ее использованием диапазон может получиться слишком широким. В таких случаях вводится дополнительное его сокращение: сделки разрешается открывать только на "верхней половине" расхождений, ближе к линии с периодом 25. 

  • Правило третье: покупаем во второй половине промежутка, ближе к линии с периодом 25, при этом линия с меньшим периодом находится сверху.
  • Правило четвёртое: продаём во второй половине промежутка, ближе к линии с периодом 25, при этом линия с меньшим периодом находится снизу.

Допустим, что вышеперечисленные условия сработали, и мы открыли позицию. Теперь надо определиться с правилами ее закрытия. В этом нам помогут уровни, сформированные расширением Фибоначчи, и индикатор Stochastic.

  • Правило пятое: закрываем сделку, если цена достигает одного из целевых уровней ДиНаполи (COP, OP, XOP), или индикатор Stochastic даёт сигнал на закрытие.

На рисунке 2 и 3 области, подходящие под эти правила, показаны жёлтыми прямоугольниками.

Рис.3. Уровни ДиНаполи со вспомогательными индикаторами EURUSD H4 (нисходящий тренд)

Рис.3. Уровни ДиНаполи со вспомогательными индикаторами EURUSD H4 (нисходящий тренд)

Как видим, получившиеся правила логичны и понятны. В них пока не оговаривалось выставление Take Profit или Stop Loss и небольшой трейлинг для перехода в безубыток. Всё это мы рассмотрим ниже.


Кодируем стратегию

Входные параметры

Вначале подключаем класс CTrade (Trade.mqh). Затем определим параметры уровней ДиНаполи — минимальный и максимальный уровень входа. По умолчанию они устанавливаются, как описано выше: от 23.6% до 61.8%. Но для разных валютных пар они могут меняться и находиться в разных пределах.

Следующие параметры — Take Profit и Stop Loss. Stop Loss выставляется по уровням от пиковой цены. На рисунках 2 и 3 они представлены красным цветом. Take Profit устанавливается от цены выставления ордера.

То есть, предположим, что уровень покупки был 50%, Stop Loss установлен на 70%, Take Profit — на 70%. Значит, если принять, что 100% — это 100 пунктов, то Stop Loss будет находиться ниже цены покупки на 20 пунктов, в то время как Take Profit — на все 70 пунктов. Это надо учитывать при оптимизации советника.

Далее надо определить трейлинг, или переход в безубыток. В соответствии с текущими параметрами в коде, при проходе цены на 400 пунктов Stop Loss сдвинется в прибыльную сторону на 10 пунктов.

Остальные параметры в комментариях не нуждаются.

//+------------------------------------------------------------------+
//|                                               Dinapoli_v1.01.mq5 |
//|                                                          Aktiniy |
//|                                            https://www.mql5.com/ |
//+------------------------------------------------------------------+
#property copyright "Aktiniy"
#property link      "https://www.mql5.com/"
#property version   "1.01"
#include<Trade\Trade.mqh>
//--- input parameters
//--- Fibo number
input double   percent_min_enter=23.6;      // Минимальный процент входа
input double   percent_max_enter=61.8;      // Максимальный процент входа
input double   percent_for_tp=60;           // Процент возможного Take Profit
input double   percent_for_sl=70;           // Процент возможного Stop Loss
input int      trailing_sl=400;             // Переход в безубыток при проходе пунктов
input int      trailing_profit=10;          // Уровень безубытка в пунктах
//--- order
input long     magic_number=65758473787389; // Магический номер
input double   order_volume=0.01;           // Размер Лота
input int      order_deviation=100;         // Отклонение по открытию позиции
//--- Stochastic
input int      stochastic_k=8;              // Индикатор Stochastic "Период %К"
input int      stochastic_d=3;              // Индикатор Stochastic "Замедление"
input int      stochastic_slowing=3;        // Индикатор Stochastic "Период %D"
input double   stochastic_up_level=70;      // Индикатор Stochastic "Уровень сигнала сверху"
input double   stochastic_down_level=30;    // Индикатор Stochastic "Уровень сигнала снизу"
//--- MA RED 25 5
input int      ma_red_period=25;            // Индикатор MA RED "Период"
input int      ma_red_shift=5;              // Индикатор MA RED "Сдвиг"
//--- MA BLUE 7 5
input int      ma_blue_period=7;            // Индикатор MA BLUE "Период"
input int      ma_blue_shift=5;             // Индикатор MA BLUE "Сдвиг"
//--- Variable
CTrade trade;
int stochastic_handle=0;
char answer_stochastic=0;
int ma_red_handle=0;
int ma_blue_handle=0;
char answer_ma=0;
int fractals_handle=0;

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

Инициализация

Далее следует небольшая функция инициализации. Здесь мы настраиваем класс CTrade и получаем хэндлы индикаторов.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   trade.SetExpertMagicNumber(magic_number);
   trade.SetDeviationInPoints(order_deviation);
   trade.SetTypeFilling(ORDER_FILLING_FOK);
   trade.SetAsyncMode(false);

   stochastic_handle=iStochastic(_Symbol,_Period,stochastic_k,stochastic_d,stochastic_slowing,MODE_SMA,STO_LOWHIGH);
   ma_red_handle=iMA(_Symbol,_Period,ma_red_period,ma_red_shift,MODE_SMA,PRICE_CLOSE);
   ma_blue_handle=iMA(_Symbol,_Period,ma_blue_period,ma_blue_shift,MODE_SMA,PRICE_CLOSE);
   fractals_handle=iFractals(_Symbol,_Period);
//---
   return(INIT_SUCCEEDED);
  }

Перед тем как перейти к главной функции, изучим принцип функций сигналов.

Получение сигнала с индикатора Stochastic

//+------------------------------------------------------------------+
//| Получение сигнала с индикатора Stochastic                        |
//+------------------------------------------------------------------+
void Stochastic(char &answer)                                                                          // 0-нет сигнала; 1-сигнал вверх; 2-сигнал вниз
  {
   answer=0;                                                                                           // ответ
   double stochastic_line_main[3];
   double stochastic_line_signal[3];
   int line_main=CopyBuffer(stochastic_handle,0,0,3,stochastic_line_main);
   int line_signal=CopyBuffer(stochastic_handle,1,0,3,stochastic_line_signal);
   if(line_main!=3 || line_signal!=3)
     {Alert("Error of copy iStochastic: main line=",line_main,", signal line=",line_signal);}          // проверяем скопированные данные Stochastic

   if(stochastic_line_main[1]>stochastic_up_level && stochastic_line_signal[1]>stochastic_up_level)
     {answer=2;}                                                                                       // благоприятна продажа
   if(stochastic_line_main[1]<stochastic_down_level && stochastic_line_signal[1]<stochastic_down_level)
     {answer=1;}                                                                                       // благоприятна покупка
  }

Всё предельно просто: копируются три последних значения индикатора, последнее из них сравнивается с уровнями, заданными в настройках. Функция передает ответ в переменной.

Получение сигнала с индикаторов MA

//+------------------------------------------------------------------+
//| Получение сигнала с индикаторов MA                               |
//+------------------------------------------------------------------+
void MA(char &answer,                                               // 0-нет сигнала; 1-сигнал вверх; 2-сигнал вниз
        double &line_blue,
        double &line_red,
        double ask,
        double bid)
  {
   answer=0;                                                        // ответ
   double ma_red[3];
   double ma_blue[3];
   int red=CopyBuffer(ma_red_handle,0,0,3,ma_red);
   int blue=CopyBuffer(ma_blue_handle,0,0,3,ma_blue);
   if(red!=3 || blue!=3)
     {Alert("Error of copy iMA: MA red=",red,", MA blue=",blue);}   // проверяем скопированные данные MA red и blue

   line_blue=ma_blue[2];
   line_red=ma_red[2];

   if(ma_blue[2]>ma_red[2])                                         // предположительно тренд направлен вверх
      if(ask<ma_blue[2])                                            // предположительно цена находится в откатном положении
         if(ask>ma_red[2])
           {answer=1;}                                              // возможно скорое движение в направлении тренда (вверх)

   if(ma_blue[2]<ma_red[2])                                         // предположительно тренд направлен в низ
      if(bid>ma_blue[2])                                            // предположительно цена находится в откатном положении
         if(bid<ma_red[2])
           {answer=2;}                                              // возможно скорое движение в направлении тренда (вниз)
  }

Здесь три последних значения тоже копируются в буферы, после чего путем сравнения определяется, находится ли цена между двумя линиями индикатора. Ранее мы уже говорили о том, что часто промежуток, в котором допустима торговля, нужно сужать. Именно поэтому данная функция передаёт не только ответ, но и последние значения двух скользящих средних. Механизм сужения интервала торговли мы рассмотрим чуть позже.

Получение данных с индикатора Fractals

Функция определения размера тренда сложнее. Она реализована на данных индикатора Fractals. В начале функции копируются 100 последних данных, потом в двух циклах проходит проверка нижних и верхних сигналов. Здесь реализован тест на наличие фрактала: все значения больше 10000 отфильтровываются, затем сравниваются соседние, в поисках наибольшего и наименьшего первого фрактала с конца.

//+------------------------------------------------------------------+
//| Получение данных с индикатора Fractals                           |
//+------------------------------------------------------------------+
void Fractals(double &price_up,
              double &price_down)
  {
   price_up=0;
   price_down=0;
   double fractals_up[100];
   double fractals_down[100];
   int up=CopyBuffer(fractals_handle,0,0,100,fractals_up);
   int down=CopyBuffer(fractals_handle,1,0,100,fractals_down);
   if(up!=100 || down!=100)
     {Alert("Error of copy iFractals: Fractals up=",up,", Fractals down=",down);} // проверяем скопированные данные Fractals up и down

   double price_high=0;
   double price_low=0;

   for(int x=99; x>0; x--)                                                        // цикл для верхнего фрактала
     {
      if(fractals_up[x]<10000)                                                    // проверка наличия фрактала
        {
         if(price_high==0){price_high=fractals_up[x];}                            // первичная проверка
         if(price_high>fractals_up[x]){break;}                                    // если фракталы пошли на понижение, прекращаем цикл
         else{price_high=fractals_up[x];}                                         // если фракталы идут вверх, то копируем
        }
     }

   for(int x=99; x>0; x--)                                                        // повторяем цикл для нижнего фрактала
     {
      if(fractals_down[x]<10000)                                                  // проверка наличия фрактала
        {
         if(price_low==0){price_low=fractals_down[x];}                            // первичная проверка
         if(price_low<fractals_down[x]){break;}                                   // если фракталы пошли на повышение, прекращаем цикл
         else{price_low=fractals_down[x];}                                        // если фракталы идут вниз, то копируем
        }
     }

   double price_ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);                         // запрос цены покупки
   double price_bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);                         // запрос цены продажи

   if(price_high>price_ask && price_high>price_bid)                               // проверяем, находятся ли цены аск и бид между верхней и нижней ценой
      if(price_low<price_ask && price_low<price_bid)
        {
         price_up=price_high;                                                     // присваиваем значения на ответ
         price_down=price_low;
        }
  }
//+------------------------------------------------------------------+

Для надёжности сигнала перед ответом проверяется, находится ли цена внутри найденного диапазона. Это делается, потому что последний и, возможно, ключевой фрактал формируется после образования двух последних свечей (по правилам образования фрактала).

Расчёт цены открытия позиции

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

//+------------------------------------------------------------------+
//| Расчёт цены открытия позиции                                     |
//+------------------------------------------------------------------+
void Price_for_order(double high_price,
                     double low_price,
                     double &p_enter_min,
                     double &p_enter_max,
                     double &p_tp,
                     double &p_sl,
                     char trend,                                      // 1- вверх; 2 - вниз
                     double blue_line,
                     double red_line
                     )
  {
   double point_price=(high_price-low_price);
   double point_enter_min=point_price*percent_min_enter/100;
   double point_enter_max=point_price*percent_max_enter/100;
   double point_tp=point_price*percent_for_tp/100;
   double point_sl=point_price*percent_for_sl/100;
   double point_ma_line=MathAbs(blue_line-red_line)/2;

   point_enter_min=NormalizeDouble(point_enter_min,_Digits);
   point_enter_max=NormalizeDouble(point_enter_max,_Digits);
   point_ma_line=NormalizeDouble(point_ma_line,_Digits);

   point_tp=NormalizeDouble(point_tp,_Digits);
   point_sl=NormalizeDouble(point_sl,_Digits);

   if(trend==1)                                                       // вверх
     {
      p_enter_min=high_price-point_enter_min;
      double p_ma_min=red_line+point_ma_line;
      if(p_enter_min>p_ma_min)
        {p_enter_min=p_ma_min;}
      p_enter_max=high_price-point_enter_max;
      if(p_enter_max>p_enter_min)
        {p_enter_max=red_line;}

      p_tp=p_enter_min+point_tp;
      p_sl=high_price-point_sl;
     }

   if(trend==2)                                                       // вниз
     {
      p_enter_min=low_price+point_enter_min;
      double p_ma_min=red_line-point_ma_line;
      if(p_enter_min<p_ma_min)
        {p_enter_min=p_ma_min;}
      p_enter_max=low_price+point_enter_max;
      if(p_enter_max<p_enter_min)
        {p_enter_max=red_line;}

      p_tp=p_enter_min-point_tp;
      p_sl=low_price+point_sl;
     }
  }

Далее, в зависимости от направления тренда, рассчитываются цены, и функция возвращает ответ.

Модификация и закрытие позиции

Сначала получаем все данные по последней позиции. Далее, в зависимости от типа ордера, он модернизируется (переходит в безубыток) или закрывается, если Stochastic даёт противоположный сигнал.

//+------------------------------------------------------------------+
//| Модификация и закрытие позиции                                   |
//+------------------------------------------------------------------+
void Position_mod(double ask,
                  double bid,
                  int point,
                  int profit,
                  char stochastic)
  {
   double price=trade.RequestPrice();
   double tp=trade.RequestTP();
   double sl=trade.RequestSL();
   double sl_point=point*_Point;
   double sl_profit=profit*_Point;
   double tp_point=(MathAbs(tp-price))/2;

   if(trade.RequestType()==ORDER_TYPE_BUY)              // ордер покупки
     {
      if(sl<price && bid>(price+sl_point))
        {
         sl_profit=sl_profit+price;
         trade.PositionModify(_Symbol,sl_profit,tp);
        }
      if(stochastic==2)                                 // ожидается движение вниз
        {
         trade.PositionClose(_Symbol,order_deviation);
        }
     }
   if(trade.RequestType()==ORDER_TYPE_SELL)             // ордер продажи
     {
      if(sl>price && ask<(price-sl_point))
        {
         sl_profit=sl_profit-price;
         trade.PositionModify(_Symbol,sl_profit,tp);
        }
      if(stochastic==1)                                 // ожидается движение вверх
        {
         trade.PositionClose(_Symbol,order_deviation);
        }

     }
  }

Консолидирующая функция

Последняя функция объединяет в себе все функции, рассмотренные ранее. В начале объявляются все согласующие переменные. Затем через функции индикаторов получаются текущие основные значения "верхних правил стратегии". Далее происходит разделение, в зависимости от полученных ответов по "верхним правилам". Рассчитывается размер тренда и цены, с которыми благоприятно входить на рынок. Если ранее открытых позиций не обнаружено и цена находится в рассчитанном диапазоне, то позиция открывается.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double price_high=0;                                           // верхняя цена для расчёта по фракталам
   double price_low=0;                                            // нижняя цена для расчёта по фракталам

   double price_enter_min=0;                                      // минимальная цена входа
   double price_enter_max=0;                                      // максимальная цена входа
   double price_tp=0;                                             // уровень Take Profit
   double price_sl=0;                                             // уровень Stop Loss

   double price_ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);         // запрос цены покупки
   double price_bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);         // запрос цены продажи

   double ma_blue_line=0;                                         // значение малопериодной МА BLUE
   double ma_red_line=0;                                          // значение многопериодной МА RED

   Stochastic(answer_stochastic);
   MA(answer_ma,ma_blue_line,ma_red_line,price_ask,price_bid);

   if(answer_stochastic==1)                                       // ожидается движение вверх
     {
      if(answer_ma==1)                                            // находимся в диапазоне торговли на покупку 
        {
         Fractals(price_high,price_low);
         Price_for_order(price_high,price_low,price_enter_min,price_enter_max,price_tp,price_sl,1,ma_blue_line,ma_red_line);

         if(price_ask<price_enter_min && price_ask>price_enter_max)
           {
            if(PositionsTotal()==0)
              {
               trade.Buy(order_volume,_Symbol,price_ask,price_sl,price_tp,"Buy");
              }
           }
        }
     }

   if(answer_stochastic==2)                                        // находимся в диапазоне торговли на продажу 
     {
      if(answer_ma==2)                                             // ожидается движение вниз
        {
         Fractals(price_high,price_low);
         Price_for_order(price_high,price_low,price_enter_min,price_enter_max,price_tp,price_sl,2,ma_blue_line,ma_red_line);

         if(price_bid>price_enter_min && price_bid<price_enter_max)
            if(PositionsTotal()==0)
              {
               trade.Sell(order_volume,_Symbol,price_bid,price_sl,price_tp,"Sell");
              }
        }
     }

   if(PositionsTotal()!=0)
     {
      Position_mod(price_ask,price_bid,trailing_sl,trailing_profit,answer_stochastic);
     }

  }

В случае, если открытые позиции уже есть, вызывается функция модернизации/удаления позиции. На этом код заканчивается. Настало время протестировать полученный советник.


Тестируем то, что получилось

Тестирование советника Dinapoli_v1.01 проводилось на разных валютных парах, на таймфрейме H4. Использована история с 2017.01.01 по 2017.11.12.

Символ: EURUSD

Параметры:

percent_min_enter=33.6 magic_number=65758473787389 stochastic_up_level=70
percent_max_enter=56 order_volume=0.01 stochastic_down_level=30
percent_for_tp=145 order_deviation=100 ma_red_period=25
percent_for_sl=100 stochastic_k=8 ma_red_shift=5
trailing_sl=675 stochastic_d=3 ma_blue_period=7
trailing_profit=40 stochastic_slowing=3 ma_blue_shift=5

Рис.4. Результаты тестирования EURUSD H4 (2017.01.01 - 2017.11.12)

Рис.4. Результаты тестирования EURUSD H4 (2017.01.01 - 2017.11.12)

Рис.4. Результаты тестирования EURUSD H4 (2017.01.01 - 2017.11.12)

Символ: GBPUSD

Параметры:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=90
percent_max_enter=50 order_volume=0.01 stochastic_down_level=30
percent_for_tp=335 order_deviation=100 ma_red_period=15
percent_for_sl=63 stochastic_k=3 ma_red_shift=5
trailing_sl=425 stochastic_d=1 ma_blue_period=4
trailing_profit=20 stochastic_slowing=4 ma_blue_shift=5

Рис.5. Результаты тестирования GBPUSD H4 (2017.01.01 - 2017.11.12)

Рис.5. Результаты тестирования GBPUSD H4 (2017.01.01 - 2017.11.12)

Рис.5. Результаты тестирования GBPUSD H4 (2017.01.01 - 2017.11.12)

Символ: NZDUSD

Параметры:

percent_min_enter=31.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=88 order_volume=0.01 stochastic_down_level=30
percent_for_tp=45 order_deviation=100 ma_red_period=24
percent_for_sl=95 stochastic_k=10 ma_red_shift=5
trailing_sl=550 stochastic_d=2 ma_blue_period=4
trailing_profit=100 stochastic_slowing=1 ma_blue_shift=5

Рис.6. Результаты тестирования NZDUSD H4 (2017.01.01 - 2017.11.12)

Рис.6. Результаты тестирования NZDUSD H4 (2017.01.01 - 2017.11.12)

Рис.6. Результаты тестирования NZDUSD H4 (2017.01.01 - 2017.11.12)

Символ: USDCAD

Параметры:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=73 order_volume=0.01 stochastic_down_level=20
percent_for_tp=315 order_deviation=100 ma_red_period=25
percent_for_sl=69 stochastic_k=10 ma_red_shift=5
trailing_sl=325 stochastic_d=1 ma_blue_period=3
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5

Рис.7. Результаты тестирования USDCAD H4 (2017.01.01 - 2017.11.12)

Рис.7. Результаты тестирования USDCAD H4 (2017.01.01 - 2017.11.12)

Рис.7. Результаты тестирования USDCAD H4 (2017.01.01 - 2017.11.12)

Символ: USDCHF

Параметры:

percent_min_enter=49.6 magic_number=65758473787389 stochastic_up_level=70
percent_max_enter=69 order_volume=0.01 stochastic_down_level=40
percent_for_tp=55 order_deviation=100 ma_red_period=20
percent_for_sl=98 stochastic_k=13 ma_red_shift=5
trailing_sl=900 stochastic_d=6 ma_blue_period=12
trailing_profit=40 stochastic_slowing=3 ma_blue_shift=5

Рис.8. Результаты тестирования USDCHF H4 (2017.01.01 - 2017.11.12)

Рис.8. Результаты тестирования USDCHF H4 (2017.01.01 - 2017.11.12)

Рис.8. Результаты тестирования USDCHF H4 (2017.01.01 - 2017.11.12)

Символ: USDJPY

Параметры:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=50 order_volume=0.01 stochastic_down_level=20
percent_for_tp=295 order_deviation=100 ma_red_period=22
percent_for_sl=53 stochastic_k=3 ma_red_shift=5
trailing_sl=750 stochastic_d=1 ma_blue_period=5
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5

Рис.9. Результаты тестирования USDJPY H4 (2017.01.01 - 2017.11.12)

Рис.9. Результаты тестирования USDJPY H4 (2017.01.01 - 2017.11.12)

Рис.9. Результаты тестирования USDJPY H4 (2017.01.01 - 2017.11.12)

Символ: AUDUSD

Параметры:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=80
percent_max_enter=81 order_volume=0.01 stochastic_down_level=40
percent_for_tp=305 order_deviation=100 ma_red_period=13
percent_for_sl=69 stochastic_k=3 ma_red_shift=5
trailing_sl=250 stochastic_d=4 ma_blue_period=1
trailing_profit=20 stochastic_slowing=4 ma_blue_shift=5

Рис.10. Результаты тестирования AUDUSD H4 (2017.01.01 - 2017.11.12)

Рис.10. Результаты тестирования AUDUSD H4 (2017.01.01 - 2017.11.12)

Рис.10. Результаты тестирования AUDUSD H4 (2017.01.01 - 2017.11.12)

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

Причина этого в следующем: чтобы уменьшить просадку баланса, стратегия подразумевает выставление Stop Loss как можно ближе. Но таким образом повышается требовательность к качеству сигналов. Соответственно, чем сигналы качественнее, тем меньше происходит входов в рынок, но и подъем графика становится более стабильным (например, на паре USDCHF). Однако на практике мы планируем получить как можно больше прибыли. Нам надо быть уверенными в том, что советник будет стабильно минимизировать убытки в сложных рыночных ситуациях.

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

Символ: XAUUSD

После того, как советник протестирован на всех популярных валютных парах, было бы неплохо узнать, как он поведет себя на товарном рынке. Поэтому я протестировал символ XAUUSD (фьючерсы на золото к доллару США), и вот что получилось:

Параметры:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=90
percent_max_enter=50 order_volume=0.2 stochastic_down_level=10
percent_for_tp=255 order_deviation=100 ma_red_period=23
percent_for_sl=80 stochastic_k=3 ma_red_shift=5
trailing_sl=750 stochastic_d=1 ma_blue_period=6
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5


Рис.11. Результаты тестирования XAUUSD H4 (2017.01.01 - 2017.11.12)

Рис.11. Результаты тестирования XAUUSD H4 (2017.01.01 - 2017.11.12)

Рис.11. Результаты тестирования XAUUSD H4 (2017.01.01 - 2017.11.12)

Результат по золоту интересный: советник рассчитал входы с точностью 83.3% (прибыльные трейды), а сама прибыль составила 461%, с просадкой не более 40%. То есть прибыль почти в 10 раз преобладала над просадкой. Довольно интересный показатель, но в силу небольшого количества сделок (их всего 18 трейдов) мы не можем делать серьезных выводов на основе проведенного тестирования.


Недостатки торговой стратегии

Как и любой другой, торговый советник, который мы разработали, не лишен недостатков.

Рис.12. Работа советника на тренде (NZDUSD H4)

Рис.12. Работа советника на тренде (NZDUSD H4)

На рисунке 12 видно, как советник работает в определенном канале. Всё выглядит довольно стабильно, но есть главный недостаток, который бросается в глаза: ранний выход из сделок.

Рис.13. Работа советника во флете (EURUSD H4)

Рис.13. Работа советника во флэте (EURUSD H4)

И второе "узкое место": советник не любит работать на флэте. На рисунке 13 мы видим, что прибыль при таком движении цены невелика, да и входы рассчитаны не совсем корректно.

Таблица результатов

СимволТрейдыПрибыльные трейды (%)Чистая прибыль, $ Макс. просадка в % по балансуМатожидание, $PFRFSharpe
AUDUSD4116 (39.0%)49.9411.81.222.262.800.19
EURUSD5228 (53.8%)124.7917.72.402.234.010.28
GBPUSD4017 (42.5%)126.3919.03.164.845.020.24
NZDUSD13151 (38.9%)111.6311.90.852.255.290.26
USDCAD23145 (19.4%)85.7128.70.371.921.930.12
USDCHF1714 (82.3%)77.114.34.547.167.240.94
USDJPY21045 (21.4%)50.8852.30.241.350.960.07
XAUUSD1815 (83.3%)461.995.1
25.679.009.880.47

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

Заключение

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

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

Приложенные файлы

# Имя Тип Описание
1 Dinapoli_v1.01.mq5 Советник Советник, реализующий стратегию использования уровней ДиНаполи и вспомогательных индикаторов
2 AUDUSDH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе AUDUSD Н4
3 EURUSDH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе EURUSD H4
4 GBPUSDH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе GBPUSD H4
5 NZDUSDH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе NZDUSD H4
6 USDCADH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе USDCAD H4
7 USDCHFH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе USDCHF H4
8 USDJPYH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе USDJPY H4
9 XAUUSDH4.set Файл настроек советника Настройки, используемые при тестировании и оптимизации на символе XAUUSD H4
Прикрепленные файлы |
Dinapoli_v1.01.mq5 (29.87 KB)
AUDUSDH4.set (1.3 KB)
EURUSDH4.set (1.36 KB)
GBPUSDH4.set (1.3 KB)
NZDUSDH4.set (1.3 KB)
USDCADH4.set (1.3 KB)
USDCHFH4.set (1.3 KB)
USDJPYH4.set (1.3 KB)
XAUUSDH4.set (1.3 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (3)
Denis Tikhonov
Denis Tikhonov | 21 янв. 2018 в 18:00
При тестировании, по какой-то причине Fractals(price_high,price_low) иногда возвращает нулевые значения, после чего Price_for_order формирует ордер без стоп-лосса.
Dmitriy Zabudskiy
Dmitriy Zabudskiy | 25 янв. 2018 в 21:26
Denis Tikhonov:
При тестировании, по какой-то причине Fractals(price_high,price_low) иногда возвращает нулевые значения, после чего Price_for_order формирует ордер без стоп-лосса.

Это скорее всего происходит, когда цена находится выше или ниже фракталов:

if(price_high>price_ask && price_high>price_bid)                               // проверяем, находятся ли цены аск и бид между верхней и нижней ценой
      if(price_low<price_ask && price_low<price_bid)
        {
         price_up=price_high;                                                     // присваиваем значения на ответ
         price_down=price_low;
        }

, а сигналы на покупку и продажу с других индикаторов поступают.

Можно исправить поставив проверку перед вызовом функции Price_for_order, примерно такую:

if(price_high!=0 && price_low!=0)
Konstantin Seredkin
Konstantin Seredkin | 18 мар. 2018 в 09:58

Интересный подход к расчетам канала фракталов.

Как дополнительный фильтр внедрите дополнительный настраиваемый параметр в виде Delta - где дельта это минимальное расстояние от линии лоу (мин фрактал ) до линии хай (максимальный фрактал ) если расстояние в пп между этими линиями меньше установленного, то считаем что тренд - импульсное движение цены маленькое т.к. нет смысла ловить вход если между мин и мак точками расстояние всего в 100 пунктов - это по сути зона накопление объема - флет, что бы отсекать эти зоны, ставим к примеру 1000 пунктов и все что меньше, мы просто игнорируем т.к. на проходе цены в 1000 и более пунктов, намного выше шанс поймать коррекционное движение на 61 фибо, которое в свою очередь окажется отбойным в продолжении движения тренда.

добавил в робота трендовые линии которые привязаны к найденным фракталам, получается такая картинка


В ведя дельту, мы избежим вот таких входов непонятных в узком диапазоне.


Создаем новую торговую стратегию с использованием технологии разложения входов на индикаторы Создаем новую торговую стратегию с использованием технологии разложения входов на индикаторы
В статье предложена технология, с помощью которой каждый желающий сможет создать свою уникальную торговую стратегию, собрав индивидуальный набор индикаторов, и разработать собственные сигналы для входа в рынок.
Автоматический подбор перспективных сигналов Автоматический подбор перспективных сигналов
Статья посвящена изучению торговых сигналов для MetaTrader 5 с автоматическим исполнением на счетах подписчиков. Также рассматривается разработка инструментов для поиска перспективных торговых сигналов прямо в терминале.
Как снизить риски трейдера Как снизить риски трейдера
Торговля на финансовых рынках связана с целым комплексом рисков, которые должны учитываться в алгоритмах торговых систем. Снижение таких рисков — важнейшая задача для получения прибыли при трейдинге.
Торговая стратегия 'Momentum Pinball' Торговая стратегия 'Momentum Pinball'
В этой статье продолжается тема написания кода к торговым системам, описанным в книге Линды Рашке и Лоуренса Коннорса "Биржевые секреты. Высокоэффективные стратегии краткосрочной торговли". На этот раз исследуется система 'Momentum Pinball': описано создание двух индикаторов, торгового робота и сигнального блока по ней.