English
preview
Ein Beispiel für automatisch optimierte Take-Profits und Indikatorparameter mit SMA und EMA

Ein Beispiel für automatisch optimierte Take-Profits und Indikatorparameter mit SMA und EMA

MetaTrader 5Beispiele | 26 September 2024, 10:26
90 0
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

Einführung

In der sich ständig weiterentwickelnden Welt des algorithmischen Handels ist Innovation der Schlüssel, um der Zeit immer einen Schritt voraus zu sein. Wir freuen uns, Ihnen heute einen hochentwickelten Expert Advisor (EA) vorstellen zu können, der maschinelles Lernen mit traditioneller technischer Analyse kombiniert, um die Devisenmärkte zu steuern. Dieser EA nutzt ein ONNX-Modell zusammen mit sorgfältig optimierten technischen Indikatoren, um Handelsentscheidungen auf den Währungsmärkten zu treffen.

Der EA-Ansatz ist vielschichtig und nutzt die Preisvorhersage eines maschinellen Lernmodells, Trendfolgetechniken und adaptive Parameteroptimierung. Es ist in erster Linie für den #AAPL-Aktien konzipiert, kann aber auch flexibel für andere Instrumente angepasst werden. Mit Funktionen wie dynamischer Losgrößenbestimmung, Trailing-Stops und automatischer Anpassung an die Marktbedingungen stellt dieser EA eine Mischung aus modernster Technologie und bewährten Handelsprinzipien dar.

Erläuterung der verwendeten Indikatoren:

  1. Einfacher gleitender Durchschnitt (SMA): Der EA verwendet einen einfachen gleitenden Durchschnitt mit einer adaptiv optimierten Periode. Der SMA hilft bei der Ermittlung der allgemeinen Trendrichtung und wird in Verbindung mit dem Preis und anderen Indikatoren verwendet, um Handelssignale zu generieren.
  2. Exponentieller gleitender Durchschnitt (EMA): Außerdem wird ein Exponential Moving Average verwendet, dessen Periodenlänge dynamisch optimiert wird. Der EMA reagiert schneller auf jüngste Kursänderungen als der SMA und bietet eine andere Perspektive auf die Trendrichtung.
  3. Average True Range (ATR): Obwohl der EA nicht explizit im Code berechnet wird, verwendet er ATR-basierte Berechnungen zur Festlegung von Stop-Loss- und Take-Profit-Levels. Dies ermöglicht eine an die Volatilität angepasste Positionsgröße und Risikomanagement.
  4. Modell für maschinelles Lernen: Der EA enthält ein ONNX-Modell (Open Neural Network Exchange) für die Preisvorhersage. Dieses Modell nimmt eine Reihe aktueller Kursdaten auf und versucht, die nächste Kursbewegung vorherzusagen, was der Handelsstrategie ein prognostisches Element hinzufügt.

Diese Indikatoren werden auf raffinierte Weise kombiniert, wobei ihre Parameter auf der Grundlage der aktuellen Marktbedingungen dynamisch optimiert werden. Der EA enthält auch Funktionen wie Trailing-Stops und moralische Erwartungsberechnungen, um offene Positionen effektiv zu verwalten.

Die Kombination dieser Indikatoren mit der Komponente des maschinellen Lernens ermöglicht es dem EA, sich an veränderte Marktbedingungen anzupassen und potenzielle Handelsmöglichkeiten in verschiedenen Marktphasen zu erkennen.


Aufschlüsselung des Codes

1. Ersteinrichtung und Einbindungen:

Der Code beginnt mit Copyright-Informationen und enthält die erforderlichen Bibliotheken wie Trade.mqh.

#include <Trade\Trade.mqh>

2. Globale Variablen und Parameter:

  • Die Parameter des ONNX-Modells werden definiert, einschließlich Stichprobengröße und Handles.
  • Eingabeparameter für Indikatoren (SMA, EMA, ATR) und Handelsoperationen werden angegeben.
  • Es werden Enums und Konstanten für Preisbewegungen und magische Zahlen definiert.

#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. Initialisierungsfunktion (OnInit):

  • Richtet das ONNX-Modell aus einem Puffer ein.
  • Initialisiert technische Indikatoren (SMA, EMA).
  • Ruft Funktionen zur Optimierung von Indikatoren und Handelsparametern auf.

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. Deinitialisierungsfunktion (OnDeinit):

Freigabe der Handles des ONNX-Modells und der Indikatoren.

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

   IndicatorRelease(SMAHandle);
   IndicatorRelease(EMAHandle);
  }

5. Haupthandelslogik (OnTick):

  • Prüft, ob der Markt geschlossen ist.
  • Optimiert periodisch Indikatoren und Handelsparameter.
  • Aktualisiert die Logik des Trailing-Stops.
  • Prognostiziert die Kursentwicklung anhand des ONNX-Modells.
  • Prüft auf der Grundlage von Vorhersagen und Indikatoren die Bedingungen für offene/geschlossene Positionen.

