English 中文 Español Deutsch 日本語 Português
preview
Автооптимизация тейк-профитов и параметров индикатора с помощью SMA и EMA

Автооптимизация тейк-профитов и параметров индикатора с помощью SMA и EMA

MetaTrader 5Примеры |
1 022 4
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

Введение

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

Подход советника многогранен и использует прогнозирование цен с помощью модели машинного обучения, методы отслеживания трендов и адаптивную оптимизацию параметров. Он предназначен в первую очередь для работы с акциями #AAPL, хотя его можно адаптировать и для других инструментов. Благодаря таким функциям, как динамическое определение размера лота, трейлинг-стопы и автоматическая подстройка под рыночные условия, этот советник представляет собой сочетание передовых технологий и проверенных временем принципов торговли.

Используемые индикаторы:

  1. Простая скользящая средняя (SMA): Советник использует простую скользящую среднюю с адаптивно оптимизируемым периодом. SMA помогает определить общее направление тренда и используется в сочетании с ценовыми и другими индикаторами для генерации торговых сигналов.
  2. Экспоненциальная скользящая средняя (EMA): Также используется с динамически оптимизируемым периодом. EMA быстрее реагирует на последние изменения цен, чем SMA, обеспечивая иной взгляд на направление тренда.
  3. Средний истинный диапазон (Average True Range, ATR): Хотя индикатор явно не рассчитывается в коде, советник использует расчеты на основе ATR для установки уровней стоп-лосса и тейк-профита. Это позволяет корректировать размер позиции и управлять рисками с учетом волатильности.
  4. Модель машинного обучения: Советник использует модель ONNX (Open Neural Network Exchange) для прогнозирования цен. Эта модель учитывает ряд последних ценовых данных и пытается спрогнозировать следующее движение цены, добавляя прогностический элемент в торговую стратегию.

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

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


Обзор кода

1. Первоначальная настройка и включаемые файлы:

Код начинается с информации об авторских правах и включает необходимые библиотеки, такие как Trade.mqh.

#include <Trade\Trade.mqh>

2. Глобальные переменные и параметры:

  • Определяются параметры модели ONNX, включая размер выборки и хэндлы.
  • Объявляются входные параметры для индикаторов (SMA, EMA, ATR) и торговых операций.
  • Определяются перечисления и константы для движения цен и магических чисел.

#resource "/Files/model.EURUSD.D1.1_1_2024.onnx" as uchar ExtModel[];
input group "----- Indicators Parameters -----"
int SMA_Period = 20;
int EMA_Period = 50;

input double StopLossATR = 1.5;
input double TakeProfitATR = 3.0;
input int OptimizationDays = 1;        // Hours between optimizations
input int LookbackPeriod = 7;         // Hours loockback periods
input int MinSMAPeriod = 5;            // Period min para SMA
input int MaxSMAPeriod = 50;           // Periodo max para SMA
input int MinEMAPeriod = 5;            // Periodo min para EMA
input int MaxEMAPeriod = 50;           // Periodo max para EMA
#define MAGIC_SE 12321
datetime lastOptimizationTime = 0;
double optimizedTakeProfit = 0.0;//InpTakeProfit;
double optimizedStopLoss = 0.0;//InpStopLoss;
double InpTakeProfit1 ;
double InpStopLoss1;

3. Функция инициализации (OnInit):

  • Настраивает модель ONNX из буфера.
  • Инициализирует технические индикаторы (SMA, EMA).
  • Вызывает функции для оптимизации индикаторов и торговых параметров.

