English 中文 Español Deutsch 日本語 Português
preview
Разработка торговой системы на основе индикатора Fibonacci

Разработка торговой системы на основе индикатора Fibonacci

MetaTrader 5Трейдинг | 29 мая 2023, 10:30
2 169 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Введение

Это новая статья из серии, в которой мы учимся создавать торговые системы на основе популярных аналитических инструментов и технических индикаторов. В этот раз мы разберем, как создать торговую систему на основе индикатора Fibonacci Retracement. Пожалуй, это один из самых популярных индикаторов в трейдинге. Создавать мы будет торговую систему, которую можно использовать в торговом терминале MetaTrader 5. Мы будем писать программу на языке MQL5, используя встроенную среду MetaEditor. Мы уже ранее разбирали в деталях, как загружать и использовать MetaTrader 5 и IDE, можете прочитать"Как написать MQL5-код в редакторе MetaEditor" в более ранней статье.

Что мы с вами изучим:

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

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


Определение Fibonacci

В этой части узнаем, что из себя представляет инструмент Fibonacci Retracement и как его можно использовать на графике. Фибоначчи — это технический инструмент, который можно использовать для поиска областей поддержки или сопротивления на графике (это области, от которых мы ожидаем отскока). Он основан на последовательности Фибоначчи, которая представляет собой математический ряд чисел. Каждое число этого ряда является суммой двух предыдущих чисел. На графике уровни Фибоначчи строятся в виде горизонтальных линий. Самые популярные линии на графике — 23.6%, 38.2%, 50% и 61.8%.

Чтобы увидеть эти уровни на графике, достаточно выбрать этот индикатор из списка доступных технических инструментов в MetaTrader 5 и запустить на графике. Как это сделать по шагам:

Открываем терминал MetaTrader 5, переходим на вкладку Insert --> Объекты --> Fibonacci Retracement

Запуск уровней Фибоначчи на графике

После этого, если образовался откат после восходящего тренда, строим его от минимума к максимуму и наоборот, если есть откат после нисходящего тренда, строим уровень от максимума к минимуму, как в следующих примерах.

Фибоначчи после восходящего тренда:

 Запуск уровней Фибоначчи на графике при бычьем тренде

Фибоначчи после нисходящего тренда:

Запуск уровней Фибоначчи на графике при медвежьем тренде

Как видно на примерах выше, на графике отображается линия тренда, проведенная между двумя точками самого высокого и самого низкого значений, а также горизонтальные линии с уровнями 23,6, 38,2, 50 и 61,8. Это уровни, ка которых можно ождидать коррекции или отката после восходящего или нисходящего тренда, то есть можно ожидать, что цена достигнет этих уровней и отскочит от них. Благодаря такой особенности уровни Фибоначчи можно использовать в качестве уровней поддержки или сопротивления.

Уровнями можно управлять через окно настроек. Для этого нажмите правой кнопкой мыши на инструменте рисования или на графике. Выберите Объекты в меню и из списка выберите уровни Фибоначчи. После этого откроется вот такое окно:

Окно уровней Фибоначчи 1

На вкладке общих настроек можно выбрать имя объекта и стиль отображения: цены, тип и толщина линии.

Окно уровней Фибоначчи 2

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

Окно уровней Фибоначчи 3

На вкладке параметров можно установить дату, время и значение, с которых мы начнем строить уровни, а также дату, время и значения, на которых построение объекта Фибоначчи закончится.


Стратегии по индикатору Fibonacci

В этой части на примере простых стратегий мы узнаем, как можно использовать уровни Fibonacci Retracement. Разберем с вами два подхода. Один из них — определяем уровни Фибоначчи на основе последней дневной свечи, а второй — установка количества свечей на любом таймфрейме и определение уровней на их основе. Затем мы поработаем с другой стратегией — будем получать сигнал на покупку или продажу на основе определенного заранее уровня фибоначчи. Давайте рассмотрим каждую из этих стратегий в подробностях.

Первый подход: на основе дневных данных

Простая система Simple FIBO

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

Имеем следующее:

Закрытие последнего дня выше открытия ==> бычья свеча

Строим зеленые уровни фибоначчи, получаем цены этих уровней.  

Закрытие последнего дня ниже открытия ==> медвежья свеча

Строим красные уровни фибоначчи, получаем цены этих уровней.

Сигналы Фибоначчи:

Эта стратегия будет генерировать сигналы на покупку и продажу на основе определенных бычьих и медвежьих уровней Фибоначчи. К примеру, установим бычий уровень Фибо равным 38.2 и далее будем получать цену на этом уровне для открытия сделки на покупку. Установив этот уровень для медвежьих свечей будем получать уровень цены для входа в сделку на продажу.

Второй подход: на основе массива определенных свечей

Вторая простая система Simple FIBO 2

По этой стратегии мы будем получать ценовые уровни Фибо на основе массива свечей. Направление рынка (бычье или медвежье) для построения соответствующих уровней Фибоначчи будем определять на основе целого массива свечей.

Имеем следующее:

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

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

Сигналы по уровням Фибоначчи 2: 

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


Схема стратегий по Fibonacci

В этой части построим схемы разработки для написания кода для двух рассмотренных стратегий. Такой план/схема позволяет визуально организовать процесс разработки торговой системы.

Первый подход: на основе дневных данных

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

Простая система Simple FIBO

Схема простой системы Фибоначчи

Сигналы Фибоначчи:

Схема сигналов Фибоначчи

