English 日本語
preview
Formulierung von dynamischen Multi-Pair EA (Teil 5): Scalping vs. Swing Handelsansätze

Formulierung von dynamischen Multi-Pair EA (Teil 5): Scalping vs. Swing Handelsansätze

MetaTrader 5Beispiele |
36 9
Hlomohang John Borotho
Hlomohang John Borotho

Inhaltsverzeichnis

  1. Einführung
  2. System-Übersicht
  3. Die ersten Schritte
  4. Backtest-Ergebnisse
  5. Schlussfolgerung


Einführung

Die Wahl des richtigen Handelsansatzes für unterschiedliche Marktbedingungen ist oft eine Herausforderung. Schnelllebige Märkte können dazu führen, dass sich Swing-Strategien zu langsam anfühlen, während volatile Sitzungen Scalping-Handelsgeschäfte, die auf enge Ziele ausgerichtet sind, schnell zum Erliegen bringen können. Dies führt zu einem Dilemma: Entweder verpassen die Händler kurzfristige Chancen mit hoher Wahrscheinlichkeit oder sie handeln zu viel unter Bedingungen, die für ihre gewählte Strategie ungeeignet sind. Infolgedessen werden die Gewinne uneinheitlich, und Systeme, die für einen Vermögenswert oder einen Zeitrahmen gut funktionieren, versagen oft bei der Anwendung auf andere.

Diese Herausforderung kann durch die Entwicklung eines dynamischen Multi-Pair Expert Advisors überwunden werden, der sowohl Scalping- als auch Swing-Trading-Modi in einem einzigen Rahmen integriert. Indem der Händler je nach Marktvolatilität und -struktur zwischen diesen Modi umschalten oder sie automatisieren kann, kann der EA seine Handelslogik, seine Stop-Levels und Zeithorizonte dynamisch anpassen. Dies stellt sicher, dass das System unter verschiedenen Bedingungen profitabel bleibt und ein Gleichgewicht zwischen schnellen Intraday-Gewinnen und längeren, qualitativ hochwertigeren Swing-Setups schafft.


System-Übersicht

Scalping ist ein Handelsansatz, der sich darauf konzentriert, von sehr kleinen Kursbewegungen innerhalb kurzer Zeiträume, oft Sekunden bis Minuten, zu profitieren. Händler, die diesen Stil verwenden, eröffnen und schließen mehrere Positionen im Laufe des Tages und versuchen, von Mikroschwankungen des Marktpreises zu profitieren, anstatt von großen Richtungsänderungen. Es erfordert Präzision, schnelle Ausführung und strikte Disziplin, da Spreads, Slippage und Transaktionskosten die Gewinne schnell auffressen können. Scalper verlassen sich stark auf niedrigere Zeitrahmen wie 1-Minuten- oder 5-Minuten-Charts und verwenden technische Indikatoren wie gleitende Durchschnitte, Volumenspitzen und Momentum-Oszillatoren, um Ein- und Ausstiege mit hoher Genauigkeit zu timen.

Beim Swing-Trading hingegen werden größere Kursbewegungen angestrebt, die sich über einen längeren Zeitraum erstrecken, in der Regel von einigen Stunden bis zu Tagen oder sogar Wochen. Der Schwerpunkt liegt auf dem Erkennen und Erfassen von Marktschwankungen – den natürlichen Auf- und Abwärtsbewegungen, die auftreten, wenn der Preis auf Trends, Rückschritte und wichtige Unterstützungs- und Widerstandsebenen reagiert. Swing Trader stützen sich auf eine Kombination aus technischer Analyse, Marktstruktur und manchmal auch auf fundamentale Zusammenhänge, um Einstiegspunkte mit hoher Wahrscheinlichkeit und günstige Risiko-Rendite-Setups zu bestimmen. Diese Methode ermöglicht im Vergleich zum Scalping eine geringere Anzahl von Handelsgeschäften und eine kürzere Bildschirmzeit, wodurch sie sich gut für Händler eignet, die einen strategischeren und analytischeren Ansatz für das Marktverhalten bevorzugen.

Aspekt Scalping Swing-Handel 
Handel DauerSekunden bis MinutenStunden bis Tage (manchmal Wochen)
Häufigkeit des HandelsDutzende bis Hunderte pro Tag1 bis 10 Abschlüsse pro Woche (im Durchschnitt)
ZielErfassen von kleine, häufige Kursbewegungen (50 bis 100 Pips oder $0,50-$1 bei Metallen)Erfassen Sie größere Marktschwankungen (Hunderte von Pips)
Zeitliche BindungIntensive, hohe BildschirmzeitMäßig, auf Analyse ausgerichtet
MarktkontextFunktioniert am besten in Märkten mit hoher Volatilität und hoher Liquidität (z. B. XAUUSD und die wichtigsten FX-Paare)Funktioniert am besten in Märkten, die sich im Trend bewegen oder eine Spanne ausdehnen
Stop Loss/Take ProfitSehr enger SL (50 bis 150 Pips) / kleiner TP (40 bis 100 Pips)Größerer SL (200+ Pips) / größerer TP (1000+ Pips)
Größe der PositionenIn der Regel größer (da die Ziele klein sind)In der Regel kleiner (da die Ziele entfernter sind)


Die ersten Schritte

//+------------------------------------------------------------------+
//|                                            Scalps and Swings.mq5 |
//|                        GIT under Copyright 2025, MetaQuotes Ltd. |
//|                     https://www.mql5.com/en/users/johnhlomohang/ |
//+------------------------------------------------------------------+
#property copyright "GIT under Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com/en/users/johnhlomohang/"
#property version   "1.00"
#property description "Dual-mode EA for Scalping and Swing Trading"
#include <Trade/Trade.mqh>

