English 日本語
preview
Aufbau eines nutzerdefinierten Systems zur Erkennung von Marktregimen in MQL5 (Teil 2): Expert Advisor

Aufbau eines nutzerdefinierten Systems zur Erkennung von Marktregimen in MQL5 (Teil 2): Expert Advisor

MetaTrader 5Handel |
158 1
Sahil Bagdi
Sahil Bagdi
  1. Einführung
  2. Aufbau eines adaptiven Expert Advisors
  3. Praktische Überlegungen und Optimierung
  4. Indikator: Multi-Timeframe Regimes
  5. Evaluierung des adaptiven Expert Advisors: Backtest-Ergebnisse
  6. Schlussfolgerung


Einführung

In Teil 1 dieser Serie haben wir die wesentlichen Grundlagen für die Bewältigung der Herausforderung der sich ständig verändernden Marktdynamik gelegt. Wir haben eine solide statistische Grundlage geschaffen, die Klasse CMarketRegimeDetector konstruiert, die in der Lage ist, das Marktverhalten objektiv zu klassifizieren, und einen nutzerdefinierten Indikator ( MarketRegimeIndicator ) entwickelt, um diese Regime direkt in unseren Charts zu visualisieren. Wir sind von der Erkennung des Problems - der Leistungsverschlechterung statischer Strategien auf dynamischen Märkten - zur Entwicklung eines Systems übergegangen, das den vorherrschenden Marktzustand erkennen kann: Trends (Aufwärts/Abwärts), Ranging oder Volatile (Link Teil 1 als Referenz).

Die Identifizierung des derzeitigen Regimes ist jedoch nur die halbe Miete. Die wahre Stärke liegt in der Anpassung unseres Handelsansatzes auf der Grundlage dieses Wissens. Ein Detektor, egal wie ausgeklügelt er ist, bleibt ein Analyseinstrument, bis seine Erkenntnisse in umsetzbare Handelsentscheidungen umgewandelt werden. Wie wäre es, wenn unser Handelssystem automatisch einen Gang höher schalten könnte, indem es bei starken Trends die Trendfolgelogik einsetzt, bei Seitwärtsmärkten auf die Taktik der Rückkehr zum Mittelwert umschaltet und bei Volatilitätsspitzen die Risikoparameter anpasst?

Genau diese Lücke werden wir in Teil 2 schließen. Aufbauend auf den zuvor geschaffenen Grundlagen werden wir uns nun auf die praktische Anwendung und Verfeinerung konzentrieren. In diesem Artikel werden wir uns damit befassen:

  • Aufbau eines adaptiven Expert Advisors (EA): Wir werden ein vollständiges MarketRegimeEA konstruieren, das unseren CMarketRegimeDetector integriert, um automatisch verschiedene Handelsstrategien (Trendfolge, Rückkehr zum Mittelwert, Ausbruch) auszuwählen und auszuführen, die auf das erkannte Regime zugeschnitten sind.
  • Einführung eines regimetypischen Risikomanagements: Der EA zeigt Ihnen, wie Sie Parameter wie Losgröße, Stop-Loss und Take-Profit an die aktuelle Marktlage anpassen können.
  • Praktische Überlegungen: Wir werden wichtige Aspekte der praktischen Umsetzung untersuchen, einschließlich der Parameteroptimierung für verschiedene Instrumente und Zeitrahmen.
  • Umgang mit Regimeübergängen: Strategien zur Bewältigung der kritischen Momente, in denen der Markt von einem Regime zum anderen wechselt, um eine reibungslosere Anpassung der Strategie zu gewährleisten.
  • Integrationstechniken: Erörterung der Frage, wie das Market Regime Detection System in Ihr bestehendes Handelssystem integriert werden kann, um dessen Anpassungsfähigkeit zu verbessern.

Am Ende dieses zweiten Teils werden Sie nicht nur wissen, wie man Marktregimes erkennt, sondern auch, wie man ein automatisiertes Handelssystem aufbaut, das sein Verhalten intelligent anpasst, um unter den verschiedenen Bedingungen der Finanzmärkte eine konsistentere Performance zu erzielen. Lassen Sie uns unser Erkennungssystem in eine wirklich adaptive Handelslösung umwandeln.


Aufbau eines adaptiven Expert Advisors

In diesem Abschnitt werden wir einen Expert Advisor erstellen, der unseren Market Regime Detector verwendet, um seine Handelsstrategie an die aktuellen Marktbedingungen anzupassen. Dies zeigt, wie die Regime-Erkennung in ein vollständiges Handelssystem integriert werden kann.

Der MarktRegimeEA

Unser Expert Advisor verwendet unterschiedliche Handelsansätze für verschiedene Marktregime:
  • Auf Märkten, die sich im Trend befinden, werden Trendfolgestrategien eingesetzt.
  • In Seitwärtsmärkten (ranging) wird sie Strategien zur Rückkehr zum Mittelwert anwenden.
  • In volatilen Märkten werden Ausbruchsstrategien mit reduzierten Positionsgrößen eingesetzt.

Hier ist die Umsetzung:

// Include the Market Regime Detector
#include <MarketRegimeEnum.mqh>
#include <MarketRegimeDetector.mqh>

// EA input parameters
input int      LookbackPeriod = 100;       // Lookback period for calculations
input int      SmoothingPeriod = 10;       // Smoothing period for regime transitions
input double   TrendThreshold = 0.2;       // Threshold for trend detection (0.1-0.5) 
input double   VolatilityThreshold = 1.5;  // Threshold for volatility detection (1.0-3.0)

// Trading parameters
input double   TrendingLotSize = 0.1;      // Lot size for trending regimes
input double   RangingLotSize = 0.05;      // Lot size for ranging regimes
input double   VolatileLotSize = 0.02;     // Lot size for volatile regimes
input int      TrendingStopLoss = 100;     // Stop loss in points for trending regimes
input int      RangingStopLoss = 50;       // Stop loss in points for ranging regimes
input int      VolatileStopLoss = 150;     // Stop loss in points for volatile regimes
input int      TrendingTakeProfit = 200;   // Take profit in points for trending regimes
input int      RangingTakeProfit = 80;     // Take profit in points for ranging regimes
input int      VolatileTakeProfit = 300;   // Take profit in points for volatile regimes

// Global variables
CMarketRegimeDetector *Detector = NULL;
int OnBarCount = 0;
datetime LastBarTime = 0;

Der EA enthält Parameter zur Konfiguration sowohl der Regime-Erkennung als auch der Handelsstrategie. Beachten Sie, dass wir unterschiedliche Losgrößen, Stop-Losses und Gewinnmitnahmen für verschiedene Marktregimes verwenden. Dadurch kann die EA ihren Risikomanagementansatz an die aktuellen Marktbedingungen anpassen.