//+------------------------------------------------------------------+
//| 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. Handelsfunktionen:

  • CheckForOpen: Bestimmt auf der Grundlage von Prognosen und Indikatorsignalen, ob eine Kauf- oder Verkaufsposition eröffnet werden soll.
  • CheckForClose: Prüft, ob aktuelle Positionen aufgrund von Vorhersagen geschlossen werden sollten.

//+------------------------------------------------------------------+
//| 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. Preisvorhersage (PredictPrice):

Verwendet das ONNX-Modell zur Vorhersage zukünftiger Kursbewegungen.

//+------------------------------------------------------------------+
//| 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. Trailing-Stop-Funktionen:

Verschiedene Funktionen (AllTS, METS, SimpleTS) implementieren unterschiedliche Trailing-Stop-Strategien.

Das alles wird in diesem MQL5-Artikel erklärt:  „Trailing-Stopp im Handel

9. Optimierungsfunktionen:

  • OptimizeParameters: Probiert verschiedene Take-Profit- und Stop-Loss-Werte aus, um optimale Einstellungen zu finden.
  • OptimizeIndicators: Findet die besten Zeiträume für SMA- und EMA-Indikatoren.

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. Nutzwertfunktionen und Geldmanagement: :

Funktionen zur Berechnung der Losgröße, zur Überprüfung des Volumens, zur Überprüfung der Marktschließung, einschließlich Funktionen zur Überprüfung, ob genügend Geld für den Handel vorhanden ist, und zur Normalisierung der Losgröße usw.

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);
  }

Wesentliche Merkmale:

  1. Verwendet maschinelles Lernen (ONNX-Modell) für die Preisvorhersage.
  2. Kombiniert technische Indikatoren (SMA, EMA) mit ML-Vorhersagen für Handelsentscheidungen.
  3. Implementiert mehrere Trailing-Stop-Strategien.
  4. Umfasst die regelmäßige Optimierung der Indikatorparameter und Handelseinstellungen.
  5. Verfügt über ein integriertes Risikomanagement (Losgrößenbestimmung, Geldkontrolle).
  6. Berücksichtigt die Marktzeiten für den Handel.

Dieser Expert Advisor (EA) ist ziemlich ausgeklügelt und kombiniert traditionelle technische Analyse mit maschinellem Lernen für den Forex-Handel. Es umfasst auch verschiedene Risikomanagement- und Optimierungsfunktionen zur Anpassung an sich ändernde Marktbedingungen.

Eingaben

Grafik AAPL

Backtesting AAPL

Diese Analyse zeigt, dass die automatisierte Handelsstrategie mit einer soliden Sharpe Ratio von 6,21 rentabel ist. Allerdings weist er einen hohen Drawdown auf, was auf die Notwendigkeit eines sorgfältigen Risikomanagements hinweist. Die Fähigkeit der Strategie, beständige Gewinne zu erzielen, wie die Aktienkurve zeigt, spiegelt ihr Potenzial für reale Handelsanwendungen wider. Künftige Optimierungen könnten sich darauf konzentrieren, die Drawdowns zu verringern und den Rückgewinnungsfaktor zu verbessern, um die Gesamtleistung zu steigern.


Zusammenfassung