Wie üblich beginnen wir mit dem Import der wesentlichen Handelsbibliothek, die unser Expert Advisor benötigt, um Aufträge auszuführen und Positionen zu verwalten.

//+------------------------------------------------------------------+
//| Input Parameters                                                 |
//+------------------------------------------------------------------+
enum ENUM_MODE
{
   MODE_SCALP,  // Scalping
   MODE_SWING   // Swing Trading
};

input ENUM_MODE          TradeMode = MODE_SCALP;          // Trading Mode
input string             TradePairs = "XAUUSD,BTCUSD,US100,GBPUSD"; // Trading Pairs (comma separated)
input bool               UseATR = false;                  // Use ATR for SL/TP

// Scalping Parameters
input double             LotSize_Scalp = 0.1;             // Scalp Lot Size
input int                StopLoss_Scalp = 50;             // Scalp Stop Loss (pips)
input int                TakeProfit_Scalp = 30;           // Scalp Take Profit (pips)
input int                ScalpTrailingStop = 15;          // Scalp Trailing Stop (pips)
input ENUM_TIMEFRAMES    ScalpTimeframe = PERIOD_M5;      // Scalping Timeframe
input int                Scalp_EMA_Fast = 5;              // Scalp Fast EMA
input int                Scalp_EMA_Slow = 20;             // Scalp Slow EMA
input int                Scalp_RSI_Period = 14;           // Scalp RSI Period
input int                Scalp_RSI_Overbought = 55;       // Scalp RSI Overbought
input int                Scalp_RSI_Oversold = 45;         // Scalp RSI Oversold

// Swing Trading Parameters
input double             LotSize_Swing = 0.1;             // Swing Lot Size
input int                StopLoss_Swing = 200;            // Swing Stop Loss (pips)
input int                TakeProfit_Swing = 400;          // Swing Take Profit (pips)
input int                SwingTrailingStop = 100;         // Swing Trailing Stop (pips)
input ENUM_TIMEFRAMES    SwingTimeframe = PERIOD_H4;      // Swing Timeframe
input int                Swing_Lookback = 20;             // Swing Lookback Period
input double             Fib_Level = 0.618;               // Fibonacci Retracement Level
input bool               UseHigherTFConfirmation = true;  // Use D1 Confirmation
input ENUM_TIMEFRAMES    HigherTF = PERIOD_D1;            // Higher Timeframe

// Risk Management
input int                MaxOpenPositions = 4;            // Max Open Positions per Pair
input int                MagicNumber = 12345;             // Magic Number
input int                Slippage = 3;                    // Slippage (points)

Wir beginnen mit der Definition der Eingabeparameter für ein Multimode-Handelssystem, das sowohl Scalping als auch Swing Trading unterstützt. Im ersten Abschnitt wird die Enumeration, ENUM_MODE, eingeführt, mit der der Nutzer zwischen MODE_SCALP und MODE_SWING wählen kann. Diese Eingabe steuert das Verhalten des EA – ob er kurzfristige Intraday-Bewegungen oder längerfristige Marktschwankungen handeln wird. TradePairs einzugeben bietet die Flexibilität, mehrere Instrumente zu definieren (z. B. XAUUSD, BTCUSD, US100, GBPUSD), während die Option UseATR adaptive Stop-Loss- und Take-Profit-Levels auf Basis der Volatilität anstelle von festen Pip-Werten ermöglicht.

Die Scalping-Parameter bestimmen, wie sich der EA in schnellen, hochfrequenten Umgebungen verhält. Dazu gehören kleinere Abstände für Stop-Loss und Take-Profit, ein kürzerer Zeitrahmen (z. B. M5) und sich schneller bewegende Indikatoren wie die 5-Perioden- und 20-Perioden-EMAs in Kombination mit einem 14-Perioden-RSI. Die RSI-Schwellenwerte sind absichtlich eng gewählt (55 und 45), um subtile Momentumverschiebungen zu erkennen. Der Trailing-Stop-Wert ist kleiner, sodass die Handelsgeschäfte auf die Intraday-Volatilität reagieren. Diese Einstellungen gewährleisten schnelle Handelszyklen, die geringfügige Kursschwankungen erfassen, ohne den Händler längeren Marktstörungen auszusetzen.

Umgekehrt sind die Parameter für das Swing-Trading auf breitere Marktbewegungen abgestimmt. Der EA verwendet größere Stop-Loss- und Take-Profit-Abstände, um der höheren Volatilität im Zeitrahmen und der Trendfortsetzung Rechnung zu tragen. Ein Rückblickzeitraum von 20 Balken und ein Fibonacci-Retracement-Level (0,618) helfen bei der Identifizierung wichtiger Korrekturzonen für potenzielle Umkehrungen. Die Bestätigung auf einem höheren Zeitrahmen (in der Regel D1) dient der Trendbestätigung, um gegenläufige Handelsgeschäfte zu vermeiden. Schließlich bieten Risikomanagement-Eingaben wie MaxOpenPositions, MagicNumber und Slippage eine robuste Kontrolle über Handelsvolumen, Identifikation und Orderpräzision und gewährleisten, dass der EA über alle Paare und Bedingungen hinweg konsistent und sicher bleibt.

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
string   SymbolList[];
int      TotalPairs;
datetime LastTickTime = 0;
color    TextColor = clrWhite;
CTrade   trade;