EA-Initialisierung

Die Funktion OnInit() erstellt und konfiguriert den Marktregime-Detektor:

int OnInit()
{
    // Create and initialize the Market Regime Detector
    Detector = new CMarketRegimeDetector(LookbackPeriod, SmoothingPeriod);
    if(Detector == NULL)
    {
        Print("Failed to create Market Regime Detector");
        return INIT_FAILED;
    }
    
    // Configure the detector
    Detector.SetTrendThreshold(TrendThreshold);
    Detector.SetVolatilityThreshold(VolatilityThreshold);
    Detector.Initialize();
    
    // Initialize variables
    OnBarCount = 0;
    LastBarTime = 0;
    
    return INIT_SUCCEEDED;
}

Diese Funktion erstellt und konfiguriert den Marktregime-Detektor mit den vom Nutzer angegebenen Parametern. Außerdem werden die Variablen für die Balkenzählung initialisiert, mit denen wir neue Balken verfolgen werden.

Die Tick-Verarbeitung des EAs

Die Funktion OnTick() verarbeitet neue Kursdaten und führt die regelbasierte Handelsstrategie aus:

void OnTick()
{
    // Check for new bar
    datetime currentBarTime = iTime(Symbol(), PERIOD_CURRENT, 0);
    if(currentBarTime == LastBarTime)
        return; // No new bar
        
    LastBarTime = currentBarTime;
    OnBarCount++;
    
    // Wait for enough bars to accumulate
    if(OnBarCount < LookbackPeriod)
    {
        Comment("Accumulating data: ", OnBarCount, " of ", LookbackPeriod, " bars");
        return;
    }
    
    // Get price data
    double close[];
    ArraySetAsSeries(close, true);
    int copied = CopyClose(Symbol(), PERIOD_CURRENT, 0, LookbackPeriod, close);
    
    if(copied != LookbackPeriod)
    {
        Print("Failed to copy price data: copied = ", copied, " of ", LookbackPeriod);
        return;
    }
    
    // Process data with the detector
    if(!Detector.ProcessData(close, LookbackPeriod))
    {
        Print("Failed to process data with Market Regime Detector");
        return;
    }
    
    // Get current market regime
    ENUM_MARKET_REGIME currentRegime = Detector.GetCurrentRegime();
    
    // Display current regime information
    string regimeText = "Current Market Regime: " + Detector.GetRegimeDescription();
    string trendText = "Trend Strength: " + DoubleToString(Detector.GetTrendStrength(), 4);
    string volatilityText = "Volatility: " + DoubleToString(Detector.GetVolatility(), 4);
    
    Comment(regimeText + "\n" + trendText + "\n" + volatilityText);
    
    // Execute trading strategy based on market regime
    ExecuteRegimeBasedStrategy(currentRegime);
}
Diese Funktion:
  1. Überprüft, ob ein neuer Balken vorhanden ist, um redundante Berechnungen zu vermeiden
  2. Wartet, bis sich genügend Balken angesammelt haben, um das Regime zuverlässig zu erkennen
  3. Ruft die neuesten Preisdaten ab
  4. Verarbeitet die Daten mit dem Market Regime Detector
  5. Ruft das aktuelle Marktregime ab.
  6. Zeigt die Informationen zum Regime an
  7. Führt die regelbasierte Handelsstrategie aus

Die Verwendung von ArraySetAsSeries(close, true) ist wichtig, da sie sicherstellt, dass das Preis-Array in umgekehrter Reihenfolge indiziert wird, sodass der jüngste Preis bei Index 0 steht. Dies ist die Standard-Indexierungskonvention in MQL5 für die Arbeit mit Zeitreihendaten.

Regime-basierte Handelsstrategie

Die Funktion ExecuteRegimeBasedStrategy() implementiert unterschiedliche Handelsansätze für verschiedene Marktregime:

void ExecuteRegimeBasedStrategy(ENUM_MARKET_REGIME regime)
{
    // Check if we already have open positions
    if(PositionsTotal() > 0)
        return; // Don't open new positions if we already have one
    
    // Get current market information
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    double point = SymbolInfoDouble(Symbol(), SYMBOL_POINT);
    
    // Determine trading parameters based on regime
    double lotSize = 0.0;
    int stopLoss = 0;
    int takeProfit = 0;
    ENUM_ORDER_TYPE orderType = ORDER_TYPE_BUY;
    
    switch(regime)
    {
        case REGIME_TRENDING_UP: {
            lotSize = TrendingLotSize;
            stopLoss = TrendingStopLoss;
            takeProfit = TrendingTakeProfit;
            orderType = ORDER_TYPE_BUY; // Buy in uptrend
            break;
        }
        case REGIME_TRENDING_DOWN: {
            lotSize = TrendingLotSize;
            stopLoss = TrendingStopLoss;
            takeProfit = TrendingTakeProfit;
            orderType = ORDER_TYPE_SELL; // Sell in downtrend
            break;
	}
            
        case REGIME_RANGING: {
            // In ranging markets, we can use mean-reversion strategies
            // For simplicity, we'll use RSI to determine overbought/oversold
            double rsi[];
            ArraySetAsSeries(rsi, true);
            int rsiCopied = CopyBuffer(iRSI(Symbol(), PERIOD_CURRENT, 14, PRICE_CLOSE), 0, 0, 2, rsi);
            
            if(rsiCopied != 2)
                return;
                
            lotSize = RangingLotSize;
            stopLoss = RangingStopLoss;
            takeProfit = RangingTakeProfit;
            
            if(rsi[0] < 30) // Oversold
                orderType = ORDER_TYPE_BUY;
            else if(rsi[0] > 70) // Overbought
                orderType = ORDER_TYPE_SELL;
            else
                return; // No signal
                
            break;
        }

        case REGIME_VOLATILE: {
            // In volatile markets, we can use breakout strategies
            // For simplicity, we'll use Bollinger Bands
            double upper[], lower[];
            ArraySetAsSeries(upper, true);
            ArraySetAsSeries(lower, true);
            
            int bbCopied1 = CopyBuffer(iBands(Symbol(), PERIOD_CURRENT, 20, 2, 0, PRICE_CLOSE), 1, 0, 2, upper);
            int bbCopied2 = CopyBuffer(iBands(Symbol(), PERIOD_CURRENT, 20, 2, 0, PRICE_CLOSE), 2, 0, 2, lower);
            
            if(bbCopied1 != 2 || bbCopied2 != 2)
                return;
                
            lotSize = VolatileLotSize;
            stopLoss = VolatileStopLoss;
            takeProfit = VolatileTakeProfit;
            
            double close[];
            ArraySetAsSeries(close, true);
            int copied = CopyClose(Symbol(), PERIOD_CURRENT, 0, 2, close);
            
            if(copied != 2)
                return;
                
            if(close[1] < upper[1] && close[0] > upper[0]) // Breakout above upper band
                orderType = ORDER_TYPE_BUY;
            else if(close[1] > lower[1] && close[0] < lower[0]) // Breakout below lower band
                orderType = ORDER_TYPE_SELL;
            else
                return; // No signal
                
            break;
        }

        default:
            return; // No trading in undefined regime
    }
    
    // Calculate stop loss and take profit levels
    double slLevel = 0.0;
    double tpLevel = 0.0;
    
    if(orderType == ORDER_TYPE_BUY)
    {
        slLevel = ask - stopLoss * point;
        tpLevel = ask + takeProfit * point;
    }
    else if(orderType == ORDER_TYPE_SELL)
    {
        slLevel = bid + stopLoss * point;
        tpLevel = bid - takeProfit * point;
    }
    
    // Execute trade
    MqlTradeRequest request;
    MqlTradeResult result;
    
    ZeroMemory(request);
    ZeroMemory(result);
    
    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = lotSize;
    request.type = orderType;
    request.price = (orderType == ORDER_TYPE_BUY) ? ask : bid;
    request.sl = slLevel;
    request.tp = tpLevel;
    request.deviation = 10;
    request.magic = 123456; // Magic number for this EA
    request.comment = "Market Regime: " + Detector.GetRegimeDescription();
    request.type_filling = ORDER_FILLING_FOK;
    
    bool success = OrderSend(request, result);
    
    if(success)
    {
        Print("Trade executed successfully: ", result.retcode, " ", result.comment);
    }
    else
    {
        Print("Trade execution failed: ", result.retcode, " ", result.comment);
    }
}
Diese Funktion implementiert eine umfassende regelbasierte Handelsstrategie:
  1. Trend-Regimes: Nutzt Trendfolgestrategien, kauft bei Aufwärtstrends und verkauft bei Abwärtstrends.
  2. Ranging-Regimes: Verwendet die Strategie der Rückkehr zum Mittelwert auf der Grundlage des RSI, wobei er kauft, wenn er überverkauft ist, und verkauft, wenn er überkauft ist.
  3. Volatil-Regimes: Verwendet Breakout-Strategien auf der Grundlage von Bollinger-Bändern, mit reduzierten Positionsgrößen zur Risikosteuerung.