int OnInit()
  {
//--- create a model from static buffer
   ExtHandle = OnnxCreateFromBuffer(ExtModel, ONNX_DEFAULT);
   if(ExtHandle == INVALID_HANDLE)
     {
      Print("OnnxCreateFromBuffer error ", GetLastError());
      return(INIT_FAILED);
     }

//--- set input and output shapes
   const long input_shape[] = {1, SAMPLE_SIZE, 1};
   if(!OnnxSetInputShape(ExtHandle, ONNX_DEFAULT, input_shape))
     {
      Print("OnnxSetInputShape error ", GetLastError());
      return(INIT_FAILED);
     }
   const long output_shape[] = {1, 1};
   if(!OnnxSetOutputShape(ExtHandle, 0, output_shape))
     {
      Print("OnnxSetOutputShape error ", GetLastError());
      return(INIT_FAILED);
     }

   SMAHandle = iMA(_Symbol, _Period, SMA_Period, 0, MODE_SMA, PRICE_CLOSE); // Ensure correct period
   if(SMAHandle == INVALID_HANDLE)
     {
      Print("Error initializing SMA indicator: ", GetLastError());
      return INIT_FAILED;
     }
   EMAHandle = iMA(_Symbol, _Period, EMA_Period, 0, MODE_EMA, PRICE_CLOSE); // Ensure correct index
   if(EMAHandle == INVALID_HANDLE)
     {
      Print("Error initializing EMA indicator: ", GetLastError());
      return INIT_FAILED;
     }
   trade.SetDeviationInPoints(Slippage);

   trade.SetExpertMagicNumber(MAGIC_SE);
   OptimizeIndicators();
   OptimizeParameters();
   return(INIT_SUCCEEDED);
  }

4. Функция деинициализации (OnDeinit):

Освобождает хэндлы для модели ONNX и индикаторов.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(ExtHandle != INVALID_HANDLE)
     {
      OnnxRelease(ExtHandle);
      ExtHandle = INVALID_HANDLE;
     }

   IndicatorRelease(SMAHandle);
   IndicatorRelease(EMAHandle);
  }

5. Основная торговая логика (OnTick):

  • Проверяет, закрыт ли рынок.
  • Периодически оптимизирует индикаторы и торговые параметры.
  • Обновляет логику трейлинг-стопа.
  • Прогнозирует движение цен с использованием модели ONNX.
  • Проверяет условия открытия/закрытия позиций на основе прогнозов и индикаторов.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(IsMarketClosed())  // Verificar si el mercado está cerrado
     {
      return; // Si el mercado está cerrado, no hacer nada
     }

   static datetime lastOptimizationTime2 = 0;

   if(TimeCurrent() - lastOptimizationTime2 >= OptimizationDays * PeriodSeconds(PERIOD_H1))
     {
      OptimizeIndicators();
      lastOptimizationTime2 = TimeCurrent();

      // Actualizar los indicadores con los nuevos períodos
      IndicatorRelease(SMAHandle);
      IndicatorRelease(EMAHandle);
      SMAHandle = iMA(_Symbol, _Period, SMA_Period, 0, MODE_SMA, PRICE_CLOSE);
      EMAHandle = iMA(_Symbol, _Period, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
     }

//--- Optimización cada 2 días
   if(TimeCurrent() - lastOptimizationTime >= PeriodSeconds(PERIOD_H1) * HoursAnalyze)
     {
      OptimizeParameters();
      lastOptimizationTime = TimeCurrent();
     }

//---

   if(NewBarTS()==true)//gather statistics and launch trailing stop
     {
      double open=iOpen(_Symbol,TFTS,1);
      CalcLvl(up,(int)MathRound((iHigh(_Symbol,TFTS,1)-open)/_Point));
      CalcLvl(dn,(int)MathRound((open-iLow(_Symbol,TFTS,1))/_Point));
      buy_sl=CalcSL(dn);
      buy_tp=CalcTP(up);
      sell_sl=CalcSL(up);
      sell_tp=CalcTP(dn);

      if(TypeTS==Simple)//simple trailing stop
         SimpleTS();

      if(TypeTS==MoralExp)//Moral expectation
         METS();
      if(TypeTS==None)//None TS
         return;
     }

   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);

   if(bid==SLNeutral || bid<=SLBuy || (SLSell>0 && bid>=SLSell))
     {
      for(int i=PositionsTotal()-1; i>=0; i--)
        {
         ulong ticket=PositionGetTicket(i);
         if(PositionSelectByTicket(ticket)==true)
            trade.PositionClose(ticket);
        }
     }