Dieser Artikel stellt einen innovativen Expert Advisor (EA) für den algorithmischen Handel auf dem Forex-Markt vor, der speziell für den Handel mit Aktien von Apple Inc. (#AAPL) entwickelt wurde. Der EA ist eine ausgeklügelte Mischung aus maschinellem Lernen und traditioneller technischer Analyse, die darauf abzielt, die Komplexität der Devisenmärkte mit Präzision und Anpassungsfähigkeit zu navigieren.

Das Herzstück dieses EA ist ein ONNX-Modell (Open Neural Network Exchange), das als Komponente des maschinellen Lernens dient. Dieses Modell hat die Aufgabe, Kursbewegungen auf der Grundlage der jüngsten Marktdaten vorherzusagen, wodurch die Handelsstrategie um ein vorausschauendes Element erweitert wird. Der EA kombiniert diese Vorhersagen mit etablierten technischen Indikatoren, nämlich Simple Moving Average (SMA) und Exponential Moving Average (EMA), um Handelssignale zu generieren.

Der Ansatz des EAs ist vielschichtig und umfasst mehrere Schlüsselmerkmale:

  1. Dynamische Optimierung: Sowohl die technischen Indikatoren als auch die Handelsparameter unterliegen einer periodischen Optimierung. Dadurch kann sich der EA an veränderte Marktbedingungen anpassen und seine Leistung im Laufe der Zeit verbessern.
  2. Adaptives Risikomanagement: Der EA arbeitet mit dynamischer Losgröße und verwendet Average True Range (ATR)-Berechnungen zur Festlegung von Stop-Loss- und Take-Profit-Levels. Dieser Ansatz zielt darauf ab, die Positionsgrößen und das Risikoengagement auf der Grundlage der aktuellen Marktvolatilität anzupassen.
  3. Mehrere Trailing-Stop-Strategien: Der EA implementiert verschiedene Trailing-Stop-Methoden, die ein flexibles Management offener Positionen ermöglichen und potenziell Gewinne maximieren und Verluste minimieren.
  4. Bewusstsein für die Marktlage: Das System ist so konzipiert, dass es die Marktzeiten und -bedingungen berücksichtigt und sicherstellt, dass Geschäfte nur dann ausgeführt werden, wenn sie angemessen sind.

Der Artikel enthält eine detaillierte Aufschlüsselung der Code-Struktur des EA und erläutert seine wichtigsten Komponenten:

  1. Initialisierung: In dieser Phase werden das ONNX-Modell und die technischen Indikatoren eingerichtet und der EA für den Betrieb vorbereitet.
  2. Haupthandelslogik: Die Kernfunktionalität, die auf der Grundlage der kombinierten Signale des maschinellen Lernmodells und der technischen Indikatoren entscheidet, wann Positionen eröffnet oder geschlossen werden.
  3. Preisvorhersage: Nutzt das ONNX-Modell zur Vorhersage künftiger Kursbewegungen.
  4. Optimierungsfunktionen: Passt regelmäßig die Indikatorparameter und Handelseinstellungen an, um die Effektivität unter wechselnden Marktbedingungen aufrechtzuerhalten.
  5. Risikomanagement: Enthält Funktionen zur Berechnung der Losgröße, zur Geldverwaltung und zur Überprüfung der Marktbedingungen.

Die Leistung des EA wurde durch Backtesting mit AAPL-Aktiendaten bewertet. Die Ergebnisse zeigten eine vielversprechende Rentabilität mit einer Sharpe Ratio von 6,21, was auf starke risikobereinigte Renditen hinweist. Die Analyse ergab jedoch auch relativ hohen Drawdown, was auf Bereiche mit Verbesserungspotenzial im Risikomanagement hinweisen.


Schlussfolgerung

Nun, der Expert Advisor (EA), den wir heute haben, ist ein großer Sprung. Es nutzt eine Mischung aus intelligenter Technologie (maschinelles Lernen) und bewährten Methoden (technische Analyse), um Händlern wertvolle, nur für Mitglieder zugängliche Entscheidungen über die Investition in AAPL-Aktien und andere Symbole zu liefern.

Der EA kombiniert ein ONNX-Modell zur Preisvorhersage mit optimierten technischen Indikatoren. Diese Mischung bedeutet, dass sie sowohl auf unmittelbare Preisänderungen als auch auf langsame Bewegungen in längerfristigen Entwicklungen reagieren kann.

Das Besondere an diesem EA ist, dass er über ein kohärentes Risikomanagementsystem verfügt. Zum Beispiel verwendet er dynamische Losgrößen (Änderung der Losgröße je nach Marktbedingungen), ATR-basierte Stop-Loss- und Take-Profit-Levels (Grenzsetzung für Verluste, wenn die Dinge schlecht laufen, oder für Gewinne, wenn sie zu Ihren Gunsten sind) sowie mehrere Trailing-Stop-Strategien in Bezug auf Preisänderungen. Diese Instrumente sind darauf zugeschnitten, dass Sie Ihr Geld behalten können, ohne dass Sie auf unerklärliche Weise abgezockt werden.

Eine weitere großartige Sache dieses EAs ist, dass es seine Indikatoren und Handelsparameter ziemlich regelmäßig aktualisiert. Dies ermöglicht es, mit dem sich wandelnden Markt Schritt zu halten, was sehr wichtig ist, um auf Dauer effektiv zu bleiben.

Die Ergebnisse der Backtesting-Analyse, die zeigt, wie der EA in der Vergangenheit abgeschnitten hätte, sind jedoch immer noch etwas enttäuschend. Obwohl die Ergebnisse in Bezug auf Gewinne und Risikomanagement gut zu sein scheinen, wurden einige hohe Drawdowns - ein großer Wertverlust - festgestellt, was darauf hindeutet, dass das Risikomanagement verschärft werden könnte. Zukünftige Versionen des EA können bessere Schutzmechanismen oder vorsichtigeres Handeln in sehr volatilen Zeiten beinhalten.

Obwohl es für den Handel mit AAPL-Aktien entwickelt wurde, lassen sich die darin enthaltenen Prinzipien leicht auf andere Finanzmärkte übertragen. Diese Flexibilität macht dieses Instrument sowohl für den aktuellen Handel als auch als Modell für künftige algorithmische Systeme interessant.

Es handelt sich um einen komplexen, vielversprechenden EA des automatisierten Handels - eine Mischung aus modernster Technologie und traditionellen Methoden, die sich durch ein starkes Risikomanagement auszeichnet und sich an veränderte Marktbedingungen anpassen lässt. Wie jedes andere Handelsinstrument muss es jedoch regelmäßig überwacht, aktualisiert und in realen Szenarien getestet werden, um seine reibungslose Funktionalität im Laufe der Zeit zu gewährleisten.

Schließlich, während dieser EA zu haben scheint eine Menge Potenzial, aber mehr Arbeit auf sie gemacht werden muss, und viele der Optimierung getan werden müssen, ist es wichtig, sich daran zu erinnern, dass der Handel immer mit Risiko verbunden ist, und die vergangene Leistung nicht garantieren zukünftigen Erfolg. Wenn Sie dieses oder ein anderes automatisiertes System verwenden möchten, sollten Sie sich über die Risiken im Klaren sein, Ihre Hausaufgaben machen und es idealerweise in einer simulierten Umgebung testen, bevor Sie echtes Geld einsetzen.

Ich hoffe, Sie genießen es, diesen Artikel zu lesen, so wie ich es genoss, ihn zu schreiben und ich hoffe, Sie können diesen EA viel besser machen und noch bessere Ergebnisse erzielen. Dies ist ein gutes Beispiel dafür, wie die automatische Optimierung mit Stopps und Indikatoren umgesetzt werden kann. Nochmals, ich hoffe, es hat Ihnen gefallen. Prost!

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15476

Beigefügte Dateien |
SE_v9.mq5 (80.02 KB)
Preisgesteuertes CGI-Modell: Erweiterte Datennachbearbeitung und Implementierung Preisgesteuertes CGI-Modell: Erweiterte Datennachbearbeitung und Implementierung
In diesem Artikel befassen wir uns mit der Entwicklung eines vollständig anpassbaren Skripts für den Preisdatenexport mit MQL5, das einen neuen Fortschritt in der Simulation des CGI-Modells Price Man darstellt. Wir haben fortschrittliche Verfeinerungstechniken implementiert, um sicherzustellen, dass die Daten nutzerfreundlich und für Animationszwecke optimiert sind. Außerdem werden wir die Möglichkeiten von Blender 3D bei der effektiven Arbeit mit und der Visualisierung von Preisdaten kennenlernen und sein Potenzial für die Erstellung dynamischer und ansprechender Animationen demonstrieren.
Integration von MQL5 in Datenverarbeitungspakete (Teil 1): Fortgeschrittene Datenanalyse und statistische Verarbeitung Integration von MQL5 in Datenverarbeitungspakete (Teil 1): Fortgeschrittene Datenanalyse und statistische Verarbeitung
Die Integration ermöglicht einen nahtlosen Arbeitsablauf, bei dem Finanzrohdaten aus MQL5 in Datenverarbeitungspakete wie Jupyter Lab für erweiterte Analysen einschließlich statistischer Tests importiert werden können.
Selbstoptimierende Expert Advisors mit MQL5 und Python erstellen (Teil II): Abstimmung tiefer neuronaler Netze Selbstoptimierende Expert Advisors mit MQL5 und Python erstellen (Teil II): Abstimmung tiefer neuronaler Netze
Modelle für maschinelles Lernen verfügen über verschiedene einstellbare Parameter. In dieser Artikelserie werden wir untersuchen, wie Sie Ihre KI-Modelle mithilfe der SciPy-Bibliothek an Ihren spezifischen Markt anpassen können.
Stimmungsanalyse auf Twitter mit Sockets Stimmungsanalyse auf Twitter mit Sockets
Dieser innovative Trading-Bot integriert MetaTrader 5 mit Python, um die Stimmungsanalyse sozialer Medien in Echtzeit für automatisierte Handelsentscheidungen zu nutzen. Durch die Analyse der Twitter-Stimmung in Bezug auf bestimmte Finanzinstrumente übersetzt der Bot Trends in den sozialen Medien in umsetzbare Handelssignale. Es nutzt eine Client-Server-Architektur mit Socket-Kommunikation, die eine nahtlose Interaktion zwischen den Handelsfunktionen von MT5 und der Datenverarbeitungsleistung von Python ermöglicht. Das System demonstriert das Potenzial der Kombination von quantitativer Finanzwirtschaft und natürlicher Sprachverarbeitung und bietet einen innovativen Ansatz für den algorithmischen Handel, der alternative Datenquellen nutzt. Der Bot ist vielversprechend, zeigt aber auch Bereiche auf, die in Zukunft noch verbessert werden müssen, z. B. fortschrittlichere Techniken der Stimmungsanalyse und verbesserte Risikomanagementstrategien.