English 中文 Español Deutsch 日本語 Português
preview
Вспоминаем старую трендовую стратегию: два стохастических осциллятора, MA и Фибоначчи

Вспоминаем старую трендовую стратегию: два стохастических осциллятора, MA и Фибоначчи

MetaTrader 5Торговые системы | 5 октября 2023, 13:04
1 688 0
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

Введение в стратегию

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

  • 14-периодный стохастический осциллятор.
  • Пятипериодный стохастический осциллятор.
  • Скользящую среднюю с периодом 200.
  • Проекцию Фибоначчи (для установки целевых уровней).

Стохастический осциллятор — популярный инструмент технического анализа, используемый трейдерами и инвесторами для измерения импульса и силы движения цен финансового инструмента. Он был разработан Джорджем Лэйном в конце 1950-х годов. Стохастик ограничен значениями от 0 до 100, при этом значения, близкие к нижней границе, называются уровнями перепроданности (бычий уклон), а значения, близкие к верхней границе, - уровнями перекупленности (медвежий уклон).

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

Stoch

где High и Low — это самые высокие и самые низкие цены за последние 5 дней соответственно, а %D — скользящее среднее %K за N дней (последние N значений %K). Обычно это простое скользящее среднее, но может быть и экспоненциальным с менее стандартизированным взвешиванием для более поздних значений. При работе исключительно с %D есть только один достоверный сигнал – расхождение между %D и анализируемой ценной бумагой.

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

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


Реализация стратегии

Правила стратегии следующие:

  • Сигнал на покупку генерируется всякий раз, когда оба стохастических осциллятора одновременно достигают уровня перепроданности, отскакивают, а затем возвращаются к нему (примерно в одно и то же время). Всё это должно произойти, пока рынок находится выше 200-периодной скользящей средней. Первый целевой уровень устанавливается с помощью проекции Фибоначчи, применяемой от минимума первого раза, когда стохастические осцилляторы достигли своего дна, и минимума второго раза, когда они достигли своего дна. Таким образом, первая цель — это проекция 61,8%, а вторая цель — проекция 100,0%.
  • Сигнал на продажу генерируется всякий раз, когда оба стохастических осциллятора одновременно достигают уровня перекупленности, отскакивают, а затем возвращаются к нему (примерно в одно и то же время). Всё это должно произойти, пока рынок находится ниже 200-периодной скользящей средней. Первая цель устанавливается с помощью инструмента проекции Фибоначчи, применяемого от максимума первого раза, когда стохастические осцилляторы достигли своей вершины, и максимума второго раза, когда они достигли своей вершины. Таким образом, первая цель — это проекция 61,8%, а вторая цель — проекция 100,0%.

(Я внес изменения в стратегию, чтобы иметь стоп-уровни на каждом уровне Фибоначчи)

На следующем рисунке показан медвежий сигнал:

bearish


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

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

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

Прогноз коррекции Фибоначчи создается с помощью двух крайних точек на графике и деления вертикального расстояния на коэффициенты Фибоначчи. 0% считается началом коррекции, а 100% — полным разворотом к первоначальной цене до движения. Горизонтальные линии рисуются на графике (не в этом советнике) для этих ценовых уровней, чтобы обеспечить уровни поддержки и сопротивления.

Общие уровни - 23,6%, 38,2%, 50% и 61,8%.


Результаты

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

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

   int Highest = iHighest(Symbol(),my_timeframe,MODE_CLOSE,shift,1);
   double High0=iHigh(Symbol(),my_timeframe,0);


   int Lowest = iLowest(Symbol(),my_timeframe,MODE_CLOSE,shift,1);
   double Low0=iLow(Symbol(),my_timeframe,0);

Но в целях тестирования мы будем использовать меньшее значение сдвига (например, 300).

Это результаты для сдвига =300, таймфрейм = 30 минут, период - с 2013 до 2023 (20 июня) и риск 2%.

График

data

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

sharpe



Код

В OnInit мы объявим технические характеристики, которые собираемся использовать, хэндлы:

void OnInit()
  {
   Stochastic_handle1 = iStochastic(_Symbol, PERIOD_CURRENT, Signal_0_Stoch_PeriodK, Signal_0_Stoch_PeriodD, Signal_0_Stoch_PeriodSlow, MODE_SMA, STO_LOWHIGH);
   Stochastic_handle2 = iStochastic(_Symbol, PERIOD_CURRENT, Signal_1_Stoch_PeriodK, Signal_1_Stoch_PeriodD, Signal_1_Stoch_PeriodSlow, MODE_SMA, STO_LOWHIGH);

//--- create handle of the indicator iMA
   handle_iMA=iMA(_Symbol,PERIOD_CURRENT,Inp_MA_ma_period,Inp_MA_ma_shift,
                  Inp_MA_ma_method,Inp_MA_applied_price);


//Test

   Alert("Expert Advisor has been launched");

  }