Für jedes Regime legt die Funktion auf der Grundlage der vom Nutzer angegebenen Parameter geeignete Losgrößen, Stop-Losses und Take-Profits fest. Anschließend werden die spezifischen Stop-Loss- und Take-Profit-Levels berechnet und der Handel mit der Funktion OrderSend() ausgeführt.

Die Anwendung verschiedener Strategien für verschiedene Regime ist die wichtigste Neuerung dieses EA. Durch die Anpassung seines Ansatzes an die aktuellen Marktbedingungen kann der EA eine konsistentere Performance in einem breiten Spektrum von Marktverhalten erzielen.

EA-Bereinigung

Die Funktion OnDeinit() sorgt für eine ordnungsgemäße Bereinigung, wenn der EA entfernt wird:

void OnDeinit(const int reason)
{
    // Clean up
    if(Detector != NULL)
    {
        delete Detector;
        Detector = NULL;
    }
    
    // Clear the comment
    Comment("");
}

Diese Funktion löscht das Market Regime Detector-Objekt, um Speicherlecks zu vermeiden, und löscht alle Kommentare aus dem Chart.

Vorteile des regelbasierten Handels

Dieser Expert Advisor demonstriert mehrere wichtige Vorteile des regelbasierten Handels:
  1. Anpassungsfähigkeit: Der EA passt seine Handelsstrategie automatisch an die aktuellen Marktbedingungen an, indem er unterschiedliche Ansätze für verschiedene Regimes verwendet.
  2. Risikomanagement: Der EA passt die Positionsgrößen auf der Grundlage der Marktvolatilität an, indem er in volatileren Zeiten kleinere Positionen einsetzt, um das Risiko zu steuern.
  3. Auswahl der Strategie: Der EA wählt für jedes Regime die am besten geeignete Strategie aus, wobei er bei trendfolgenden Märkten die Trendfolgestrategie und bei schwankenden Märkten die Rückkehr zum Mittelwert verwendet.
  4. Transparenz: Der EA zeigt das aktuelle Marktregime und seine wichtigsten Merkmale deutlich an und bietet Händlern damit einen wertvollen Kontext für ihre Handelsentscheidungen.

Indem wir die Erkennung von Marktregimen in Ihre Handelssysteme integrieren, können wir ähnliche Vorteile erzielen und robustere und anpassungsfähigere Strategien entwickeln, die unter einer Vielzahl von Marktbedingungen gut funktionieren.

Im nächsten Abschnitt werden wir praktische Überlegungen zur Implementierung und Optimierung des Market Regime Detection Systems in realen Handelsumgebungen diskutieren.


Praktische Überlegungen und Optimierung

In diesem letzten Abschnitt werden wir praktische Überlegungen zur Implementierung und Optimierung des Market Regime Detection Systems in realen Handelsumgebungen diskutieren. Wir befassen uns mit der Optimierung von Parametern, der Handhabung von Regimeübergängen und der Integration in bestehende Handelssysteme.

Optimierung der Parameter