int handleEmaFast_Scalp, handleEmaSlow_Scalp, handleRsi_Scalp;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // Initialize trade object
    trade.SetExpertMagicNumber(MagicNumber);
    trade.SetDeviationInPoints(Slippage);

    // Split trading pairs
    SplitString(TradePairs, ",", SymbolList);
    TotalPairs = ArraySize(SymbolList);

    // Validate symbols
    for(int i = 0; i < TotalPairs; i++)
    {
        if(!SymbolInfoInteger(SymbolList[i], SYMBOL_TRADE_MODE))
        {
            Print("Error: Symbol ", SymbolList[i], " is not available for trading");
            return(INIT_FAILED);
        }
    }

    // Create indicator handles for scalping mode
    handleEmaFast_Scalp = iMA(NULL, ScalpTimeframe, Scalp_EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
    if(handleEmaFast_Scalp == INVALID_HANDLE)
    {
        Print("Failed to create handle for fast EMA (Scalp)");
        return(INIT_FAILED);
    }
    handleEmaSlow_Scalp = iMA(NULL, ScalpTimeframe, Scalp_EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
    if(handleEmaSlow_Scalp == INVALID_HANDLE)
    {
        Print("Failed to create handle for slow EMA (Scalp)");
        return(INIT_FAILED);
    }
    handleRsi_Scalp = iRSI(NULL, ScalpTimeframe, Scalp_RSI_Period, PRICE_CLOSE);
    if(handleRsi_Scalp == INVALID_HANDLE)
    {
        Print("Failed to create handle for RSI (Scalp)");
        return(INIT_FAILED);
    }

    Print("EA initialized successfully with ", TotalPairs, " pairs");
    Print("Trading Mode: ", EnumToString(TradeMode));

    return(INIT_SUCCEEDED);
}

Anschließend definieren wir die globalen Variablen und die Initialisierungsroutine für den Expert Advisor. Die globalen Variablen deklarieren Schlüsselkomponenten wie die Liste der Handelssymbole, die Gesamtzahl der Paare und eine Instanz der CTrade-Klasse für die Handelsausführung. Zu den zusätzlichen Variablen gehören Indikator-Handles für den Scalping-Modus – schneller EMA, langsamer EMA und RSI – die später zum Abrufen von Echtzeitdaten für die Signalerzeugung verwendet werden. Die Variable LastTickTime gewährleistet die Effizienz der Tick-Verarbeitung, während TextColor die Standardfarbe für Textelemente des Charts definiert, die in der Visualisierung oder Protokollierung verwendet werden.

In der Funktion OnInit() beginnt der EA mit dem Einrichten der Handelsumgebung. Es weist dem CTrade-Objekt eine eindeutige magische Zahl und eine Schlupftoleranz zu, um eine konsistente Auftragsverwaltung zu gewährleisten. Der Eingabestring TradePairs wird mithilfe einer nutzerdefinierten SplitString()-Funktion in ein Array aufgeteilt, das bestimmt, mit welchen Symbolen der EA arbeitet. Jedes Symbol wird validiert, um zu bestätigen, dass es für den Handel verfügbar ist, bevor fortgefahren werden kann. Die Funktion erstellt dann Indikator-Handles für den schnellen und den langsamen EMAs und den RSI für den Scalping-Modus. Jeder Handle wird auf seine Gültigkeit geprüft, um sicherzustellen, dass der EA nicht mit fehlerhaften Indikatorreferenzen startet. Sobald alle Validierungen bestanden sind, wird eine Erfolgsmeldung zur Initialisierung ausgegeben, die die Anzahl der aktiven Paare und den ausgewählten Handelsmodus anzeigt und bestätigt, dass der EA vollständig zur Ausführung bereit ist.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment(""); // Clear chart comment
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Avoid multiple processing in the same tick
   if(LastTickTime == iTime(_Symbol, _Period, 0)) return;
   LastTickTime = iTime(_Symbol, _Period, 0);
   
   // Process each trading pair
   for(int i = 0; i < TotalPairs; i++)
   {
      string symbol = SymbolList[i];
      
      if(TradeMode == MODE_SCALP)
      {
         ScalpModeHandler(symbol);
         
         if(IsNewBar(symbol, ScalpTimeframe))
         {
            ExecuteScalpTrade(symbol);
         }
         
         ManageScalpTrades(symbol);
      }
      else if(TradeMode == MODE_SWING)
      {
         if(SwingSignal(symbol))
         {
            if(IsNewBar(symbol, SwingTimeframe))
            {
               ExecuteSwingTrade(symbol);
            }
         }
         ManageSwingTrades(symbol);
      }
   }
   
   // Update dashboard
   UpdateDashboard();
}

//+------------------------------------------------------------------+
//| Check if new bar formed                                          |
//+------------------------------------------------------------------+
bool IsNewBar(string symbol, ENUM_TIMEFRAMES timeframe)
{
   static datetime lastBarTime = 0;
   datetime currentBarTime = iTime(symbol, timeframe, 0);
   
   if(currentBarTime != lastBarTime)
   {
      lastBarTime = currentBarTime;
      return true;
   }
   return false;
}

Wie wir wissen, dient die Funktion OnTick() als Kern der Ausführungsschleife des Expert Advisors und wird jedes Mal ausgeführt, wenn ein neuer Tick eintrifft. Zunächst wird geprüft, ob die Zeit des aktuellen Ticks mit der des zuletzt verarbeiteten Ticks identisch ist, um redundante Operationen innerhalb desselben Ticks zu vermeiden. Der EA durchläuft dann alle in der SymbolList definierten Handelspaare, wobei er je nach ausgewähltem Handelsmodus dynamisch die Logik für den Scalping- oder Swing-Handel verarbeitet. Im Scalping-Modus ruft er ScalpModeHandler() auf, um Signale auszuwerten, führt Handelsgeschäfte auf neuen Balken aus und verwaltet bestehende Scalp-Positionen. Im Swing-Modus erkennt es gültige Swing-Signale, platziert entsprechende Handelsgeschäfte und aktualisiert laufende Positionen durch ManageSwingTrades(). Schließlich aktualisiert die Funktion das Dashboard auf dem Bildschirm, um Handels- und Leistungsfeedback in Echtzeit zu liefern und sicherzustellen, dass der EA effizient und adaptiv über alle aktiven Paare läuft.