//---
//--- check new day
   if(TimeCurrent() >= ExtNextDay)
     {
      GetMinMax();
      ExtNextDay = TimeCurrent();
      ExtNextDay -= ExtNextDay % PeriodSeconds(PERIOD_D1);
      ExtNextDay += PeriodSeconds(PERIOD_D1);
     }

//--- check new bar
   if(TimeCurrent() < ExtNextBar)
      return;
   ExtNextBar = TimeCurrent();
   ExtNextBar -= ExtNextBar % PeriodSeconds();
   ExtNextBar += PeriodSeconds();

//--- check min and max
   float close = (float)iClose(_Symbol, _Period, 0);
   if(ExtMin > close)
      ExtMin = close;
   if(ExtMax < close)
      ExtMax = close;


   double sma[], ema[];//, willr[];
   CopyBuffer(SMAHandle, 0, 0, 1, sma);
   CopyBuffer(EMAHandle, 0, 0, 1, ema);
//CopyBuffer(WillRHandle, 0, 0, 1, willr);

//--- predict next price
   PredictPrice();

//--- check trading according to prediction and indicators
   if(ExtPredictedClass >= 0)
     {
      if(PositionSelect(_Symbol))
         CheckForClose(sma[0], ema[0]);//, willr[0]);
      else
         CheckForOpen(sma[0], ema[0]);//, willr[0]);
     }
  }

6. Торговые функции:

  • CheckForOpen - определяет, открывать ли позицию на покупку или продажу на основе прогнозов и сигналов индикаторов.
  • CheckForClose - проверяет, следует ли закрыть текущие позиции на основе прогнозов.