Die Wirksamkeit unseres Systems zur Erkennung von Marktregimen hängt wesentlich von der Wahl der Parameter ab. Hier sind die wichtigsten Parameter, die Händler für ihre spezifischen Handelsinstrumente und Zeitrahmen optimieren sollten:

  1. Rückblickzeitraum: Der Rückblickzeitraum bestimmt, wie viele historische Daten für die Regimeerkennung verwendet werden. Längere Zeiträume bieten stabilere Klassifizierungen, reagieren aber möglicherweise weniger stark auf aktuelle Marktveränderungen. Kürzere Zeiträume sind reaktionsschneller, können aber mehr Fehlsignale erzeugen.
    // Example of testing different lookback periods
    for(int lookback = 50; lookback <= 200; lookback += 25)
    {
        CMarketRegimeDetector detector(lookback, SmoothingPeriod);
        detector.SetTrendThreshold(TrendThreshold);
        detector.SetVolatilityThreshold(VolatilityThreshold);
        
        // Process historical data and evaluate performance
        // ...
    }
    
    In der Regel eignen sich für die meisten Instrumente und Zeitrahmen Rückblickzeiträume zwischen 50 und 200 Bars. Der optimale Wert hängt von der typischen Dauer der Marktregime für das gehandelte Instrument ab.

  2. Trend-Schwellenwert: Die Trendschwelle legt fest, wie stark ein Trend sein muss, damit der Markt als tendenziell eingestuft wird. Höhere Schwellenwerte führen zu einer geringeren Anzahl von Trendklassifizierungen, jedoch mit höherer Zuverlässigkeit. Niedrigere Schwellenwerte lassen mehr Trends erkennen, schließen aber möglicherweise schwächere Trends ein.
    // Example of testing different trend thresholds
    for(double threshold = 0.1; threshold <= 0.5; threshold += 0.05)
    {
        CMarketRegimeDetector detector(LookbackPeriod, SmoothingPeriod);
        detector.SetTrendThreshold(threshold);
        detector.SetVolatilityThreshold(VolatilityThreshold);
        
        // Process historical data and evaluate performance
        // ...
    }
    Trendschwellen zwischen 0,1 und 0,3 sind übliche Ausgangspunkte. Der optimale Wert hängt vom typischen Trendverhalten des Instruments ab.

  3. Schwellenwert für die Volatilität: Die Volatilitätsschwelle legt fest, wie viel Volatilität erforderlich ist, um den Markt als volatil einzustufen. Höhere Schwellenwerte führen zu weniger volatilen Einstufungen, während niedrigere Schwellenwerte volatilere Perioden identifizieren.
    // Example of testing different volatility thresholds
    for(double threshold = 1.0; threshold <= 3.0; threshold += 0.25)
    {
        CMarketRegimeDetector detector(LookbackPeriod, SmoothingPeriod);
        detector.SetTrendThreshold(TrendThreshold);
        detector.SetVolatilityThreshold(threshold);
        
        // Process historical data and evaluate performance
        // ...
    }
    Volatilitätsschwellen zwischen 1,5 und 2,5 sind übliche Ausgangspunkte. Der optimale Wert hängt von den typischen Volatilitätsmerkmalen des Instruments ab.

Umgang mit Regimeübergängen

Anmerkung: Bei den folgenden 5 Codeblöcken handelt es sich nicht um die Umsetzung der Idee, sondern nur um Ideen und Pseudocode, wie die Umsetzung aussehen könnte.

Regimeübergänge sind kritische Momente, die besondere Aufmerksamkeit erfordern. Abrupte Änderungen der Handelsstrategie während der Übergänge können zu schlechter Ausführung und erhöhtem Slippage führen. Hier finden Sie Strategien, um Übergänge effektiver zu gestalten

  1. Übergänge glätten: Der Parameter für die Glättungsperiode trägt dazu bei, das Rauschen der Regimeklassifizierung zu reduzieren, indem ein Regime für eine Mindestanzahl von Balken bestehen bleiben muss, bevor es erkannt wird:
    // Example of implementing smoothed regime transitions
    ENUM_MARKET_REGIME SmoothRegimeTransition(ENUM_MARKET_REGIME newRegime)
    {
        static ENUM_MARKET_REGIME regimeHistory[20];
        static int historyCount = 0;
        
        // Add new regime to history
        for(int i = 19; i > 0; i--)
            regimeHistory[i] = regimeHistory[i-1];
            
        regimeHistory[0] = newRegime;
        
        if(historyCount < 20)
            historyCount++;
            
        // Count occurrences of each regime
        int regimeCounts[5] = {0};
        
        for(int i = 0; i < historyCount; i++)
            regimeCounts[regimeHistory[i]]++;
            
        // Find most common regime
        int maxCount = 0;
        ENUM_MARKET_REGIME dominantRegime = REGIME_UNDEFINED;
        
        for(int i = 0; i < 5; i++)
        {
            if(regimeCounts[i] > maxCount)
            {
                maxCount = regimeCounts[i];
                dominantRegime = (ENUM_MARKET_REGIME)i;
            }
        }
        
        return dominantRegime;
    }
    Diese Funktion speichert eine Historie der letzten Regimeklassifizierungen und gibt das häufigste Regime zurück, wodurch die Auswirkungen vorübergehender Schwankungen verringert werden.

  2. Graduelle Positionsanpassung: Bei Regimewechseln ist es oft ratsam, die Positionsgrößen schrittweise anzupassen, anstatt abrupte Änderungen vorzunehmen:
    // Example of gradual position sizing during transitions
    double CalculateTransitionLotSize(ENUM_MARKET_REGIME previousRegime, 
                                     ENUM_MARKET_REGIME currentRegime,
                                     int transitionBars,
                                     int maxTransitionBars)
    {
        // Base lot sizes for each regime
        double regimeLotSizes[5] = {
            TrendingLotSize,    // REGIME_TRENDING_UP
            TrendingLotSize,    // REGIME_TRENDING_DOWN
            RangingLotSize,     // REGIME_RANGING
            VolatileLotSize,    // REGIME_VOLATILE
            0.0                 // REGIME_UNDEFINED
        };
        
        // If not in transition, use current regime's lot size
        if(previousRegime == currentRegime || transitionBars >= maxTransitionBars)
            return regimeLotSizes[currentRegime];
            
        // Calculate weighted average during transition
        double previousWeight = (double)(maxTransitionBars - transitionBars) / maxTransitionBars;
        double currentWeight = (double)transitionBars / maxTransitionBars;
        
        return regimeLotSizes[previousRegime] * previousWeight + 
               regimeLotSizes[currentRegime] * currentWeight;
    }
    Diese Funktion berechnet einen gewichteten Durchschnitt der Positionsgrößen bei Regimewechseln und sorgt so für eine gleichmäßigere Anpassung bei Marktveränderungen.

Integration mit bestehenden Handelssystemen