//+------------------------------------------------------------------+
//| Scalping Signal Function                                         |
//+------------------------------------------------------------------+
void ScalpModeHandler(string symbol)
{
    // Define arrays to hold indicator values
    double emaFastArr[2], emaSlowArr[2], rsiArr[2];

    // Copy values: current and previous
    if(CopyBuffer(handleEmaFast_Scalp, 0, 0, 2, emaFastArr) < 2) return;
    if(CopyBuffer(handleEmaSlow_Scalp, 0, 0, 2, emaSlowArr) < 2) return;
    if(CopyBuffer(handleRsi_Scalp,     0, 0, 2, rsiArr)     < 2) return;

    // Assign named values
    double emaFastCurr = emaFastArr[0];
    double emaFastPrev = emaFastArr[1];
    double emaSlowCurr = emaSlowArr[0];
    double emaSlowPrev = emaSlowArr[1];
    double rsiCurr     = rsiArr[0];

    // Validate (avoid zero or invalid)
    if(emaFastCurr == 0 || emaSlowCurr == 0 || rsiCurr == 0) return;

    // Check open positions for this symbol
    if(CountOpenPositions(symbol) >= MaxOpenPositions) return;

    // BUY signal condition
    if(emaFastCurr > emaSlowCurr && emaFastPrev <= emaSlowPrev && rsiCurr > Scalp_RSI_Overbought)
    {
        ExecuteAdaptiveTrade(ORDER_TYPE_BUY, symbol, LotSize_Scalp);
        Print("Scalp BUY Signal executed for ", symbol);
    }
    // SELL signal condition
    else if(emaFastCurr < emaSlowCurr && emaFastPrev >= emaSlowPrev && rsiCurr < Scalp_RSI_Oversold)
    {
        ExecuteAdaptiveTrade(ORDER_TYPE_SELL, symbol, LotSize_Scalp);
        Print("Scalp SELL Signal executed for ", symbol);
    }
}

//+------------------------------------------------------------------+
//| Swing Trading Signal Function                                    |
//+------------------------------------------------------------------+
bool SwingSignal(string symbol)
{
   int swingHighBar = iHighest(symbol, SwingTimeframe, MODE_HIGH, Swing_Lookback, 1);
   int swingLowBar  = iLowest(symbol, SwingTimeframe, MODE_LOW, Swing_Lookback, 1);
   if(swingHighBar == -1 || swingLowBar == -1) return false;

   double swingHigh     = iHigh(symbol, SwingTimeframe, swingHighBar);
   double swingLow      = iLow(symbol, SwingTimeframe, swingLowBar);
   double currentClose  = iClose(symbol, SwingTimeframe, 0);
   double range         = swingHigh - swingLow;
   if(range == 0) return false;

   double fib618_Up     = swingHigh - Fib_Level * range;
   double fib618_Down   = swingLow + Fib_Level * range;

   bool higherTFBullish = true;
   bool higherTFBearish = true;

   if(UseHigherTFConfirmation)
   {
      int handleEMA = iMA(symbol, HigherTF, 20, 0, MODE_EMA, PRICE_CLOSE);
      if(handleEMA == INVALID_HANDLE) return false;

      double emaVal[1];
      if(CopyBuffer(handleEMA, 0, 0, 1, emaVal) < 1) return false;

      double htEMA20 = emaVal[0];
      double htClose = iClose(symbol, HigherTF, 0);
      higherTFBullish = htClose > htEMA20;
      higherTFBearish = htClose < htEMA20;
   }

   // --- Buy Signal
   if(currentClose <= fib618_Down && currentClose > swingLow && higherTFBullish)
      return true;

   // --- Sell Signal
   if(currentClose >= fib618_Up && currentClose < swingHigh && higherTFBearish)
      return true;

   return false;
}

Die Funktion ScalpModeHandler() ist für die Erzeugung und Ausführung kurzfristiger Handelssignale im Scalping-Modus zuständig. Es ruft die letzten und vorherigen Werte des schnellen EMA, des langsamen EMA und des RSI mithilfe von CopyBuffer() aus vorinitialisierten Indikator-Handles ab. Diese Werte werden verwendet, um Kreuzungs-Ereignisse und Momentum-Bedingungen zu erkennen, die die Grundlage für Scalp-Trade-Signale bilden. Ein Kaufsignal entsteht insbesondere dann, wenn der schnelle EMA den langsamen EMA übersteigt und der RSI den überkauften Schwellenwert überschreitet, was auf eine Aufwärtsdynamik hindeutet. Umgekehrt wird ein Verkaufssignal ausgelöst, wenn der schnelle EMA unter den langsamen EMA fällt und der RSI unter den überverkauften Schwellenwert sinkt, was auf eine Abwärtsdynamik hindeutet. Bevor ein Handel ausgeführt wird, stellt die Funktion sicher, dass die Indikatordaten gültig sind und dass das Symbol die maximale Anzahl offener Positionen nicht überschritten hat, um ein effizientes und kontrolliertes Handelsmanagement zu gewährleisten.