//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(double sma, double ema)//, double willr)
  {
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   int copied = CopyRates(_Symbol,0,0,1,rates);
   if(copied <= 0)
     {
      Print("Error copying rates: ", GetLastError());
      return;
     }
   double Close[1];
   Close[0]=rates[0].close;
   double close = Close[0];

   ENUM_ORDER_TYPE signal = WRONG_VALUE;
   Print("ExtPredictedClass ",ExtPredictedClass);

//--- check signals
   if(ExtPredictedClass == 2)//PRICE_DOWN)
     {
      Print("ExtPredictedClass Sell ",ExtPredictedClass);
      Print("close ",close, " sma ",sma, " ema ", ema);//, " willr ", willr);
      // Venta
      if((close < sma && close < ema))// || willr > -20)
        {
         signal = ORDER_TYPE_SELL;
         Print("Order Sell detected");
        }
     }
   else
      if(ExtPredictedClass == 0)//PRICE_UP)
        {
         Print("ExtPredictedClass Buy ",ExtPredictedClass);
         Print("close ",close, " sma ",sma, " ema ", ema);//, " willr ", willr);
         // Compra
         if((close > sma && close > ema))// || willr < -80)
           {
            signal = ORDER_TYPE_BUY;
            Print("Order Buy detected");
           }
        }

//--- open position if possible according to signal
   if(signal != WRONG_VALUE && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
     {
      Print("Proceding open order");
      double price, sl=0, tp=0;
      double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

      MqlTradeRequest request = {};
      MqlTradeResult result = {};

      request.action = TRADE_ACTION_DEAL;
      request.symbol = _Symbol;
      request.deviation = Slippage;
      request.magic = MAGIC_SE;
      request.type_filling = ORDER_FILLING_FOK;
      //request.comment = "AKWr";

      double lotaje;
      if(signal == ORDER_TYPE_SELL)
        {
         price = bid;
         Print("Price: ",price);
         if(inp_lot_type == LOT_TYPE_FIX)
            lotaje=inp_lot_fix ;
         else
            lotaje=get_lot(price);
         if(!CheckVolumeValue(lotaje))
            return;
         if(!InpUseStops && ATR)
           {
            sl = NormalizeDouble(bid + StopLossATR * ATRValue, _Digits);
            tp = NormalizeDouble(ask - TakeProfitATR * ATRValue, _Digits);
            if(!CheckMoneyForTrade(_Symbol, lotaje,ORDER_TYPE_SELL))
              {
               Print("No hay suficiente margen para abrir la posición");
               return;
              }
            request.type = ORDER_TYPE_SELL;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            request.volume = lotaje;
            request.sl = sl;
            request.tp = tp;
            request.comment = "SEW Opened sell order";
           }
         if(!InpUseStops && ATR)
           {
            sl = 0;
            tp = 0;
           }
         else
           {
            InpTakeProfit1 =optimizedTakeProfit;
            InpStopLoss1= optimizedStopLoss;
            sl = NormalizeDouble(bid + InpStopLoss1*_Point, _Digits);
            tp = NormalizeDouble(ask - InpTakeProfit1*_Point, _Digits);

           }
        }
      else
        {
         price = ask;
         Print("Price: ",price);
         if(inp_lot_type == LOT_TYPE_FIX)
            lotaje=inp_lot_fix ;
         else
            lotaje=get_lot(price);
         if(!CheckVolumeValue(lotaje))
            return;
         if(!InpUseStops)
           {
            sl = NormalizeDouble(ask - StopLossATR * ATRValue, _Digits);
            tp = NormalizeDouble(bid + TakeProfitATR * ATRValue, _Digits);
            if(!CheckMoneyForTrade(_Symbol, lotaje,ORDER_TYPE_BUY))
              {
               Print("No hay suficiente margen para abrir la posición");
               return;
              }
            request.type = ORDER_TYPE_BUY;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            request.volume = lotaje;
            request.sl = sl;
            request.tp = tp;
            request.comment = "SEW Opened buy order";
           }
         if(!InpUseStops && ATR)
           {
            sl = 0;
            tp = 0;
           }
         else
           {
            InpTakeProfit1 =optimizedTakeProfit;
            InpStopLoss1= optimizedStopLoss;
            sl = NormalizeDouble(ask - InpStopLoss1*_Point, _Digits);
            tp = NormalizeDouble(bid + InpTakeProfit1*_Point, _Digits);
           }
        }
      Print("No InpUseStops used");

      //ExtTrade.PositionOpen(_Symbol, signal, lotaje, price, sl, tp);

      if(!CheckMoneyForTrade(_Symbol, lotaje, (ENUM_ORDER_TYPE)signal))
        {
         Print("No hay suficiente margen para abrir la posición");
         return;
        }
      Print("Volume ", lotaje);
      request.type = signal;
      request.price = price;//SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      request.volume = lotaje;
      request.sl = sl;
      request.tp = tp;
      request.comment = "SEW";
      if(!OrderSend(request, result))
        {
         Print("Error opening the order: ", GetLastError());
         return;
        }
     }
  }
//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(double sma, double ema)//, double willr)
  {
   if(InpUseStops)
      return;

   bool bsignal = false;

//--- position already selected before
   long type = PositionGetInteger(POSITION_TYPE);

//--- check signals
   if(type == POSITION_TYPE_BUY && ExtPredictedClass == 2)//PRICE_DOWN)
      bsignal = true;
   if(type == POSITION_TYPE_SELL && ExtPredictedClass == 0)//PRICE_UP)
      bsignal = true;

//--- close position if possible
   if(bsignal && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
     {
      ExtTrade.PositionClose(_Symbol);
      CheckForOpen(sma, ema);//, willr);
     }
  }

7. Прогноз цены (PredictPrice):

Использует модель ONNX для прогнозирования будущего движения цены.

//+------------------------------------------------------------------+
//| Predict next price                                               |
//+------------------------------------------------------------------+
void PredictPrice(void)
  {
   static vectorf output_data(1);
   static vectorf x_norm(SAMPLE_SIZE);

   if(ExtMin >= ExtMax)
     {
      Print("ExtMin >= ExtMax");
      ExtPredictedClass = -1;
      return;
     }

   if(!x_norm.CopyRates(_Symbol, _Period, COPY_RATES_CLOSE, 1, SAMPLE_SIZE))
     {
      Print("CopyRates ", x_norm.Size());
      ExtPredictedClass = -1;
      return;
     }
   float last_close = x_norm[SAMPLE_SIZE - 1];
   x_norm -= ExtMin;
   x_norm /= (ExtMax - ExtMin);

   if(!OnnxRun(ExtHandle, ONNX_NO_CONVERSION, x_norm, output_data))
     {
      Print("OnnxRun");
      ExtPredictedClass = -1;
      return;
     }

   float predicted = output_data[0] * (ExtMax - ExtMin) + ExtMin;
   float delta = last_close - predicted;
   if(fabs(delta) <= 0.00001)
      ExtPredictedClass = PRICE_SAME;
   else
      if(delta < 0)
         ExtPredictedClass = PRICE_UP;
      else
         ExtPredictedClass = PRICE_DOWN;

// Debugging output
   Print("Predicted price: ", predicted, " Delta: ", delta, " Predicted Class: ", ExtPredictedClass);
  }

8. Функции трейлинг-стопа:

Различные функции (AllTS, METS, SimpleTS) реализуют различные стратегии трейлинг-стопа.

Подробности можно узнать в этой статье"Трейлинг-стоп в трейдинге"

9. Функции оптимизации:

  • OptimizeParameters - пробует различные значения тейк-профита и стоп-лосса для поиска оптимальных настроек.
  • OptimizeIndicators - находит лучшие периоды для индикаторов SMA и EMA.

void OptimizeParameters()
  {
   double bestTakeProfit = InpTakeProfit1;
   double bestStopLoss = InpStopLoss1;
   double bestPerformance = -DBL_MAX;

   for(int tp = 65; tp <= 500; tp += 5) // rango de TakeProfit
     {
      for(int sl = 65; sl <= 500; sl += 5) // rango de StopLoss
        {
         double performance = TestStrategy(tp, sl);
         if(performance > bestPerformance)
           {
            bestPerformance = performance;
            bestTakeProfit = tp;
            bestStopLoss = sl;
            //Print("Best Take Profit",bestTakeProfit);
            //Print("Best Stop Loss",bestStopLoss);
           }
        }
     }

   optimizedTakeProfit = bestTakeProfit;
   optimizedStopLoss = bestStopLoss;

   Print("Optimized TakeProfit: ", optimizedTakeProfit);
   Print("Optimized StopLoss: ", optimizedStopLoss);
  }
void OptimizeIndicators()
  {
   datetime startTime = TimeCurrent() - LookbackPeriod * PeriodSeconds(PERIOD_H1);
   datetime endTime = TimeCurrent();

   int bestSMAPeriod = SMA_Period;
   int bestEMAPeriod = EMA_Period;
   double bestPerformance = -DBL_MAX;

   for(int smaPeriod = MinSMAPeriod; smaPeriod <= MaxSMAPeriod; smaPeriod++)
     {
      for(int emaPeriod = MinEMAPeriod; emaPeriod <= MaxEMAPeriod; emaPeriod++)
        {
         double performance = TestIndicatorPerformance(smaPeriod, emaPeriod, startTime, endTime);

         if(performance > bestPerformance)
           {
            bestPerformance = performance;
            bestSMAPeriod = smaPeriod;
            bestEMAPeriod = emaPeriod;
           }
        }
     }

   SMA_Period = bestSMAPeriod;
   EMA_Period = bestEMAPeriod;

   Print("Optimized SMA Period: ", SMA_Period);
   Print("Optimized EMA Period: ", EMA_Period);
  }

10. Вспомогательные функции и управление капиталом:

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

bool IsMarketClosed()
  {
   datetime currentTime = TimeCurrent();
   MqlDateTime tm;
   TimeToStruct(currentTime, tm);

   int dayOfWeek = tm.day_of_week;
   int hour = tm.hour;

// Verifica si es fin de semana
   if(dayOfWeek <= Sunday || dayOfWeek >= Saturday)
     {
      return true;
     }

// Verifica si está fuera del horario habitual de mercado (ejemplo: 21:00 a 21:59 UTC)
   if(hour >= after || hour < before)  // Ajusta estos valores según el horario del mercado
     {
      return true;
     }

   return false;
  }


//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume)//,string &description)
  {
//--- minimal allowed volume for trade operations
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      //description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- maximal allowed volume of trade operations
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      //description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- get minimal step of volume changing
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      //description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
      //volume_step,ratio*volume_step);
      return(false);
     }
//description="Correct volume value";
   return(true);
  }
//+------------------------------------------------------------------+
bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
  {
//--- Getting the opening price
   MqlTick mqltick;
   SymbolInfoTick(symb,mqltick);
   double price=mqltick.ask;
   if(type==ORDER_TYPE_SELL)
      price=mqltick.bid;
//--- values of the required and free margin
   double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
//--- call of the checking function
   if(!OrderCalcMargin(type,symb,lots,price,margin))
     {
      //--- something went wrong, report and return false
      Print("Error in ",__FUNCTION__," code=",GetLastError());
      return(false);
     }
//--- if there are insufficient funds to perform the operation
   if(margin>free_margin)
     {
      //--- report the error and return false
      Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
      return(false);
     }
//--- checking successful
   return(true);
  }
double get_lot(double price)
  {
   if(inp_lot_type==LOT_TYPE_FIX)
      return(normalize_lot(inp_lot_fix));
   double one_lot_margin;
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,one_lot_margin))
      return(inp_lot_fix);
   return(normalize_lot((AccountInfoDouble(ACCOUNT_BALANCE)*(inp_lot_risk/100))/ one_lot_margin));
  }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