Das Market Regime Detection System kann in bestehende Handelssysteme integriert werden, um deren Leistung zu verbessern. Hier finden Sie Strategien für eine effektive Integration:

  1. Auswahl der Strategie: Nutzen Sie die ermittelte Regelung, um die am besten geeignete Handelsstrategie zu wählen:
    // Example of strategy selection based on market regime
    bool ExecuteTradeSignal(ENUM_MARKET_REGIME regime, int strategySignal)
    {
        // Strategy signal: 1 = buy, -1 = sell, 0 = no signal
        
        switch(regime)
        {
            case REGIME_TRENDING_UP:
            case REGIME_TRENDING_DOWN:
                // In trending regimes, only take signals in the direction of the trend
                if((regime == REGIME_TRENDING_UP && strategySignal == 1) ||
                   (regime == REGIME_TRENDING_DOWN && strategySignal == -1))
                    return true;
                break;
                
            case REGIME_RANGING:
                // In ranging regimes, take all signals
                if(strategySignal != 0)
                    return true;
                break;
                
            case REGIME_VOLATILE:
                // In volatile regimes, be more selective
                // Only take strong signals (implementation depends on strategy)
                if(IsStrongSignal(strategySignal))
                    return true;
                break;
                
            default:
                // In undefined regimes, don't trade
                break;
        }
        
        return false;
    }
    Diese Funktion filtert Handelssignale auf der Grundlage des aktuellen Marktregimes und führt nur die Handelsgeschäfte aus, die mit den Eigenschaften des Regimes übereinstimmen.

  2. Anpassung der Parameter: Anpassung der Strategieparameter auf der Grundlage des festgestellten Regimes:
    // Example of parameter adaptation based on market regime
    void AdaptStrategyParameters(ENUM_MARKET_REGIME regime)
    {
        switch(regime)
        {
            case REGIME_TRENDING_UP:
            case REGIME_TRENDING_DOWN:
                // In trending regimes, use longer moving averages
                FastPeriod = 20;
                SlowPeriod = 50;
                // Use wider stop losses
                StopLoss = TrendingStopLoss;
                // Use larger take profits
                TakeProfit = TrendingTakeProfit;
                break;
                
            case REGIME_RANGING:
                // In ranging regimes, use shorter moving averages
                FastPeriod = 10;
                SlowPeriod = 25;
                // Use tighter stop losses
                StopLoss = RangingStopLoss;
                // Use smaller take profits
                TakeProfit = RangingTakeProfit;
                break;
                
            case REGIME_VOLATILE:
                // In volatile regimes, use very short moving averages
                FastPeriod = 5;
                SlowPeriod = 15;
                // Use wider stop losses
                StopLoss = VolatileStopLoss;
                // Use larger take profits
                TakeProfit = VolatileTakeProfit;
                break;
                
            default:
                // In undefined regimes, use default parameters
                FastPeriod = 14;
                SlowPeriod = 28;
                StopLoss = 100;
                TakeProfit = 200;
                break;
        }
    }
    Diese Funktion passt die Strategieparameter auf der Grundlage des aktuellen Marktregimes an und optimiert die Strategie für die spezifischen Marktbedingungen.

Leistungsüberwachung

Überwachen Sie regelmäßig die Leistung Ihres Systems zur Erkennung von Marktregimen, um sicherzustellen, dass es die Marktregime richtig klassifiziert:

// Example of performance monitoring for regime detection
void MonitorRegimeDetectionPerformance()
{
    static int regimeTransitions = 0;
    static int correctPredictions = 0;
    static ENUM_MARKET_REGIME lastRegime = REGIME_UNDEFINED;
    
    // Get current regime
    ENUM_MARKET_REGIME currentRegime = Detector.GetCurrentRegime();
    
    // If regime has changed, evaluate the previous regime's prediction
    if(currentRegime != lastRegime && lastRegime != REGIME_UNDEFINED)
    {
        regimeTransitions++;
        
        // Evaluate if the previous regime's prediction was correct
        // Implementation depends on your specific evaluation criteria
        if(EvaluateRegimePrediction(lastRegime))
            correctPredictions++;
            
        // Log performance metrics
        double accuracy = (double)correctPredictions / regimeTransitions * 100.0;
        Print("Regime Detection Accuracy: ", DoubleToString(accuracy, 2), "% (", 
              correctPredictions, "/", regimeTransitions, ")");
    }
    
    lastRegime = currentRegime;
}

Diese Funktion verfolgt die Regimeübergänge und bewertet die Genauigkeit der Regimevorhersagen, was wertvolle Rückmeldungen für die Systemoptimierung liefert.


Indikator: Multi Timeframe Regimes

Vollständiger Code:

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

// Include the Market Regime Detector
#include <MarketRegimeEnum.mqh>
#include <MarketRegimeDetector.mqh>

// Input parameters
input int      LookbackPeriod = 100;       // Lookback period for calculations
input double   TrendThreshold = 0.2;       // Threshold for trend detection (0.1-0.5)
input double   VolatilityThreshold = 1.5;  // Threshold for volatility detection (1.0-3.0)

// Timeframes to analyze
input bool     UseM1 = false;              // Use 1-minute timeframe
input bool     UseM5 = false;              // Use 5-minute timeframe
input bool     UseM15 = true;              // Use 15-minute timeframe
input bool     UseM30 = true;              // Use 30-minute timeframe
input bool     UseH1 = true;               // Use 1-hour timeframe
input bool     UseH4 = true;               // Use 4-hour timeframe
input bool     UseD1 = true;               // Use Daily timeframe
input bool     UseW1 = false;              // Use Weekly timeframe
input bool     UseMN1 = false;             // Use Monthly timeframe

// Global variables
CMarketRegimeDetector *Detectors[];
ENUM_TIMEFRAMES Timeframes[];
int TimeframeCount = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    // Initialize timeframes array
    InitializeTimeframes();
    
    // Create detectors for each timeframe
    ArrayResize(Detectors, TimeframeCount);
    
    for(int i = 0; i < TimeframeCount; i++)
    {
        Detectors[i] = new CMarketRegimeDetector(LookbackPeriod);
        if(Detectors[i] == NULL)
        {
            Print("Failed to create Market Regime Detector for timeframe ", EnumToString(Timeframes[i]));
            return INIT_FAILED;
        }
        
        // Configure the detector
        Detectors[i].SetTrendThreshold(TrendThreshold);
        Detectors[i].SetVolatilityThreshold(VolatilityThreshold);
        Detectors[i].Initialize();
    }
    
    // Set indicator name
    IndicatorSetString(INDICATOR_SHORTNAME, "Multi-Timeframe Regime Analysis");
    
    return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Initialize timeframes array based on user inputs                 |