Die Funktion SwingSignal() arbeitet auf höheren Zeitrahmen, um breitere Marktumkehrungen oder -fortsetzungen zu erkennen. Es ermittelt den letzten hohen und den letzten tiefen Umkehr innerhalb eines definierten Rückblickzeitraums, berechnet die Handelsspanne und leitet Fibonacci-Retracement-Levels ab, um potenzielle Preisreaktionszonen zu lokalisieren. Anhand dieser Informationen wird geprüft, ob der aktuelle Marktpreis mit wichtigen Retracement-Niveaus übereinstimmt, die auf eine mögliche Umkehrmöglichkeit hinweisen. Wenn die Bestätigung auf einem höheren Zeitrahmen aktiviert ist, sorgt ein zusätzlicher EMA-Filter dafür, dass nur in Übereinstimmung mit dem vorherrschenden Trend auf dem größeren Zeitrahmen gehandelt wird. Die Funktion gibt dann ein boolesches Signal zurück (true oder false), je nachdem, ob ein gültiges Kauf- oder Verkaufs-Setup erkannt wurde. Diese Trennung von kurzfristiger (Scalping) und langfristiger (Swing) Logik ermöglicht es dem EA, seine Strategie dynamisch und präzise an unterschiedliche Marktbedingungen anzupassen.

//+------------------------------------------------------------------+
//| Execute Scalp Trade                                              |
//+------------------------------------------------------------------+
void ExecuteScalpTrade(string symbol)
{
   if(CountOpenPositions(symbol) >= MaxOpenPositions) return;

   int handleEmaFast = iMA(symbol, ScalpTimeframe, Scalp_EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
   int handleEmaSlow = iMA(symbol, ScalpTimeframe, Scalp_EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
   int handleRSI     = iRSI(symbol, ScalpTimeframe, Scalp_RSI_Period, PRICE_CLOSE);

   double emaFast[1], emaSlow[1], rsi[1];
   if(CopyBuffer(handleEmaFast, 0, 0, 1, emaFast) < 1) return;
   if(CopyBuffer(handleEmaSlow, 0, 0, 1, emaSlow) < 1) return;
   if(CopyBuffer(handleRSI, 0, 0, 1, rsi) < 1) return;

   double emaF = emaFast[0];
   double emaS = emaSlow[0];
   double rsiV = rsi[0];

   if(emaF > emaS && rsiV > Scalp_RSI_Overbought)
      ExecuteTrade(ORDER_TYPE_BUY, symbol, LotSize_Scalp, StopLoss_Scalp, TakeProfit_Scalp);
   else if(emaF < emaS && rsiV < Scalp_RSI_Oversold)
      ExecuteTrade(ORDER_TYPE_SELL, symbol, LotSize_Scalp, StopLoss_Scalp, TakeProfit_Scalp);
}

//+------------------------------------------------------------------+
//| Execute Swing Trade                                              |
//+------------------------------------------------------------------+
void ExecuteSwingTrade(string symbol)
{
   if(CountOpenPositions(symbol) >= MaxOpenPositions) return;
   
   // Determine trade direction (simplified logic)
   int swingHighBar = iHighest(symbol, SwingTimeframe, MODE_HIGH, Swing_Lookback, 1);
   int swingLowBar = iLowest(symbol, SwingTimeframe, MODE_LOW, Swing_Lookback, 1);
   
   if(swingHighBar != -1 && swingLowBar != -1)
   {
      double swingHigh = iHigh(symbol, SwingTimeframe, swingHighBar);
      double swingLow = iLow(symbol, SwingTimeframe, swingLowBar);
      double currentClose = iClose(symbol, SwingTimeframe, 0);
      double range = swingHigh - swingLow;
      double fib618_Down = swingLow + Fib_Level * range;
      double fib618_Up = swingHigh - Fib_Level * range;
      
      if(currentClose <= fib618_Down && currentClose > swingLow)
      {
         ExecuteTrade(ORDER_TYPE_BUY, symbol, LotSize_Swing, StopLoss_Swing, TakeProfit_Swing);
      }
      else if(currentClose >= fib618_Up && currentClose < swingHigh)
      {
         ExecuteTrade(ORDER_TYPE_SELL, symbol, LotSize_Swing, StopLoss_Swing, TakeProfit_Swing);
      }
   }
}

//+------------------------------------------------------------------+
//| Execute trade with dynamic stop/TP adaption per symbol           |
//+------------------------------------------------------------------+
void ExecuteTrade(ENUM_ORDER_TYPE tradeType, string symbol, double lotSize, int stopLossPips, int takeProfitPips)
{
   //--- Symbol info
   double point  = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int digits    = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
   double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);

   double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
   double bid = SymbolInfoDouble(symbol, SYMBOL_BID);
   double price = (tradeType == ORDER_TYPE_BUY) ? ask : bid;

   //--- Detect pip size automatically (handles forex, gold, crypto, indices)
   double pipSize;
   if(StringFind(symbol, "JPY") != -1)              // JPY pairs (2/3 digits)
      pipSize = (digits == 3) ? point * 10 : point;
   else if(StringFind(symbol, "XAU") != -1 || StringFind(symbol, "GOLD") != -1)  // Metals
      pipSize = 0.10;
   else if(StringFind(symbol, "BTC") != -1 || StringFind(symbol, "ETH") != -1)   // Cryptos
      pipSize = point * 100.0;
   else if(StringFind(symbol, "US") != -1 && digits <= 2)                         // Indices
      pipSize = point;
   else
      pipSize = (digits == 3 || digits == 5) ? point * 10 : point;                // Default Forex

   //--- Convert SL/TP from pips to price distances
   double sl_distance = stopLossPips * pipSize;
   double tp_distance = takeProfitPips * pipSize;

   //--- Determine broker minimum stop levels
   double minStopPoints = 0.0;
   if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0)
      minStopPoints = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   else if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0)
      minStopPoints = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   else
      minStopPoints = 30; // fallback default (points)

   double minStop = minStopPoints * point;

   //--- Ensure SL/TP distances are greater than min stop level
   if(sl_distance < minStop) sl_distance = minStop;
   if(tp_distance < minStop) tp_distance = minStop;

   //--- Calculate final SL/TP prices
   double sl = (tradeType == ORDER_TYPE_BUY) ? price - sl_distance : price + sl_distance;
   double tp = (tradeType == ORDER_TYPE_BUY) ? price + tp_distance : price - tp_distance;

   //--- Normalize prices
   sl = NormalizeDouble(sl, digits);
   tp = NormalizeDouble(tp, digits);
   price = NormalizeDouble(price, digits);

   //--- Safety validation (correct SL/TP relation)
   if((tradeType == ORDER_TYPE_BUY && (sl >= price || tp <= price)) ||
      (tradeType == ORDER_TYPE_SELL && (sl <= price || tp >= price)))
   {
      Print("Invalid SL/TP detected for ", symbol, " — auto-adjusting...");
      if(tradeType == ORDER_TYPE_BUY)
      {
         sl = NormalizeDouble(price - minStop, digits);
         tp = NormalizeDouble(price + minStop * 2, digits);
      }
      else
      {
         sl = NormalizeDouble(price + minStop, digits);
         tp = NormalizeDouble(price - minStop * 2, digits);
      }
   }

   //--- Try executing trade
   if(trade.PositionOpen(symbol, tradeType, lotSize, price, sl, tp, "Adaptive Multi-Pair EA"))
   {
      PrintFormat("%s opened on %s | Lot: %.2f | SL: %.5f | TP: %.5f | TickValue: %.2f",
                  EnumToString(tradeType), symbol, lotSize, sl, tp, tickValue);
   }
   else
   {
      int err = GetLastError();
      PrintFormat("Failed to open %s on %s | Error %d: %s",
                  EnumToString(tradeType), symbol, err, err);
      ResetLastError();      
   }
}
Die Funktionen ExecuteScalpTrade() und ExecuteSwingTrade() definieren zwei unterschiedliche Ausführungslogiken – eine für kurzfristige Präzisionseinträge und eine andere für Swing-Setups mit höherem Zeitrahmen. Die Scalp-Handelslogik konzentriert sich auf den schnellen Einstieg bei hohem Momentum und verwendet schnelle und langsame EMAs sowie RSI-Schwellenwerte, um kurzlebige Trends zu erkennen. Er führt Handelsgeschäfte sofort aus, wenn der schnelle EMA den langsamen EMA kreuzt und der RSI überkaufte oder überverkaufte Zustände erreicht, um ein schnelles Engagement bei volatilen Bewegungen zu gewährleisten. In der Zwischenzeit identifiziert die Swing-Trade-Funktion größere Marktstrukturen, indem sie die letzten hohen und tiefen Umkehrpunkte analysiert und dann Fibonacci-Retracement-Levels berechnet, um optimale, auf Retracement basierende Einstiegszonen zu finden. Dies ermöglicht dem EA, mittelfristige Umkehrungen oder Fortsetzungen innerhalb breiterer Trends zu erfassen.