Второй подход: на основе массива определенных свечей

В этом подходе мы будем работать с определенным количеством свечей в массиве. Определим цену открытия первой свечи и закрытие последней, а также максимальное и минимальное значение. Сравнивая цены открытия и закрытия, мы можем определить, какая у нас свеча: бычья или медвежья. И снова, в соответствии с типом движения свечей в этом массиве построим объект Фибоначчи и будем получать сигналы.

Вторая простая система Simple FIBO 2

Вторая простая система Simple FIBO 2

Сигналы Фибоначчи 2

Схема сигналов Фибоначчи 2

Торговая система по Fibonacci

Далее посмотрим, как все, о чем мы до этого говорили, реализовать в торговой системе. Создадим программу, которая будет возвращать уровни Фибоначчи в виде комментария на графике. Мы проверим оба подхода: и с использованием только последней сформированной свечи с дневного таймфрейма, и с выбором определенного количества таких свечей (будем работать с массивом значений). Также узнаем, как на основе каждого из этих двух подходов возвращать сигналы на покупку и продажу на основе уровней Фибоначчи. Давайте рассмотрим все подробно.

Первый подход: на основе дневных данных

Простая система Simple FIBO

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

Определение имени объекта с помощью макро-подстановки (#define) для предварительной обработки исходного кода перед компиляцией.

#define FIB_OBJ "Fibonacci Retracement"

Создаем целочисленную переменную barsTotal.

int barsTotal;

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

  • symbol — имя символа; у нас это _Symbol, то есть рассчитываем по символу текущего графика.
  • timeframe — таймфрейм для расчета? используем дневной D1.
int bars = iBars(_Symbol, PERIOD_D1);

Генерируем условие для определения дневной свечи, которую нужно использовать для объекта Фибоначчи. Параметр barTotal не должен быть равен bars — проверяем с помощью оператора (!=). Кроме того, текущее время должно быть больше, чем время закрытия этой дневной свечи. Для этого используем функцию TimeCurrent и StringToTime, которая преобразует строку со значением времени в значение типа datetime.

if(barsTotal != bars  && TimeCurrent() > StringToTime("00:05"))

Если это условие выполняется, программа будет делать следующее:

Устанавливаем barsTotal в значение bars.

barsTotal=bars;

Удаляем с графика любые объекты FIB_OBJ с помощью функции ObjectDelete. Параметры функции:

  • chart_id — идентификатор графика, используем 0 — текущий график. 
  • name — название объекта (FIB_OBJ).
ObjectDelete(0,FIB_OBJ);

Создаем четыре переменные для значений цен (open, close, high и low), заполняем функциями iOpen, iClose, iHigh и iLow, которые возвращают соответствующие значения нашего дневного бара. Параметры функций:

  • symbol — имя символа; у нас это _Symbol, то есть рассчитываем значение по символу текущего графика.
  • timeframe — период графика для расчетов, используем дневной таймфрейм PERIOD_D1.
  • start — индекс элемента, с которого начинается проверка, мы это значение не используем.
      double open = iOpen(_Symbol,PERIOD_D1,1);
      double close = iClose(_Symbol,PERIOD_D1,1);
      double high = iHigh(_Symbol,PERIOD_D1,1);
      double low = iLow(_Symbol,PERIOD_D1,1);

Определяем время начала и время окончания, которые будут использоваться позже для рисования нашего объекта Фибоначчи. Для этого будем использовать функцию iTime, которая возвращает время открытия бара. Параметры функции:

  • symbol — имя символа; у нас это _Symbol, то есть рассчитываем значение по символу текущего графика.
  • timeframe — период графика для расчетов, используем дневной таймфрейм PERIOD_D1.
  • start — индекс элемента, с которого начинается проверка, здесь укажем 1 для времени начала и 0 для окончания.

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

      datetime startingTime = iTime(_Symbol,PERIOD_D1,1);
      datetime endingTime = iTime(_Symbol,PERIOD_D1,0)-1;

После этого установим два условия, используя условный оператор if-else для рисования объекта Фибоначчи.

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

Создаем объект с помощью функции ObjectCreate для рисования объекта с указанными символами. Параметры функции:

  • chart_id — идентификатор графике, 0 означает текущий график.
  • name — название используемого объекта (FIB_OBJ).
  • type — тип используемого объекта, OBJ_FIBO — уровни фибоначчи
  • nwin — индекс окна, используем 0 — главное окно графика.
  • time1 — время первой точки привязки, у нас оно равно времени начала.
  • price1 — цена первой точки привязки, здесь мы проверяем минимум.
  • timeN=0 — время точки окончания, это время завершения.
  • priceN=0 — цена последней точки, используем максимум.

Обновляем цвета объекта в соответствии с направлением бара с помощью ObjectSetInteger и оператора цикла for. Параметры ObjectSetInteger:

  • chart_id — идентификатор графике, у нас это 0, что означает текущий график.
  • name — название используемого объекта, FIB_OBJ.
  • prop_id — идентификатор свойств (color), OBJPROP_COLOR.
  • prop_value — значение свойства цвета, зеленый clrGreen.
  • Используем цикл for для непрерывного обновления цвета объекта.
Определяем уровни фибоначчи, 23.6 - 38.2 - 50 - 61.8 - 100. Выводим на график комментарий со значениями последнего дня, открытия и закрытия.
      if(close>open)
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,low,endingTime,high);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrGreen);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrGreen);
           }
         double fibRetracLvl1 = NormalizeDouble(high - (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(high - (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(high - (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(high - (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(high - (high-low) * 100 / 100,_Digits);
         Comment("Last Day Open = ",open,"\n",
                 "Last Day Close = ",close,"\n",
                 "Fib lvl 0% = ",high,"\n",
                 "Fib lvl 23.6% = ",fibRetracLvl1,"\n",
                 "Fib lvl 38.2% = ",fibRetracLvl2,"\n",
                 "Fib lvl 50% = ",fibRetracLvl3,"\n",
                 "Fib lvl 61.8% = ",fibRetracLvl4,"\n",
                 "Fib lvl 100% = ",fibRetracLvl5);
        }

Если имеем дело с медвежьей дневной свечой, делаем то же самое, но отличие будет следующим:

  • Создаем объект, начиная от максимума к минимуму.
  • Цвет объекта будет красный.
      else
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,high,endingTime,low);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrRed);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrRed);
           }
         double fibRetracLvl1 = NormalizeDouble(low + (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(low + (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(low + (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(low + (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(low + (high-low) * 100 / 100,_Digits);
         Comment("Last Day Open = ",open,"\n",
                 "Last Day Close = ",close,"\n",
                 "Fib lvl 0% = ",low,"\n",
                 "Fib lvl 23.6% = ",fibRetracLvl1,"\n",
                 "Fib lvl 38.2% = ",fibRetracLvl2,"\n",
                 "Fib lvl 50% = ",fibRetracLvl3,"\n",
                 "Fib lvl 61.8% = ",fibRetracLvl4,"\n",
                 "Fib lvl 100% = ",fibRetracLvl5);
        }

А ниже код этой стратегии.

//+------------------------------------------------------------------+
//|                                         Simple Fibo System#2.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define FIB_OBJ "Fibonacci Retracement"
#property script_show_inputs
input double fibRetracLvl = 38.2;
int barsTotal;
//+------------------------------------------------------------------+
void OnTick()
  {

   int bars = iBars(_Symbol, PERIOD_D1);
   if(barsTotal != bars  && TimeCurrent() > StringToTime("00:05"))
     {
      barsTotal=bars;
      ObjectDelete(0,FIB_OBJ);
      double open = iOpen(_Symbol,PERIOD_D1,1);
      double close = iClose(_Symbol,PERIOD_D1,1);
      double closeCandle = iClose(_Symbol,_Period,1);
      double high = iHigh(_Symbol,PERIOD_D1,1);
      double low = iLow(_Symbol,PERIOD_D1,1);
      datetime startingTime = iTime(_Symbol,PERIOD_D1,1);
      datetime endingTime = iTime(_Symbol,PERIOD_D1,0)-1;
      if(close>open)
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,low,endingTime,high);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrGreen);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrGreen);
           }
         double fibRetracLvl1 = NormalizeDouble(high - (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(high - (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(high - (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(high - (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(high - (high-low) * 100 / 100,_Digits);
         double entryLvl = NormalizeDouble(high - (high-low) * fibRetracLvl /100,_Digits);
         Comment("Last Day Open = ",open,"\n",
                 "Last Day Close = ",close,"\n",
                 "Buy Entry Price: ",entryLvl,"\n",
                 "Close: ",closeCandle,"\n");
        }
      else
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,high,endingTime,low);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrRed);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrRed);
           }
         double fibRetracLvl1 = NormalizeDouble(low + (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(low + (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(low + (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(low + (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(low + (high-low) * 100 / 100,_Digits);
         double entryLvl = NormalizeDouble(low + (high-low) * fibRetracLvl /100,_Digits);
           {
            Comment("Last Day Open = ",open,"\n",
                    "Last Day Close = ",close,"\n",
                    "Sell Entry Price: ",entryLvl,"\n",
                    "Close: ",closeCandle);
           }
        }
     }
  }
//+------------------------------------------------------------------+

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

//+------------------------------------------------------------------+
//|                                         Simple Fibo System#1.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define FIB_OBJ "Fibonacci Retracement"
int barsTotal;
//+------------------------------------------------------------------+
void OnTick()
  {
   int bars = iBars(_Symbol, PERIOD_D1);
   if(barsTotal != bars  && TimeCurrent() > StringToTime("00:05"))
     {
      barsTotal=bars;
      ObjectDelete(0,FIB_OBJ);
      double open = iOpen(_Symbol,PERIOD_D1,1);
      double close = iClose(_Symbol,PERIOD_D1,1);
      double high = iHigh(_Symbol,PERIOD_D1,1);
      double low = iLow(_Symbol,PERIOD_D1,1);
      datetime startingTime = iTime(_Symbol,PERIOD_D1,1);
      datetime endingTime = iTime(_Symbol,PERIOD_D1,0)-1;
      if(close>open)
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,low,endingTime,high);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrGreen);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrGreen);
           }
         double fibRetracLvl1 = NormalizeDouble(high - (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(high - (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(high - (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(high - (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(high - (high-low) * 100 / 100,_Digits);
         Comment("Last Day Open = ",open,"\n",
                 "Last Day Close = ",close,"\n",
                 "Fib lvl 0% = ",high,"\n",
                 "Fib lvl 23.6% = ",fibRetracLvl1,"\n",
                 "Fib lvl 38.2% = ",fibRetracLvl2,"\n",
                 "Fib lvl 50% = ",fibRetracLvl3,"\n",
                 "Fib lvl 61.8% = ",fibRetracLvl4,"\n",
                 "Fib lvl 100% = ",fibRetracLvl5);
        }
      else
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,high,endingTime,low);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrRed);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrRed);
           }
         double fibRetracLvl1 = NormalizeDouble(low + (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(low + (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(low + (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(low + (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(low + (high-low) * 100 / 100,_Digits);
         Comment("Last Day Open = ",open,"\n",
                 "Last Day Close = ",close,"\n",
                 "Fib lvl 0% = ",low,"\n",
                 "Fib lvl 23.6% = ",fibRetracLvl1,"\n",
                 "Fib lvl 38.2% = ",fibRetracLvl2,"\n",
                 "Fib lvl 50% = ",fibRetracLvl3,"\n",
                 "Fib lvl 61.8% = ",fibRetracLvl4,"\n",
                 "Fib lvl 100% = ",fibRetracLvl5);
        }
     }
  }
//+------------------------------------------------------------------+

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

Дневная свеча бычья:

Простая система Фибоначчи - бычья - дневная

Уровни фибоначчи строятся от минимума к максимуму, цвет зеленый, а уровни фибо и открытие/закрытие рассчитываются для дневного графика. Это показано на следующем скриншоте:

Простая система Фибоначчи - бычья

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

  • Last day open — совпадает со значением открытия дневной свечи на графике
  • Last day close — это значение закрытия.
  • Пять уровней Фибоначчи.

Дневная свеча медвежья:

Простая система Фибоначчи - медвежья - дневная

Сейчас уровни фибоначчи строятся от максимума к минимуму, цвет красный, и уровни фибо и открытие/закрытие рассчитываются для дневного графика. Это показано на следующем скриншоте:

Простая система Фибоначчи - медвежья

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

  • The last day open — совпадает со значением открытия дневной свечи на графике
  • The last day close — это значение закрытия.
  • Пять уровней Фибоначчи.

Сигналы Фибоначчи:

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

//+------------------------------------------------------------------+
//|                                         Simple Fibo System#2.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define FIB_OBJ "Fibonacci Retracement"
#property script_show_inputs
input double fibRetracLvl = 38.2;
int barsTotal;
//+------------------------------------------------------------------+
void OnTick()
  {

   int bars = iBars(_Symbol, PERIOD_D1);
   if(barsTotal != bars  && TimeCurrent() > StringToTime("00:05"))
     {
      barsTotal=bars;
      ObjectDelete(0,FIB_OBJ);
      double open = iOpen(_Symbol,PERIOD_D1,1);
      double close = iClose(_Symbol,PERIOD_D1,1);
      double closeCandle = iClose(_Symbol,_Period,1);
      double high = iHigh(_Symbol,PERIOD_D1,1);
      double low = iLow(_Symbol,PERIOD_D1,1);
      datetime startingTime = iTime(_Symbol,PERIOD_D1,1);
      datetime endingTime = iTime(_Symbol,PERIOD_D1,0)-1;
      if(close>open)
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,low,endingTime,high);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrGreen);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrGreen);
           }
         double fibRetracLvl1 = NormalizeDouble(high - (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(high - (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(high - (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(high - (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(high - (high-low) * 100 / 100,_Digits);
         double entryLvl = NormalizeDouble(high - (high-low) * fibRetracLvl /100,_Digits);
         Comment("Last Day Open = ",open,"\n",
                 "Last Day Close = ",close,"\n",
                 "Buy Entry Price: ",entryLvl);
        }
      else
        {
         ObjectCreate(0,FIB_OBJ,OBJ_FIBO,0,startingTime,high,endingTime,low);
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrRed);
         for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
           {
            ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrRed);
           }
         double fibRetracLvl1 = NormalizeDouble(low + (high-low) * 23.6 / 100,_Digits);
         double fibRetracLvl2 = NormalizeDouble(low + (high-low) * 38.2 / 100,_Digits);
         double fibRetracLvl3 = NormalizeDouble(low + (high-low) * 50 / 100,_Digits);
         double fibRetracLvl4 = NormalizeDouble(low + (high-low) * 61.8 / 100,_Digits);
         double fibRetracLvl5 = NormalizeDouble(low + (high-low) * 100 / 100,_Digits);
         double entryLvl = NormalizeDouble(low + (high-low) * fibRetracLvl /100,_Digits);
           {
            Comment("Last Day Open = ",open,"\n",
                    "Last Day Close = ",close,"\n",
                    "Sell Entry Price: ",entryLvl);
           }
        }
     }
  }
//+------------------------------------------------------------------+

Отличия в этом коде:

Добавили свойства для отображения окна, в котором пользователь может ввести значение. Это #property script_show_inputs, которое отображает окно со свойствами.

#property script_show_inputs

Используем входной переменной для создания double fibRetracLvl со значением по умолчанию 38,2.

input double fibRetracLvl = 38.2;

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

double entryLvl = NormalizeDouble(high - (high-low) * fibRetracLvl /100,_Digits);

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

double entryLvl = NormalizeDouble(low + (high-low) * fibRetracLvl /100,_Digits);

Комментарий к графику в случае бычьего тренда.

         Comment("Last Day Open = ",open,"\n",
                 "Last Day Close = ",close,"\n",
                 "Buy Entry Price: ",entryLvl,"\n",
                 "Close: ",closeCandle,"\n");

Комментарий к графику в случае медвежьего тренда.

            Comment("Last Day Open = ",open,"\n",
                    "Last Day Close = ",close,"\n",
                    "Sell Entry Price: ",entryLvl,"\n",
                    "Close: ",closeCandle);

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

Дневная свеча бычья:

Сигнал Фибоначчи - бычий - дневной

Итак, мы должны получить построенные зеленые уровни Фибоначчи, начиная с минимума до максимума на периоде 15 минут, открытие и закрытие последнего дня такие же, как на дневном графике, а уровень входа - уровень цены рядом с 38,2. Для 15-минутного графика имеем следующее:

Сигнал Фибоначчи - бычий - дневной

Итак, это 15-минутный график, на котором у нас есть все построения и необходимые значения:

  • Last day open — уровень открытия дневного графика.
  • Last day close — закрытие.
  • Buy entry price — цена для входа на уровне Фибоначчи 38.2.

Дневная свеча медвежья:

Сигнал Фибоначчи - бычий - дневная свеча

Теперь проверим 15-минутный график, на котором нужно получить сигнал на основе торговой стратегии, он должен показать уровень входа на продажу на основе уровня Фибоначчи 38.2. Проверим на графике ниже:

Сигнал Фибоначчи - медвежий

Как видим, на графике выше сформировался сигнал со следующими значениями:

  • Last day open — уровень открытия дневного графика.
  • Last day close — закрытие.
  • Sell entry price — цена для входа на уровне Фибоначчи 38.2.

Второй подход: на основе массива определенных свечей

Вторая простая система Simple FIBO 2

D рамках этого подхода будем использовать установленное количество свечей, которые будут использоваться для построения уровней Фибоначчи. Рассмотрим шаг за шагом, как это сделать:

Определение FIB_OBJ с помощью #define.

#define FIB_OBJ "Fibonacci Retracement"

Создаем целочисленные переменные для максимального и минимального значения.

int highestCandle, lowestCandle;

Создание двух массивов для максимумом и минимумов.

double high[],low[];

Сортировка данных в массивах с помощью функции ArraySetAsSeries. Параметры функции:

  • array[] — определяем созданные массивы.
  • flag — устанавливаем направление индексирования в массиве, true.
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);

Получаем исторические данные максимумов и минимумов с помощью функций CopyHigh и CopyLow. Параметры CopyHigh:

  • symbol_name — название символа; укажем _Symbol, чтобы использовать текущий.
  • period — период расчета индикатора; используем текущий период (_period) 
  • start_pos — установим позицию начала расчета, укажем 0 для начала на текущей свече.
  • count — количество данных для копирования, укажем 100
  • high_array[] — целевой массив, у нас это high.

Для CopyLow параметры будут такими же, но в качестве целевого массива будет создан массив low.

CopyHigh(_Symbol,_Period,0,100,high);
CopyLow(_Symbol,_Period,0,100,low);

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

double openCandle = iOpen(_Symbol,_Period,100);
double closeCandle = iClose(_Symbol,_Period,1);

Определяем максимальное и минимальное значения в созданных массивах high и low, используя функции ArrayMaximum и ArrayMinimum. Параметры функций:

  • array[] — массив, high для максимумов и low для минимумов.
  • start=0 — индекс элемента, с которого начинается проверка, используем 0.
  • count— количество проверяемых элементов, у нас оно равно 100 или WHOLE_ARRAY .
highestCandle=ArrayMaximum(high,0,100);
lowestCandle=ArrayMinimum(low,0,100);

Создаем массив цен с помощью функции MqlRates для хранения информации о ценах и сортируем данные в этом массиве с помощью функции ArraySetAsSeries.

MqlRates pArray[];
ArraySetAsSeries(pArray,true);

Получаем исторические данные из MqlRates функцией CopyRates. Параметры функции:

  • symbol_name — имя символа для расчета индикатора, _Symbol — текущий символ.
  • timeframe — таймфрейм для расчета, _Period означает текущий таймфрейм графика.
  • start_pos — позиция начала расчета индикатора, укажем 0 для расчета от текущей позиции
  • count — количество данных для копирования, Bars.
  • rates_array[] — массив, в который копируем данные, pArray
int pData=CopyRates(_Symbol,_Period,0,Bars(_Symbol,_Period),pArray);

Определяем dateTime и цены нулевого уровня и уровня 100 с помощью ObjectGetInteger и ObjectGetDouble

datetime dTlvl0 = ObjectGetInteger(0,"Fibonacci Retracement",OBJPROP_TIME,0);
double PriceFibLvl00 = ObjectGetDouble(0,"Fibonacci Retracement",OBJPROP_PRICE,0);
datetime dTlvl1 = ObjectGetInteger(0,"Fibonacci Retracement",OBJPROP_TIME,1);
double PriceFibLvl0 = ObjectGetDouble(0,"Fibonacci Retracement",OBJPROP_PRICE,1);

Установка условий бычьего и медвежьего тренда с помощью оператора if-else.

В случае бычьего (CloseCandle больше, чем openCandle) следующие шаги будут такими:

  • Удаляем ранее построенный объект FIBO с помощью ObjectDelete.
  • Создаем новый объект FIBO, начиная с минимума и заканчивая максимумом массива, с помощью ObjectCreate.
  • Обновляем цвета объекта FIBO - меняем на зеленый с помощью ObjectSetInteger и цикла for для продолжения обновления в соответствии с трендом.
  • Определяем ценовой диапазон, получая разницу между максимумом и минимумом.
  • Определяем уровни FIBO, 23.6 - 38.2 - 50 - 61.8.
  • Выводим на график комментарий с уровнями Array Open, Array Close и FIBO.
   if(closeCandle>openCandle)
     {
      ObjectDelete(_Symbol, "Fibonacci Retracement");
      ObjectCreate(_Symbol, "Fibonacci Retracement",OBJ_FIBO,0,pArray[100].time,
                   pArray[lowestCandle].low,pArray[0].time,pArray[highestCandle].high);
      ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrGreen);
      for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
        {
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrGreen);
        }
      double pRange =  PriceFibLvl0 - PriceFibLvl00;
      double PriceFibLvl1 = NormalizeDouble (PriceFibLvl0 - pRange * 23.6/100,_Digits);
      double PriceFibLvl2 = NormalizeDouble (PriceFibLvl0 - pRange * 38.2/100,_Digits);
      double PriceFibLvl3 = NormalizeDouble (PriceFibLvl0 - pRange * 50/100,_Digits);
      double PriceFibLvl4 = NormalizeDouble(PriceFibLvl0 - pRange * 61.8/100,_Digits);
      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Fib lvl 0% = ",PriceFibLvl0,"\n",
              "Fib lvl 23.6% = ",PriceFibLvl1,"\n",
              "Fib lvl 38.2% = ",PriceFibLvl2,"\n",
              "Fib lvl 50% = ",PriceFibLvl3,"\n",
              "Fib lvl 61.8% = ",PriceFibLvl4,"\n",
              "Fib lvl 100% = ",PriceFibLvl00);
     }

В случае медвежьего тренда (CloseCandle меньше, чем openCandle) шаги будут такими:

  • Удаляем ранее построенный объект FIBO с помощью ObjectDelete.
  • Создаем новый объект FIBO, начиная с максимума и заканчивая минимумом массива, с помощью ObjectCreate.
  • Обновляем цвета объекта FIBO - меняем на красный с помощью ObjectSetInteger и цикла for для продолжения обновления в соответствии с трендом.
  • Определяем ценовой диапазон, получая разницу между минимумом и максимумом.
  • Определяем уровни FIBO, 23.6 - 38.2 - 50 - 61.8.
  • Выводим на график комментарий с уровнями Array Open, Array Close и FIBO.
   else
     {
      ObjectDelete(_Symbol, "Fibonacci Retracement");
      ObjectCreate(_Symbol, "Fibonacci Retracement",OBJ_FIBO,0,pArray[100].time,
                   pArray[highestCandle].high,pArray[0].time,pArray[lowestCandle].low);
      ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrRed);
      for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
        {
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrRed);
        }
      double pRange =  PriceFibLvl00 - PriceFibLvl0;
      double PriceFibLvl1 = NormalizeDouble (PriceFibLvl0 + pRange * 23.6/100,_Digits);
      double PriceFibLvl2 = NormalizeDouble (PriceFibLvl0 + pRange * 38.2/100,_Digits);
      double PriceFibLvl3 = NormalizeDouble(PriceFibLvl0 + pRange * 50/100,_Digits);
      double PriceFibLvl4 = NormalizeDouble (PriceFibLvl0 + pRange * 61.8/100,_Digits);
      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Fib lvl 0% = ",PriceFibLvl0,"\n",
              "Fib lvl 23.6% = ",PriceFibLvl1,"\n",
              "Fib lvl 38.2% = ",PriceFibLvl2,"\n",
              "Fib lvl 50% = ",PriceFibLvl3,"\n",
              "Fib lvl 61.8% = ",PriceFibLvl4,"\n",
              "Fib lvl 100% = ",PriceFibLvl00);
     }

Ниже приведен полный код:

//+------------------------------------------------------------------+
//|                                         Simple Fibo System 2.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define FIB_OBJ "Fibonacci Retracement"
//+------------------------------------------------------------------+
void OnTick()
  {
   int highestCandle, lowestCandle;
   double high[],low[];
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   CopyHigh(_Symbol,_Period,0,100,high);
   CopyLow(_Symbol,_Period,0,100,low);
   double openCandle = iOpen(_Symbol,_Period,100);
   double closeCandle = iClose(_Symbol,_Period,1);
   highestCandle=ArrayMaximum(high,0,100);
   lowestCandle=ArrayMinimum(low,0,100);
   MqlRates pArray[];
   ArraySetAsSeries(pArray,true);
   int pData=CopyRates(_Symbol,_Period,0,Bars(_Symbol,_Period),pArray);
   datetime dTlvl0 = ObjectGetInteger(0,"Fibonacci Retracement",OBJPROP_TIME,0);
   double PriceFibLvl00 = ObjectGetDouble(0,"Fibonacci Retracement",OBJPROP_PRICE,0);
   datetime dTlvl1 = ObjectGetInteger(0,"Fibonacci Retracement",OBJPROP_TIME,1);
   double PriceFibLvl0 = ObjectGetDouble(0,"Fibonacci Retracement",OBJPROP_PRICE,1);
   if(closeCandle>openCandle)
     {
      ObjectDelete(_Symbol, "Fibonacci Retracement");
      ObjectCreate(_Symbol, "Fibonacci Retracement",OBJ_FIBO,0,pArray[100].time,
                   pArray[lowestCandle].low,pArray[0].time,pArray[highestCandle].high);
      ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrGreen);
      for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
        {
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrGreen);
        }
      double pRange =  PriceFibLvl0 - PriceFibLvl00;
      double PriceFibLvl1 = NormalizeDouble (PriceFibLvl0 - pRange * 23.6/100,_Digits);
      double PriceFibLvl2 = NormalizeDouble (PriceFibLvl0 - pRange * 38.2/100,_Digits);
      double PriceFibLvl3 = NormalizeDouble (PriceFibLvl0 - pRange * 50/100,_Digits);
      double PriceFibLvl4 = NormalizeDouble(PriceFibLvl0 - pRange * 61.8/100,_Digits);
      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Fib lvl 0% = ",PriceFibLvl0,"\n",
              "Fib lvl 23.6% = ",PriceFibLvl1,"\n",
              "Fib lvl 38.2% = ",PriceFibLvl2,"\n",
              "Fib lvl 50% = ",PriceFibLvl3,"\n",
              "Fib lvl 61.8% = ",PriceFibLvl4,"\n",
              "Fib lvl 100% = ",PriceFibLvl00);
     }
   else
     {
      ObjectDelete(_Symbol, "Fibonacci Retracement");
      ObjectCreate(_Symbol, "Fibonacci Retracement",OBJ_FIBO,0,pArray[100].time,
                   pArray[highestCandle].high,pArray[0].time,pArray[lowestCandle].low);
      ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrRed);
      for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
        {
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrRed);
        }
      double pRange =  PriceFibLvl00 - PriceFibLvl0;
      double PriceFibLvl1 = NormalizeDouble (PriceFibLvl0 + pRange * 23.6/100,_Digits);
      double PriceFibLvl2 = NormalizeDouble (PriceFibLvl0 + pRange * 38.2/100,_Digits);
      double PriceFibLvl3 = NormalizeDouble(PriceFibLvl0 + pRange * 50/100,_Digits);
      double PriceFibLvl4 = NormalizeDouble (PriceFibLvl0 + pRange * 61.8/100,_Digits);
      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Fib lvl 0% = ",PriceFibLvl0,"\n",
              "Fib lvl 23.6% = ",PriceFibLvl1,"\n",
              "Fib lvl 38.2% = ",PriceFibLvl2,"\n",
              "Fib lvl 50% = ",PriceFibLvl3,"\n",
              "Fib lvl 61.8% = ",PriceFibLvl4,"\n",
              "Fib lvl 100% = ",PriceFibLvl00);
     }
  }
//+------------------------------------------------------------------+

Компилируем код и запускаем из Навигатора на график. Советник будет генерировать сигналы. Ниже приведены примеры тестовых сигналов.

В случае бычьего массива:

Простая система Фибоначчи 2 - бычья

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

  • Array open — значение открытие в массиве.
  • Array close — значение закрытия в массиве.
  • Уровни Фибоначчи 0, 23.6, 38.2, 50, 61.8, 100.

В случае медвежьего массива:

Простая система Фибоначчи 2 - медвежья

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

  • Array open — значение открытие в массиве.
  • Array close — значение закрытия в массиве.
  • Уровни Фибоначчи 0, 23.6, 38.2, 50, 61.8, 100.

Сигналы Фибоначчи 2

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

//+------------------------------------------------------------------+
//|                                               Fibo Signals 2.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define FIB_OBJ "Fibonacci Retracement"
#property script_show_inputs
input double fibRetracLvl = 38.2;
//+------------------------------------------------------------------+
void OnTick()
  {
   int highestCandle, lowestCandle;
   double high[],low[];
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   CopyHigh(_Symbol,_Period,0,100,high);
   CopyLow(_Symbol,_Period,0,100,low);
   double openCandle = iOpen(_Symbol,_Period,100);
   double closeCandle = iClose(_Symbol,_Period,1);
   highestCandle=ArrayMaximum(high,0,100);
   lowestCandle=ArrayMinimum(low,0,100);
   MqlRates pArray[];
   ArraySetAsSeries(pArray,true);
   int pData=CopyRates(_Symbol,_Period,0,Bars(_Symbol,_Period),pArray);
   datetime dTlvl0 = ObjectGetInteger(0,"Fibonacci Retracement",OBJPROP_TIME,0);
   double PriceFibLvl00 = ObjectGetDouble(0,"Fibonacci Retracement",OBJPROP_PRICE,0);
   datetime dTlvl1 = ObjectGetInteger(0,"Fibonacci Retracement",OBJPROP_TIME,1);
   double PriceFibLvl0 = ObjectGetDouble(0,"Fibonacci Retracement",OBJPROP_PRICE,1);
   if
   (closeCandle>openCandle)
     {
      ObjectDelete(_Symbol, "Fibonacci Retracement");
      ObjectCreate(_Symbol, "Fibonacci Retracement",OBJ_FIBO,0,pArray[100].time,
                   pArray[lowestCandle].low,pArray[0].time,pArray[highestCandle].high);
      ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrGreen);
      for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
        {
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrGreen);
        }
      double pRange =  PriceFibLvl0 - PriceFibLvl00;
      double PriceFibLvl1 = NormalizeDouble(PriceFibLvl0 - pRange * 23.6/100,_Digits);
      double PriceFibLvl2 = NormalizeDouble(PriceFibLvl0 - pRange * 38.2/100,_Digits);
      double PriceFibLvl3 = NormalizeDouble(PriceFibLvl0 - pRange * 50/100,_Digits);
      double PriceFibLvl4 = NormalizeDouble(PriceFibLvl0 - pRange * 61.8/100,_Digits);
      double entryLvl = NormalizeDouble(PriceFibLvl0 - pRange * fibRetracLvl/100,_Digits);
      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Buy Entry Price: ",entryLvl);
     }
   else
     {
      ObjectDelete(_Symbol, "Fibonacci Retracement");
      ObjectCreate(_Symbol, "Fibonacci Retracement",OBJ_FIBO,0,pArray[100].time,
                   pArray[highestCandle].high,pArray[0].time,pArray[lowestCandle].low);
      ObjectSetInteger(0,FIB_OBJ,OBJPROP_COLOR,clrRed);
      for(int i = 0; i < ObjectGetInteger(0,FIB_OBJ,OBJPROP_LEVELS); i++)
        {
         ObjectSetInteger(0,FIB_OBJ,OBJPROP_LEVELCOLOR,i,clrRed);
        }
      double pRange =  PriceFibLvl00 - PriceFibLvl0;
      double PriceFibLvl1 = NormalizeDouble(PriceFibLvl0 + pRange * 23.6/100,_Digits);
      double PriceFibLvl2 = NormalizeDouble(PriceFibLvl0 + pRange * 38.2/100,_Digits);
      double PriceFibLvl3 = NormalizeDouble(PriceFibLvl0 + pRange * 50/100,_Digits);
      double PriceFibLvl4 = NormalizeDouble(PriceFibLvl0 + pRange * 61.8/100,_Digits);
      double entryLvl = NormalizeDouble(PriceFibLvl0 + pRange * fibRetracLvl/100,_Digits);
      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Sell Entry Price: ",entryLvl);
     }
  }
//+------------------------------------------------------------------+

Отличия в этом коде:

Здесь мы добавили свойство #property script_show_inputs, которое выводит окно со свойствами. Используем входную переменную, создаем fibRetracLvl типа double, например, со значением по умолчанию 38,2.

#property script_show_inputs
input double fibRetracLvl = 38.2;

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

double entryLvl = NormalizeDouble(PriceFibLvl0 - pRange * fibRetracLvl/100,_Digits);

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

double entryLvl = NormalizeDouble(PriceFibLvl0 + pRange * fibRetracLvl/100,_Digits);

Комментарий для бычьего Фибоначчи.

      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Buy Entry Price: ",entryLvl);

Комментарий для медвежьего Фибоначчи.

      Comment("Array Open: ",openCandle,"\n",
              "Array Close: ",closeCandle,"\n",
              "Sell Entry Price: ",entryLvl);

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

Массив бычий:

Сигнал Фибоначчи 2 - бычий - дневной

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

  • Array open — значение открытие в массиве.
  • Array close — значение закрытия в массиве.
  • Buy entry price — цена для входа в покупку на уровне Фибоначчи 38.2.

В случае медвежьего массива:

Сигнал Фибоначчи 2 - медвежий

На графике имеем уровни Фибоначчи красного цвета от максимума к минимуму, на графике комментарий со следующими значениями:

  • Array open — значение открытие в массиве.
  • Array close — значение закрытия в массиве.
  • Sell entry price — цена для входа в сделку на продажу на уровне Фибоначчи 38.2.


Заключение

Итак, мы с вами узнали, как создать простую торговую систему по уровням Фибоначчи с использованием MQL5. Эта торговая система предназначена для работы в торговом терминале MetaTrader 5. Перед созданием стратегий мы подробно рассмотрели сам технический инструмент Фибоначчи, узнали, как использовать его в MetaTrader 5.

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

Надеюсь, эта статья поможет сделать вашу торговлю чуточку лучше, подскажет новые идеи. Желаю всем вам прибыльной торговли! Если статья понравилась, если вы считаете ее полезной, почитайте мои предыдущие статьи из этой же серии, чтобы узнать, как разрабатывать торговые системы на основе различных популярных технических индикаторов. Так, ранее мы изучали индикаторы Stochastic, RSI, Bollinger Bands, Moving Averages, Envelopes, MACD, ADX и другие.

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

Прикрепленные файлы |
Fibo_Signals.mq5 (3.37 KB)
Fibo_Signals_2.mq5 (3.79 KB)
Нейросети — это просто (Часть 43): Освоение навыков без функции вознаграждения Нейросети — это просто (Часть 43): Освоение навыков без функции вознаграждения
Проблема обучения с подкреплением заключается в необходимости определения функции вознаграждения, которая может быть сложной или затруднительной для формализации, и для решения этой проблемы исследуются подходы, основанные на разнообразии действий и исследовании окружения, которые позволяют обучаться навыкам без явной функции вознаграждения.
Как создать советник, который торгует автоматически (Часть 14): Автоматизация (VI) Как создать советник, который торгует автоматически (Часть 14): Автоматизация (VI)
Здесь мы действительно применим на практике все знания этой серии статей. Наконец мы построим 100% автоматическую и функциональную систему, но для этого нам придется научиться одной последней детали.
Как построить советник, работающий автоматически (Часть 15): Автоматизация (VII) Как построить советник, работающий автоматически (Часть 15): Автоматизация (VII)
Чтобы завершить этот цикл статей об автоматизации, мы дополним то, что рассмотрели в предыдущей статье. Это определенно показывает, как всё будет сочетаться друг с другом, заставляя советника работать как часы.
Как построить советник, работающий автоматически (Часть 13): Автоматизация (V) Как построить советник, работающий автоматически (Часть 13): Автоматизация (V)
Знаете ли вы, что такое блок-схема? Умеете ли вы ее использовать? Думаете ли вы, что блок-схемы - это дело начинающих программистов? Тогда я вам предлагаю ознакомиться с этой статьей и узнать, как работать с блок-схемами.