//+------------------------------------------------------------------+
void InitializeTimeframes()
{
    // Count selected timeframes
    TimeframeCount = 0;
    if(UseM1)  TimeframeCount++;
    if(UseM5)  TimeframeCount++;
    if(UseM15) TimeframeCount++;
    if(UseM30) TimeframeCount++;
    if(UseH1)  TimeframeCount++;
    if(UseH4)  TimeframeCount++;
    if(UseD1)  TimeframeCount++;
    if(UseW1)  TimeframeCount++;
    if(UseMN1) TimeframeCount++;
    
    // Resize and fill timeframes array
    ArrayResize(Timeframes, TimeframeCount);
    
    int index = 0;
    if(UseM1)  Timeframes[index++] = PERIOD_M1;
    if(UseM5)  Timeframes[index++] = PERIOD_M5;
    if(UseM15) Timeframes[index++] = PERIOD_M15;
    if(UseM30) Timeframes[index++] = PERIOD_M30;
    if(UseH1)  Timeframes[index++] = PERIOD_H1;
    if(UseH4)  Timeframes[index++] = PERIOD_H4;
    if(UseD1)  Timeframes[index++] = PERIOD_D1;
    if(UseW1)  Timeframes[index++] = PERIOD_W1;
    if(UseMN1) Timeframes[index++] = PERIOD_MN1;
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    // Check if there's enough data
    if(rates_total < LookbackPeriod)
        return 0;
    
    // Process data for each timeframe
    string commentText = "Multi-Timeframe Regime Analysis\n\n";
    
    for(int i = 0; i < TimeframeCount; i++)
    {
        // Get price data for this timeframe
        double tfClose[];
        ArraySetAsSeries(tfClose, true);
        int copied = CopyClose(Symbol(), Timeframes[i], 0, LookbackPeriod, tfClose);
        
        if(copied != LookbackPeriod)
        {
            Print("Failed to copy price data for timeframe ", EnumToString(Timeframes[i]));
            continue;
        }
        
        // Process data with the detector
        if(!Detectors[i].ProcessData(tfClose, LookbackPeriod))
        {
            Print("Failed to process data for timeframe ", EnumToString(Timeframes[i]));
            continue;
        }
        
        // Add timeframe information to comment
        commentText += TimeframeToString(Timeframes[i]) + ": ";
        commentText += Detectors[i].GetRegimeDescription();
        commentText += " (Trend: " + DoubleToString(Detectors[i].GetTrendStrength(), 2);
        commentText += ", Vol: " + DoubleToString(Detectors[i].GetVolatility(), 2) + ")";
        commentText += "\n";
    }
    
    // Display the multi-timeframe analysis
    Comment(commentText);
    
    // Return the number of calculated bars
    return rates_total;
}

//+------------------------------------------------------------------+
//| Convert timeframe enum to readable string                        |
//+------------------------------------------------------------------+
string TimeframeToString(ENUM_TIMEFRAMES timeframe)
{
    switch(timeframe)
    {
        case PERIOD_M1:  return "M1";
        case PERIOD_M5:  return "M5";
        case PERIOD_M15: return "M15";
        case PERIOD_M30: return "M30";
        case PERIOD_H1:  return "H1";
        case PERIOD_H4:  return "H4";
        case PERIOD_D1:  return "D1";
        case PERIOD_W1:  return "W1";
        case PERIOD_MN1: return "MN1";
        default:         return "Unknown";
    }
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // Clean up
    for(int i = 0; i < TimeframeCount; i++)
    {
        if(Detectors[i] != NULL)
        {
            delete Detectors[i];
            Detectors[i] = NULL;
        }
    }
    
    // Clear the comment
    Comment("");
}

Dieser Indikator zeichnet keine Linien auf dem Chart. Stattdessen analysiert es Marktregime (Trending Up/Down, Ranging, Volatile) über mehrere vom Nutzer ausgewählte Zeitrahmen mit Hilfe der Klasse CMarketRegimeDetector (entwickelt in Teil 1) und zeigt die Ergebnisse als Text in der oberen linken Ecke des Charts an.

Code-Erläuterung:

  1. Properties & Includes:

    • #property indicator_chart_window : Lässt den Indikator im Fenster des Hauptcharts laufen.
    • #property indicator_buffers 0 , #property indicator_plots 0 : Gibt an, dass dieser Indikator selbst keine Datenpuffer oder Chartlinien/Histogramme verwendet.
    • #include <MarketRegimeEnum.mqh> , #include <MarketRegimeDetector.mqh> : Enthält die notwendigen Definitionen und die Kerndetektorklasse aus unserer früheren Arbeit.

  2. Eingabe Parameter:

    • LookbackPeriod , TrendThreshold , VolatilityThreshold : Dies sind die Grundeinstellungen für die Logik der Regimeerkennung, die einheitlich auf alle analysierten Zeiträume angewendet werden.
    • UseM1 bis UseMN1 : Eine Reihe von booleschen Eingaben, die es dem Nutzer ermöglichen, umzuschalten (wahr/falsch), welche Standardzeitrahmen (1 Minute bis monatlich) in die Analyse einbezogen werden sollen.

  3. Globale Variablen:

    • Detectors[] : Ein Array, das separate Instanzen des CMarketRegimeDetector aufnehmen kann. Für jeden ausgewählten Zeitrahmen wird hier ein eigenes Detektorobjekt gespeichert.
    • Timeframes[] : Ein Array zum Speichern der MQL5-Zeitrahmenbezeichner (wie PERIOD_H1 , PERIOD_D1 ), die den vom Nutzer über die Eingaben gewählten Zeitrahmen entsprechen.
    • TimeframeCount : Eine ganze Zahl, die anzeigt, wie viele Zeitrahmen tatsächlich ausgewählt wurden.

  4. OnInit() (Initialisierungsfunktion):

    • Läuft einmal, wenn der Indikator startet.
    • Ruft InitializeTimeframes() auf, um herauszufinden, welche Zeitrahmen der Nutzer ausgewählt hat, und füllt das Timeframes-Array auf.
    • Ändert die Größe des Arrays Detectors entsprechend der TimeframeCount.
    • Schleife für jeden (TimeframeCount) Zeitrahmen:
      • Für jeden ausgewählten Zeitrahmen wird ein neues CMarketRegimeDetector-Objekt unter Verwendung der gemeinsamen LookbackPeriod erstellt.
      • Es wird diese spezielle Detektorinstanz mit dem gemeinsamen TrendThreshold und VolatilityThreshold konfiguriert.
      • Entscheidend ist, dass jede Detektorinstanz ihren eigenen internen Zustand auf der Grundlage der Daten aus dem ihr zugewiesenen Zeitrahmen beibehält.
    • Legt den Anzeigenamen des Indikators fest.

  5. InitializeTimeframes() (Hilfsfunktion):

    • Zählt, wie viele Use...-Eingänge auf true gesetzt sind.
    • Ändert die Größe des globalen Timeframes-Arrays entsprechend.
    • Füllt das Timeframes-Array mit den aktuellen PERIOD_... Konstanten für die ausgewählten Timeframes.

  6. OnCalculate() (Hauptberechnungsfunktion):

    • Wird bei jedem neuen Tick oder Balken ausgeführt.
    • Überprüft, ob im aktuellen Zeitrahmen des Charts genügend historische Balken ( rates_total ) vorhanden sind, um die Anforderung der LookbackPeriod zu erfüllen.
    • Initialisiert eine leere Zeichenkette commentText .
    • Schleift durch jeden ausgewählten Zeitrahmen (verfolgt durch i):
      • Verwendet CopyClose(), um die letzten LookbackPeriod-Schlusskurse speziell für das Symbol() und die Timeframes[i] abzurufen (z. B. werden H4-Schlusskurse abgerufen, selbst wenn der Indikator auf einem M15-Chart läuft).
      • Ist der Datenabruf erfolgreich, wird die Methode ProcessData() des entsprechenden Detektorobjekts ( Detectors[i] ) mit den abgerufenen Preisdaten ( tfClose ) aufgerufen.
      • Hängt die Ergebnisse (Name des Zeitrahmens, Regimebeschreibung, Trendstärke, Volatilität) aus Detectors[i] an die Zeichenfolge commentText an.
    • Schließlich verwendet Comment(commentText), um die aggregierte Analyse für alle ausgewählten Zeitrahmen in der Ecke des Charts anzuzeigen.

  7. TimeframeToString() (Hilfsfunktion):

    • Ein einfaches Dienstprogramm zur Umwandlung von MQL5 PERIOD_... Konstanten in lesbare Strings wie „M1“, „H4“, „D1“.

  8. OnDeinit() (Deinitialisierungsfunktion):

    • Wird einmal ausgeführt, wenn der Indikator aus dem Chart entfernt wird oder das Terminal geschlossen wird.
    • Durchläuft das Array Detectors in einer Schleife und verwendet delete, um den für jedes in OnInit() erstellte CMarketRegimeDetector-Objekt zugewiesenen Speicher freizugeben und so Speicherlecks zu vermeiden.
    • Löscht den Textkommentar aus der Chartecke.