Die Funktion ExecuteTrade() fungiert als zentrale Ausführungsmaschine, die sich an verschiedene Marktinstrumente anpasst, indem sie Pip-Größen berechnet, Broker-Einschränkungen prüft und Preise für eine sichere Handelsplatzierung normalisiert. Es passt die Stop-Loss- und Take-Profit-Levels dynamisch an die Eigenschaften des Symbols an – egal ob Forex, Gold, Krypto oder Indizes – und stellt sicher, dass jeder Handel die Mindeststopp-Levels des Brokers respektiert und gleichzeitig logische SL/TP-Abstände beibehält. Zusammen bilden diese drei Funktionen ein robustes Ausführungssystem, das sich auf intelligente Weise sowohl an schnelle als auch an langsame Marktumgebungen anpasst und Präzision, Sicherheit und Konsistenz über mehrere Anlageklassen hinweg gewährleistet.
//+------------------------------------------------------------------+
//| Execute trade with adaptive SL/TP by symbol type                 |
//+------------------------------------------------------------------+
void ExecuteAdaptiveTrade(ENUM_ORDER_TYPE type, string symbol, double lotSize)
{
   double point  = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int digits    = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   double ask    = SymbolInfoDouble(symbol, SYMBOL_ASK);
   double bid    = SymbolInfoDouble(symbol, SYMBOL_BID);
   double price  = (type == ORDER_TYPE_BUY) ? ask : bid;

   //--- Determine adaptive pip scale per asset
   double pipScale;
   if(StringFind(symbol, "XAU") != -1 || StringFind(symbol, "GOLD") != -1)
      pipScale = 1.0;          // Gold → 1 dollar movement = 1 pip
   else if(StringFind(symbol, "BTC") != -1)
      pipScale = 50.0;         // Crypto → 50-point unit for volatility
   else if(StringFind(symbol, "US") != -1 && digits <= 2)
      pipScale = 10.0;         // Indices (US100, US30)
   else if(StringFind(symbol, "JPY") != -1)
      pipScale = 0.1;          // Yen pairs
   else
      pipScale = 0.0001;       // Standard Forex

   ENUM_TIMEFRAMES tf = ScalpTimeframe;

   //--- Calculate SL/TP dynamically
   double atr = iATR(symbol, tf, 14);
   if(atr <= 0) atr = pipScale * 30;  // Fallback default

   double slDistance = atr * 1.5;     // SL = 1.5x ATR
   double tpDistance = atr * 3.0;     // TP = 3x ATR

   //--- Validate broker min stop distance
   double minStop = 0;
   if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0)
      minStop = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) * point;
   else if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0)
      minStop = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) * point;
   else
      minStop = atr * 0.5;

   if(slDistance < minStop) slDistance = minStop;
   if(tpDistance < minStop) tpDistance = minStop * 2;

   //--- Final price calculation
   double sl = (type == ORDER_TYPE_BUY) ? price - slDistance : price + slDistance;
   double tp = (type == ORDER_TYPE_BUY) ? price + tpDistance : price - tpDistance;

   sl = NormalizeDouble(sl, digits);
   tp = NormalizeDouble(tp, digits);

   //--- Trade execution
   if(trade.PositionOpen(symbol, type, lotSize, price, sl, tp, "Scalp-Mode"))
   {
      PrintFormat("%s %s | Lot: %.2f | SL: %.5f | TP: %.5f | ATR: %.5f",
                  EnumToString(type), symbol, lotSize, sl, tp, atr);
   }
   else
   {
      int err = GetLastError();
      PrintFormat("Trade failed on %s | Error %d: %s",
                  symbol, err, GetLastError());
      ResetLastError();
   }
}