double normalize_lot(double lt)
  {
   double lot_step = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lt = MathFloor(lt / lot_step) * lot_step;
   double lot_minimum = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   lt = MathMax(lt, lot_minimum);
   return(lt);
  }

Основные функции:

  1. Использует машинное обучение (модель ONNX) для прогнозирования цен.
  2. Объединяет технические индикаторы (SMA, EMA) с прогнозами машинного обучения для принятия торговых решений.
  3. Реализует несколько стратегий трейлинг-стопа.
  4. Включает периодическую оптимизацию параметров индикатора и торговых настроек.
  5. Имеет встроенное управление рисками (размер лота, проверка капитала).
  6. Учитывает часы работы рынка для торговли.

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

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

График AAPL

Тестирование на истории AAPL

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


Итог

В статье представлен инновационный советник для алгоритмической торговли на рынке Форекс, специально разработанный для торговли акциями Apple Inc. (#AAPL). Советник представляет собой сложное сочетание машинного обучения и традиционного технического анализа, направленное на точное и адаптивное управление сложными ситуациями на валютных рынках.

В основе советника лежит модель ONNX (Open Neural Network Exchange), которая служит компонентом машинного обучения. Задача модели — прогнозировать движение цен на основе последних рыночных данных. Советник объединяет прогнозы с популярными техническими индикаторами, а именно простой скользящей средней (SMA) и экспоненциальной скользящей средней (EMA), для генерации торговых сигналов.

Подход многогранен и включает в себя несколько ключевых особенностей:

  1. Динамическая оптимизация: Как технические индикаторы, так и торговые параметры подлежат периодической оптимизации. Это позволяет советнику адаптироваться к изменяющимся рыночным условиям, потенциально улучшая свою производительность с течением времени.
  2. Адаптивное управление рисками: Советник использует динамическое определение размера лота и расчеты среднего истинного диапазона (ATR) для установки уровней стоп-лосса и тейк-профита. Подход направлен на корректировку размеров позиций и степени риска на основе текущей волатильности рынка.
  3. Несколько стратегий трейлинг-стопа: Советник реализует различные методы трейлинг-стопа, что позволяет гибко управлять открытыми позициями и потенциально максимизировать прибыль при минимизации убытков.
  4. Осведомленность о состоянии рынка: Система учитывает часы работы и условия рынка, гарантируя, что сделки будут совершаться только тогда, когда это необходимо.

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

  1. Инициализация: На этом этапе настраивается модель ONNX и технические индикаторы, подготавливая советник к работе.
  2. Основная торговая логика: Основная функциональность, которая решает, когда открывать или закрывать позиции, на основе комбинированных сигналов модели машинного обучения и технических индикаторов.
  3. Прогнозирование цен: Использует модель ONNX для прогнозирования будущих движений цен.
  4. Функции оптимизации: Периодически корректирует параметры индикатора и торговые настройки для поддержания эффективности в меняющихся рыночных условиях.
  5. Управление рисками: Включает функции для расчета размера лота, управления денежными средствами и проверки состояния рынка.

Эффективность советника оценивалась посредством тестирования на истории акций AAPL. Результаты показали многообещающую прибыльность с коэффициентом Шарпа 6,21, что указывает на высокую доходность с поправкой на риск. Однако анализ также выявил относительно высокие показатели просадки, что указывает на области для потенциального улучшения управления рисками.


Заключение

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

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

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

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

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

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

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

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

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

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

Прикрепленные файлы |
SE_v9.mq5 (80.02 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (4)
Arup Nag
Arup Nag | 16 авг. 2024 в 09:12
Пошаговое руководство по автоматической оптимизации будет очень полезно
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera | 10 сент. 2024 в 11:43
Arup Nag автооптимизации будет очень полезно

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

Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera | 13 сент. 2024 в 21:19
Arup Nag автооптимизации будет очень полезно.

Вот статья, надеюсь, она вам понравится: Как реализовать автооптимизацию в MQL5-экспертах - Статьи MQL5

yehaichang
yehaichang | 9 апр. 2025 в 20:00
Есть ли советник на основе нейросетевой торговли, я хотел бы попробовать, настроив параметры высокого коэффициента выигрыша, я собираюсь купить!
Анализируем двоичный код цен на бирже (Часть II): Преобразуем в BIP39 и пишем GPT модель Анализируем двоичный код цен на бирже (Часть II): Преобразуем в BIP39 и пишем GPT модель
Продолжаем попытки дешифровать движения цен... Как насчет лингвистического анализа "словаря рынка", который мы получим, преобразовав бинарный код цены в BIP39? В этой статье мы углубимся в инновационный подход к анализу биржевых данных и рассмотрим, как современные методы обработки естественного языка могут быть применены к языку рынка.
Машинное обучение и Data Science (Часть 28): Прогнозирование множества будущих значений для EURUSD Машинное обучение и Data Science (Часть 28): Прогнозирование множества будущих значений для EURUSD
Многие модели искусственного интеллекта заточены на прогнозирование одного единственного будущего значения. В этой статье мы посмотрим, как использовать модели машинного обучения для прогнозирования множества будущих значений. Такой подход, называемый многошаговым прогнозированием, позволяет предсказывать не только цену закрытия на завтра, но и на послезавтра и так далее. Несомненное преимущество многошагового прогнозирования для трейдеров и аналитиков данных — более широкий спектр информации для возможностей стратегического планирования.
Оптимизация портфеля на языках Python и MQL5 Оптимизация портфеля на языках Python и MQL5
В этой статье рассмотрены передовые методы оптимизации портфеля с использованием языков Python и MQL5 на платформе MetaTrader 5. В ней демонстрируется, как разрабатывать алгоритмы для анализа данных, распределения активов и генерации торговых сигналов, подчеркивая значимость принятия решений на основе данных в современном финансовом менеджменте и снижении рисков.
От начального до среднего уровня: Приоритеты операторов От начального до среднего уровня: Приоритеты операторов
Это, несомненно, самый сложный вопрос, который можно объяснить исключительно теоретически. Поэтому я советую вам попрактиковаться с материалами, которые будут показаны здесь. Хотя на первый взгляд всё может показаться простым, данный вопрос с операторами можно понять только на практике в сочетании с постоянным изучением.