Im Wesentlichen richtet dieser Code auf effiziente Weise unabhängige Regime-Detektoren für mehrere Zeitrahmen ein, holt die erforderlichen Daten für jeden ab, führt die Analyse durch und präsentiert einen konsolidierten Überblick über die Regime mehrerer Zeitrahmen direkt auf dem Chart des Nutzers.

Unter Verwendung des oben genannten Multi-Time-Frame-Indikators kann ein weiterer EA erstellt werden, der mehrere Zeitrahmen analysiert, bevor er den Handel platziert. Der Kürze halber werden wir jedoch keinen weiteren Expert Advisor erstellen, sondern zunächst diesen testen.


Evaluierung des adaptiven Expert Advisors: Backtest-Ergebnisse

Nachdem das MarketRegimeEA konstruiert wurde, ist der nächste logische Schritt die Bewertung seiner Leistung durch Backtests. Auf diese Weise können wir beobachten, wie die regimeadaptive Logik auf historischen Daten funktioniert und die Auswirkungen ihrer Parametereinstellungen bewerten.

Erste Testkonfiguration

Für diese Demonstration haben wir Gold (XAUUSD) als Testinstrument ausgewählt, wobei wir Daten auf dem Zeitrahmen M1 verwenden. Die Ausgangsparameter für den EA wurden willkürlich gewählt:

  • LookbackPeriod: 100
  • SmoothingPeriod: 10
  • TrendThreshold: 0.2
  • VolatilityThreshold: 1.5
  • Losgrößen: Trending=0.1, Ranging=0.1, Volatile=0.1
  • SL: Trending=1000, Ranging=1600, Volatile=2000
  • TP: Trending=1400, Ranging=1000, Volatile=1800

Die Ausführung des EA mit diesen Standardparametern führte zu den folgenden Ergebnissen:

Wie aus der Kapitalkurve und den Leistungskennzahlen hervorgeht, führte der erste Backtest mit diesen Einstellungen zu suboptimalen Ergebnissen. Zwar gab es Zeiten, in denen die Strategie Gewinne erwirtschaftete (zu einem bestimmten Zeitpunkt erreichte sie einen Kapitalzuwachs von etwa 20 %), doch die Gesamtperformance deutet auf einen Mangel an beständiger Rentabilität und erhebliche Drawdowns hin. Dieses Ergebnis unterstreicht die Bedeutung der Parameterabstimmung für das jeweilige Instrument und den Zeitrahmen, in dem gehandelt wird. Diese Parameter dienen als Ausgangspunkt, stellen aber nicht die optimale Konfiguration dar.

Um das Potenzial für eine verbesserte Leistung zu erforschen, haben wir die Parameteroptimierungsfunktionen des MetaTrader 5 Strategy Testers unter Verwendung seines genetischen Algorithmus eingesetzt. Ziel war es, eine Reihe von Parametern (innerhalb des getesteten Bereichs) zu identifizieren, die die Regime-Erkennung und die Handelslogik besser mit dem historischen Preisverhalten von Gold während des Backtest-Zeitraums in Einklang bringen. Zu den Parametern, die optimiert werden sollten, gehörten die regimespezifischen Stop-Loss- und Take-Profit-Werte, während andere Parameter als Standardwerte festgelegt wurden.

Nach dem Optimierungsprozess stellte der Strategietester fest, dass der folgende Parametersatz zu einer deutlich verbesserten historischen Leistung führte:

Die erneute Durchführung des Backtests mit diesen optimierten Parametern ergab ein deutlich anderes Leistungsprofil: 

Der Backtest mit den optimierten Parametern zeigt eine deutliche Verbesserung, einen positiven Nettogewinn und eine günstigere Kapitalkurve im Vergleich zum ersten Lauf.

Bei der Interpretation dieser Ergebnisse ist jedoch Vorsicht geboten. Die Optimierung von Parametern, insbesondere die Verwendung von genetischen Algorithmen auf historischen Daten und die Durchführung des Backtests im selben Zeitraum, birgt das Risiko einer Überanpassung in sich. Das bedeutet, dass die Parameter für die verwendeten historischen Daten außerordentlich gut geeignet sein können, aber möglicherweise nicht gut auf zukünftige, nicht beobachtete Marktdaten verallgemeinert werden können.

Die optimierten Ergebnisse zeigen zwar das Potenzial des adaptiven Strategierahmens, wenn die Parameter angepasst werden, sie sollten jedoch nicht als endgültiger Beweis für die künftige Rentabilität angesehen werden. Der Hauptzweck dieser Übung ist die Demonstration:

  1. der Funktionsweise des regimeadaptiven EA,
  2. der wesentlichen Auswirkungen der Parameter auf die Leistung und
  3. dass das zugrundeliegende Konzept (Anpassung der Strategie an das Regime) bei entsprechender Konfiguration zu positiven Ergebnissen bei historischen Daten führen kann.