Этот код создает хэндл индикатора Stochastic. Хэндл называется Stochastic_handle1. Для его создания используется функция iStochastic(). В функцию передаются следующие параметры: символ, текущий период, период линии %K, период линии %D, период медленной линии, режим медленной линии и тип стохастика (низкий/высокий).

Этот код используется для расчета скользящей средней (MA) текущего символа с указанными параметрами. Переменная handle_iMA хранит результат расчета MA. Параметры, используемые в расчете, — это символ, текущий период, период MA, сдвиг MA, метод MA и применяемая цена. Символ — это валютная пара или ценная бумага, для которой рассчитывается MA. Текущий период — это таймфрейм графика, для которого рассчитывается MA. Период MA — это количество баров, используемых для расчета MA. Сдвиг MA — это количество баров, на которое сдвигается расчет MA. Метод MA — это тип расчета MA, например простая, экспоненциальная, сглаженная или линейно-взвешенная. Применяемая цена — это тип цены, используемый при расчете MA, например Close (закрытие), Open (открытие), High (максимум), Low (минимум), Median (медиана), Typical (типичная) или Weighted (взвешенная).

Нам придется ввести все эти параметры, объявленные снаружи и до OnInit.


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

   MqlTick tick;
   SymbolInfoTick(_Symbol,tick);

Этот код используется для получения тиковых данных для данного символа. В первой строке объявляется переменная MqlTick с именем tick. Вторая строка вызывает функцию SymbolInfoTick(), которая принимает два параметра, имя символа и переменную tick. Функция получает тиковые данные для данного символа и сохраняет их в переменной tick.


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

int Highest = iHighest(Symbol(),my_timeframe,MODE_CLOSE,shift,1);
   double High0=iHigh(Symbol(),my_timeframe,0);


   int Lowest = iLowest(Symbol(),my_timeframe,MODE_CLOSE,shift,1);
   double Low0=iLow(Symbol(),my_timeframe,0);



   double highestValue = iHigh(Symbol(),my_timeframe,Highest);


   double lowestValue = iLow(Symbol(),my_timeframe,Lowest);
// Obtener el valor más alto y más bajo de la barra actual
   double currentHigh = High0;
   double currentLow = Low0;

// Obtener el valor más alto y más bajo de la barra anterior
   double previousHigh = highestValue;
   double previousLow = lowestValue;


   double level0s = currentHigh;
   double level1s = currentHigh - (currentHigh - previousLow) * 0.236;
   double level2s = currentHigh - (currentHigh - previousLow) * 0.382;
   double level3s = currentHigh - (currentHigh - previousLow) * 0.618;
   double level4s = previousLow;

   double level0b = currentLow;
   double level1b = currentLow + (-currentLow + previousHigh) * 0.236;
   double level2b = currentLow + (-currentLow + previousHigh) * 0.382;
   double level3b = currentLow + (-currentLow + previousHigh) * 0.618;
   double level4b = previousHigh;

Этот код на языке MQL5 используется для определения максимального и минимального значений данного символа и периода. Первые две строки кода присваивают наибольшее значение символа и периода переменной Highest, а наибольшее значение символа и периода при заданном сдвиге=0 переменной High0 (текущая свеча). Следующие две строки кода присваивают наименьшее значение символа и периода переменной Lowest, а наименьшее значение символа и периода при заданном сдвиге=0 переменной Low0.


Мы будем использовать сдвиг, чтобы выбрать, на сколько свечей мы будем смотреть назад.

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

//---
   double array_ma[];
   ArraySetAsSeries(array_ma,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iMA,0,start_pos,count,array_ma))
      return;

Этот код используется для получения массива скользящих средних из хэндла. В первой строке объявляется массив array_ma, который будет использоваться для хранения скользящих средних. Вторая строка задает массив как серию. Третья и четвертая строки объявляют две целочисленные переменные start_pos и count, которые будут использоваться для указания начальной позиции и количества элементов, извлекаемых из хэндла. Пятая строка использует функцию iGetArray для получения скользящих средних из хэндла и их сохранения в array_ma. Функция возвращает false, если получить скользящие средние не удалось.

Код следующий (за пределами OnInit)

bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      //if(InpPrintLog)
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      //if(InpPrintLog)
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }

Этот код используется для копирования части индикаторного буфера в массив. Он принимает пять параметров: хэндл, буфер, начальную позицию, счетчик и буфер массива. Сначала он проверяет, является ли буфер массива динамическим, а если нет, выводит сообщение об ошибке. Затем он сбрасывает код ошибки и копирует буфер в буфер массива. Если скопированная сумма не равна счетчику, печатается сообщение об ошибке и возвращается false. В противном случае - true.


Код для отображения результатов на графике:

   string text="";
   for(int i=0; i<count; i++)
      text=text+IntegerToString(i)+": "+DoubleToString(array_ma[i],Digits()+1)+"\n";
//---
   Comment(text);