//+------------------------------------------------------------------+
//| Dashboard Functions                                              |
//+------------------------------------------------------------------+
void UpdateDashboard()
{
   string dashboardText = "";
   string newLine = "\n";
   
   dashboardText += "=== MULTI-PAIR TRADING EA ===" + newLine;
   dashboardText += "Trading Mode: " + EnumToString(TradeMode) + newLine;
   dashboardText += "Active Pairs: " + IntegerToString(TotalPairs) + newLine;
   dashboardText += "Account Balance: " + DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2) + newLine;
   dashboardText += "=================================" + newLine;
   
   // Show status for each pair
   for(int i = 0; i < TotalPairs; i++)
   {
      string symbol = SymbolList[i];
      int positions = CountOpenPositions(symbol);
      
      dashboardText += symbol + ":" + newLine;
      dashboardText += "  Positions: " + IntegerToString(positions) + newLine;
      
      // Add signal status with detailed info
      if(TradeMode == MODE_SCALP)
      {
         //bool signal = ScalpModeHandler(symbol);
         double emaFast = iMA(symbol, ScalpTimeframe, Scalp_EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
         double emaSlow = iMA(symbol, ScalpTimeframe, Scalp_EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
         double rsi = iRSI(symbol, ScalpTimeframe, Scalp_RSI_Period, PRICE_CLOSE);
         
         //dashboardText += "  Scalp Signal: " + (signal ? "ACTIVE" : "INACTIVE") + newLine;
         dashboardText += "  EMA Fast: " + DoubleToString(emaFast, 5) + newLine;
         dashboardText += "  EMA Slow: " + DoubleToString(emaSlow, 5) + newLine;
         dashboardText += "  RSI: " + DoubleToString(rsi, 1) + newLine;
      }
      else
      {
         bool signal = SwingSignal(symbol);
         dashboardText += "  Swing Signal: " + (signal ? "ACTIVE" : "INACTIVE") + newLine;
      }
      dashboardText += newLine;
   }
   
   Comment(dashboardText);
}
//+------------------------------------------------------------------+

Die Funktion ExecuteAdaptiveTrade() führt einen intelligenten Handelsausführungsmechanismus ein, der die Abstände von Stop-Loss (SL) und Take-Profit (TP) auf der Grundlage des einzigartigen Volatilitätsprofils eines jeden Assets dynamisch anpasst. Durch die Identifizierung des Instrumententyps – ob Gold, Kryptowährungen, Indizes, JPY-Paare oder Standard-Devisen – wendet es eine geeignete Pip-Skala an und verwendet den ATR-Indikator (Average True Range) zur Berechnung adaptiver SL/TP-Levels. Dadurch wird sichergestellt, dass die Handelsgeschäfte weder zu eng für volatile Märkte noch zu weit für stabile Märkte sind und Risiko und Ertrag in Echtzeit ausgeglichen werden. Die Funktion umfasst auch Sicherheitsvorkehrungen für Broker-Mindeststoppabstände und Autokorrekturmechanismen, die eine präzise, volatilitätsbewusste Handelsplatzierung in Multi-Asset-Umgebungen ermöglichen.

Die Funktion UpdateDashboard() ergänzt die adaptive Handelslogik, indem sie Leistungstransparenz in Echtzeit liefert. Es zeigt die aktiven Positionen jedes Handelspaares, wichtige technische Metriken (EMA-Werte, RSI oder Swing-Signal) und den allgemeinen Betriebsmodus des EA an, sodass Händler den Entscheidungsfluss und den Zustand des Systems direkt vom Chart aus visuell überwachen können. Zusammen bilden diese Komponenten eine nahtlose Feedback-Schleife – eine adaptive Ausführung, die sich an der Volatilität orientiert, und ein Live-Dashboard zur Überwachung -, die es Händlern ermöglicht, mehrere Paare mit Vertrauen, Effizienz und einem klaren Verständnis des Systemverhaltens unter verschiedenen Marktbedingungen zu verwalten.


Backtest-Ergebnisse

Scalping-Parameter:
EingangsvariableParameter 
 Use ATR for SL/TPTrue
 Scalp Lot Size0.35
 Scalp Stop Loss (pips)950
 Scalp Take Profit (pips)30
 Scalp Trailing Stop 15
 Scalping Timeframe3 Minuten
 Scalp Fast EMA20
 Scalp Slow EMA50
 Scalp RSI Period14
 Scalp RSI Overbought55
 Scalp RSI Oversold45

Parameter für den Swing-Handel:

Eingangsvariable Parameter
Swing Lot Size0.45
Swing Stop Loss (pips)200
Swing Take Profit (pips)1800
Swing Trailing Stop (pips)100
Swing Timeframe4 Stunden
Swing Lookback Period20
Fibonacci Retracement Level0.618
Use D1 Confirmationtrue
Higher Timeframe1 Tag



Schlussfolgerung

Insgesamt haben wir einen dynamischen Multi-Pair EA entwickelt, der zwischen Scalping- und Swing-Trading-Ansätzen wechseln kann und sich an verschiedene Asset-Typen wie Gold, Forex, Krypto und Indizes anpasst. Das System integriert technische Modelle wie EMA-Crossovers, RSI-Filter, Fibonacci-Retracements und ATR-basierte Volatilitätsmessungen, um auf intelligente Weise die Handelsrichtung und das Positionsmanagement zu bestimmen. Durch die Implementierung adaptiver SL/TP-Levels und einer robusten Multi-Symbol-Struktur gewährleistet der EA eine optimale Risikokontrolle, eine effiziente Ausführung und eine konsistente Anwendung der Logik unter verschiedenen Marktbedingungen – egal, ob das Ziel kurzfristige Scalps oder längerfristige Swing-Setups sind.

Zusammenfassend lässt sich sagen, dass dieser Rahmen den Händlern eine vielseitige und automatisierte Handelslösung bietet, die sich dynamisch an die Marktvolatilität, die Eigenschaften der Symbole und die Handelsziele anpasst. Es ermöglicht den Anwendern die Ausführung eines einzigen Expert Advisors, der sowohl aggressive Scalping- als auch geduldige Swing-Strategien nahtlos abwickelt und manuelle Eingriffe auf ein Minimum reduziert. Dieses einheitliche Design verbessert die Ausführungspräzision und das Risikomanagement und bietet ein höheres Maß an Marktanpassungsfähigkeit – ein entscheidender Vorteil für Händler, die Konsistenz und Skalierbarkeit über mehrere Anlageklassen hinweg suchen. 

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

Beigefügte Dateien |
Letzte Kommentare | Zur Diskussion im Händlerforum (9)
Ryan L Johnson
Ryan L Johnson | 11 Nov. 2025 in 20:19

Ich glaube, dass es sich bei dem Scalping-Bild um einen reinen Tippfehler handelt:

Tippfehler

Hlomohang John Borotho
Hlomohang John Borotho | 12 Nov. 2025 in 10:47
Mohammed Altaf Ahmed #:
heruntergeladen, aber der Backtest ist fehlgeschlagen. Es passiert nicht.

Hey, bitte achten Sie auf Ihre Eingabesymbole. Sie müssen mit den Symbolen Ihres Brokers übereinstimmen, z.B. "EURUSD.m" hat das Suffix ".m". Wenn Ihre Brokersymbole Suffixe oder Präfixe haben, geben Sie diese bitte in das Eingabesymbol ein.

hemantto
hemantto | 13 Nov. 2025 in 07:46

Hallo ,


Ich habe in Demo Mt5 laufen, aber Backtest ist fehlgeschlagen. seine nicht geschieht. jedes Problem in EA ?

YDILLC
YDILLC | 21 Nov. 2025 in 06:07
Dieser EA ist fantastisch!! Ich habe es verwendet & die Ergebnisse sind wunderbar!!! Machen Sie weiter mit dem, was Sie tun, und vielen Dank für das Teilen. Eine Frage!!! Für welches Paar ist der Backtest?
Hlomohang John Borotho
Hlomohang John Borotho | 21 Nov. 2025 in 11:53
YDILLC #:
Dieser EA ist fantastisch!! Ich habe es verwendet & die Ergebnisse sind wunderbar!!! Machen Sie weiter mit dem, was Sie tun, und vielen Dank für das Teilen. Eine Frage!!! Für welches Paar ist der Backtest?

Hey, danke für dein Feedback.

Der Backtest erfolgt mit den Standardeinstellungen für das Eingangssymbol:

"XAUUSD,BTCUSD,US100,GBPUSD"
Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
Klassische Strategien neu interpretieren (Teil 17): Modellierung technischer Indikatoren Klassische Strategien neu interpretieren (Teil 17): Modellierung technischer Indikatoren
In dieser Diskussion konzentrieren wir uns auf die Frage, wie wir die gläserne Decke durchbrechen können, die uns die klassischen Techniken des maschinellen Lernens im Finanzbereich auferlegen. Es scheint, dass die größte Einschränkung für den Wert, den wir aus statistischen Modellen ziehen können, nicht in den Modellen selbst liegt – weder in den Daten noch in der Komplexität der Algorithmen – sondern vielmehr in der Methodik, mit der wir sie anwenden. Mit anderen Worten: Der wahre Engpass kann darin liegen, wie wir das Modell einsetzen, und nicht in der eigentlichen Fähigkeit des Modells.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Entwicklung einer Handelsstrategie: Die Methode der Butterfly-Oszillation Entwicklung einer Handelsstrategie: Die Methode der Butterfly-Oszillation
In diesem Artikel zeigen wir, wie das faszinierende mathematische Konzept der Butterfly-Kurve in ein praktisches Handelsinstrument umgewandelt werden kann. Wir haben den Butterfly-Oszillator konstruiert und um ihn herum eine grundlegende Handelsstrategie entwickelt. Die Strategie kombiniert effektiv die einzigartigen zyklischen Signale des Oszillators mit der traditionellen Trendbestätigung durch gleitende Durchschnitte und schafft so einen systematischen Ansatz zur Identifizierung potenzieller Einstiege in den Markt.