Die Tatsache, dass sogar die nicht optimierte Version Zeiten der Rentabilität aufwies, deutet darauf hin, dass die Kernlogik nicht grundlegend fehlerhaft ist. Die Entwicklung dieser Strategie zu einer robusten, produktionsreifen Strategie würde jedoch weitere Schritte erfordern, die über eine einfache Optimierung hinausgehen:

  • Rigorose Out-of-Sample-Tests zur Validierung der Robustheit der Parameter.
  • Einbeziehung eines ausgefeilteren Risikomanagements.
  • Potenzielle Anwendung der bereits besprochenen Techniken wie „Smoothing Transitions“ und „Gradual Position Sizing“, um Regimewechsel effektiver zu gestalten.


Schlussfolgerung

Im Laufe dieser zweiteiligen Serie haben wir uns von der Identifizierung einer grundlegenden Herausforderung im algorithmischen Handel - der nachteiligen Auswirkung sich ändernder Marktbedingungen auf statische Strategien - bis zur Entwicklung und Implementierung einer vollständigen, adaptiven Lösung vorgearbeitet. In Teil 1 haben wir den Motor zum Verständnis des Marktzustands aufgebaut, indem wir ein statistisch fundiertes System zur Erkennung von Marktregimen entwickelt und dessen Ergebnisse visualisiert haben.

In diesem zweiten und abschließenden Teil haben wir den entscheidenden Schritt vom Erkennen zum Handeln getan. Wir haben gezeigt, wie man die Leistungsfähigkeit unseres CMarketRegimeDetectors nutzen kann, indem wir den MarketRegimeEA entwickelt haben, einen Expert Advisor, der in der Lage ist, automatisch zwischen den Strategien für die Trendfolge, der Rückkehr zum Mittelwert und dem Ausbruck auf der Grundlage des identifizierten Marktregimes zu wechseln. Wir haben gesehen, wie die Anpassung nicht nur der Einstiegslogik, sondern auch von Risikoparametern wie Losgröße und Stop-Levels einen widerstandsfähigeren Handelsansatz schaffen kann.

Darüber hinaus haben wir uns mit den praktischen Realitäten der Einführung eines solchen Systems befasst. Wir untersuchten die Bedeutung der Parameteroptimierung (Lookback-Periode, Trendschwelle, Volatilitätsschwelle), um den Detektor auf spezifische Marktcharakteristika abzustimmen, und erörterten Techniken für den reibungslosen Umgang mit Regimeübergängen, um mögliche „Whipsaws“ oder abrupte Strategiewechsel zu minimieren. Schließlich haben wir erörtert, wie dieser Rahmen zur Erkennung von Regimen in bestehende Handelssysteme integriert werden kann, indem er als intelligenter Filter oder Parameteranpasser fungiert.

Das Ziel war ehrgeizig: Es sollten Handelssysteme geschaffen werden, die die dem Markt innewohnende Nicht-Stationarität anerkennen und sich an sie anpassen. Durch die Kombination der in Teil 1 entwickelten Erkennungsfähigkeiten mit dem adaptiven Ausführungsrahmen und den praktischen Überlegungen, die in Teil 2 erörtert werden, verfügen Sie nun über den Entwurf für den Aufbau von Strategien, die wesentlich robuster und auf die Dynamik der Finanzmärkte abgestimmt sind. Der Übergang von einem statischen zu einem anpassungsfähigen Ansatz ist vollzogen und ermöglicht es Ihnen, die Komplexität des Marktes mit größerer Intelligenz und Flexibilität zu bewältigen.


Datei-Übersicht

Hier finden Sie eine Zusammenfassung aller in diesem Artikel erstellten Dateien:
Dateiname Beschreibung
MarketRegimeEnum.mqh
Definiert die im gesamten System verwendeten Enumerationstypen des Marktregimes.
CStatistics.mqh Die Klasse der statistischen Berechnungen zur Erkennung des Marktregimes.
MarketRegimeDetector.mqh Die Umsetzung der Kern des Marktregimes.
MarketRegimeEA.mq5 Der Expert Advisor, der sich an verschiedene Marktregime anpasst
MultiTimeframeRegimes.mq5  Ein Beispiel für die Analyse von Regimen über mehrere Zeitrahmen.

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

Letzte Kommentare | Zur Diskussion im Händlerforum (1)
abhishek maderana
abhishek maderana | 12 Juli 2025 in 21:53
Ich denke, Sie bymistake hochgeladen die gleichen Parameter Bild für die verfeinerten Parameter, können Sie teilen, was waren die verfeinerten Parameter nach mt5 Optimierung?
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 60): Inferenzlernen (Wasserstein-VAE) mit gleitendem Durchschnitt und stochastischen Oszillatormustern MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 60): Inferenzlernen (Wasserstein-VAE) mit gleitendem Durchschnitt und stochastischen Oszillatormustern
Wir schließen unsere Betrachtung der komplementären Paarung von MA und stochastischem Oszillator ab, indem wir untersuchen, welche Rolle das Inferenzlernen in einer Situation nach überwachtem Lernen und Verstärkungslernen spielen kann. Es gibt natürlich eine Vielzahl von Möglichkeiten, wie man in diesem Fall das Inferenzlernen angehen kann, unser Ansatz ist jedoch die Verwendung von Variationsautokodierern. Wir untersuchen dies in Python, bevor wir unser trainiertes Modell mit ONNX exportieren, um es in einem von einem Assistenten zusammengestellten Expert Advisor in MetaTrader zu verwenden.
Datenwissenschaft und ML (Teil 37): Mit Kerzenmustern und AI den Markt schlagen Datenwissenschaft und ML (Teil 37): Mit Kerzenmustern und AI den Markt schlagen
Kerzenmuster helfen Händlern, die Marktpsychologie zu verstehen und Trends auf den Finanzmärkten zu erkennen. Sie ermöglichen fundiertere Handelsentscheidungen, die zu besseren Ergebnissen führen können. In diesem Artikel werden wir untersuchen, wie man Kerzenmuster mit KI-Modellen nutzen kann, um eine optimale Handelsperformance zu erzielen.
Neuronale Netze im Handel: Kontrollierte Segmentierung Neuronale Netze im Handel: Kontrollierte Segmentierung
In diesem Artikel wird eine Methode zur Analyse komplexer multimodaler Interaktionen und zum Verstehen von Merkmalen erörtert.
Websockets für MetaTrader 5: Asynchrone Client-Verbindungen mit dem Windows-API Websockets für MetaTrader 5: Asynchrone Client-Verbindungen mit dem Windows-API
Dieser Artikel beschreibt die Entwicklung einer nutzerdefinierten, dynamisch gelinkten Bibliothek, die asynchrone Websocket-Client-Verbindungen für MetaTrader-Programme ermöglicht.