Этот код используется для вывода значений массива типа double на языке MQL5. Код начинается с объявления строковой переменной с именем text и присвоения ей пустой строки. Затем для перебора массива используется цикл for, при этом переменная i используется в качестве счетчика цикла. Для каждой итерации значение i преобразуется в строку с помощью функции IntegerToString(), а значение массива по этому индексу преобразуется в строку с помощью функции DoubleToString(). Функция Digits() используется для определения количества десятичных знаков, используемых при преобразовании двойного значения в строку. Преобразованные значения затем объединяются в строку text, при этом после каждого значения добавляется новый символ строки. Наконец, функция Comment() используется для распечатки строки text.


Мы сделаем то же самое с обоими стохастиками.

Мы настроим условия, чтобы одновременно не было открыто более одного ордера:

   int total = PositionsTotal();

   if(total==0)
{
...code
}

   if(total>0)
{
...code
}

Для открытия ордеров используем код:

if(!trade.Buy(get_lot(tick.bid),_Symbol,tick.bid,newStopLossLevelb1,newTakeProfitLevelb2))
                 {
                  //--- failure message
                  Print("Buy() method failed. Return code=",trade.ResultRetcode(),
                        ". Code description: ",trade.ResultRetcodeDescription());
                 }
               else
                 {
                  Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
                        " (",trade.ResultRetcodeDescription(),")");
                 }

Здесь мы будем последовательно использовать Ticket.bid, а также SL и TP. TP будет самым высоким максимумом периода сдвига, а SL будет минимумом фактической свечи.

Чтобы закрыть ордер, когда цена пересекает MA, мы будем использовать следующий код:

if(rates[1].close >array_ma22[0])
           {

            trade.PositionClose(_Symbol,5);
            Print("cerro");
            return;
           }
         else
            return;

        }

Чтобы изменить TP и SL, используем код:

            //--- setting the operation parameters
            request.action  =TRADE_ACTION_SLTP; // type of trade operation
            request.position=position_ticket;   // ticket of the position
            request.symbol=position_symbol;     // symbol
            request.sl      =newStopLossLevelss;                  // Stop Loss of the position
            request.tp      =newTakeProfitLevelss;               // Take Profit of the position
            request.magic=Expert_MagicNumber;         // MagicNumber of the position
            //--- output information about the modification
            PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
            //--- send the request
            if(!OrderSend(request,result))
               PrintFormat("OrderSend error %d",GetLastError());  // if unable to send the request, output the error code
            //--- information about the operation
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);

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

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


Заключение

Представленная стратегия может быть прибыльной в некоторые периоды времени, но может оказаться неэффективной в других обстоятельствах. Во время кризиса 2008–2014 годов и ковидного кризиса 2020 года стратегия показала себя плохо. 

Стратегия хорошо работает в некризисные времена и трендовые периоды.

Она выдает коэффициент Шарпа около 4, это означает, что стратегия как минимум надежна.

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

Вы можете менять ее по своему усмотрению.

Цель статьи - помочь людям понять стратегию. Стратегия не предназначена для использования. Применяйте ее на своих страх и риск.

Я рекомендую вам протестировать этого робота на большем количестве таймфреймов и на других символах.

Использование других таймфреймов, вероятно, даст другие результаты.

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

Прикрепленные файлы |
2Stoch_1MA.mq5 (77.39 KB)
Теория категорий в MQL5 (Часть 13): События календаря со схемами баз данных Теория категорий в MQL5 (Часть 13): События календаря со схемами баз данных
В статье рассматривается, как схемы баз данных могут быть включены для классификации в MQL5. Мы кратко рассмотрим, как концепции схемы базы данных могут сочетаться с теорией категорий при идентификации текстовой (строковой) информации, имеющей отношение к торговле. В центре внимания будут находиться события календаря.
Создавать графические панели в MQL5 стало проще Создавать графические панели в MQL5 стало проще
В этой статье мы предоставим простое и понятное руководство для всех, кто хочет создать один из самых ценных и полезных инструментов в трейдинге — графическую панель, упрощающую выполнение торговых задач. Графические панели позволяют сэкономить время и больше сосредоточиться на самой торговле.
Библиотека численного анализа ALGLIB в MQL5 Библиотека численного анализа ALGLIB в MQL5
В этой статье мы кратко рассмотрим библиотеку численного анализа ALGLIB 3.19, ее приложения и новые алгоритмы, позволяющие повысить эффективность анализа финансовых данных.
Разработка системы репликации - Моделирование рынка (Часть 16): Новая система классов Разработка системы репликации - Моделирование рынка (Часть 16): Новая система классов
Нам нужно лучше организовать свою работу. Код растёт, и если этого не сделать сейчас, потом это станет невозможным. Давайте разделять и властвовать. То, что MQL5 позволяет нам использовать классы, поможет нам в этой задаче, но для этого нам нужно иметь некоторые знания о некоторых моментах, связанных с классами. Наверное, новичков больше всего смущает наследование. В этой статье мы рассмотрим практичным и простым способом, как использовать данные механизмы.