//+------------------------------------------------------------------+ //| EMACrossOver.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property link "https://www.mql5.com" #property copyright "Copyright 2025, MetaQuotes Ltd." #property version "1.00" #include //--- Eingabeparameter (Input Parameters) - Optimized Profitable Parameters input int EMA_Periode = 51; // EMA Periode input double PreisSchwelle = 300.0; // Preisbewegung Schwelle in Pips input double SteigungSchwelle = 40.0; // EMA Steigung Schwelle in Pips input int ÜberwachungTimeout = 1600; // Überwachungszeit in Sekunden input double TrailingStop = 100.0; // Gleitender Stop in Pips input double LotGröße = 0.03; // Handelsvolumen input int MagicNumber = 12350; // Magic Number für Trades input bool UseSpreadAdjustment = true; // Spread-Anpassung verwenden input ENUM_TIMEFRAMES Timeframe = PERIOD_H1; // Zeitraum für Analyse input bool UseBarData = true; // Bar-Daten statt Tick-Daten verwenden input int MaxTradesPerCrossover = 6; // Maximale Trades pro Crossover-Ereignis input int ProfitCheckBars = 11; // Bars bis zur Profit-Prüfung input bool CloseUnprofitableTrades = true; // Unprofitable Trades nach X Bars schließen //--- V-Shape Reversal Protection Parameters input bool UseRSIFilter = true; // RSI Filter verwenden (vermeidet Extreme) input int RSIPeriod = 14; // RSI Periode input double RSIOverbought = 71.0; // RSI Überkauft Level input double RSIOversold = 31.0; // RSI Überverkauft Level input bool UseMomentumConfirmation = true; // Momentum-Bestätigung verwenden input int MomentumBars = 5; // Bars für Momentum-Prüfung input bool UsePullbackConfirmation = true; // Pullback-Bestätigung verwenden input double PullbackThreshold = 0.5; // Pullback-Schwelle (50% der Bewegung) input bool UseEarlyReversalDetection = true; // Frühe Reversal-Erkennung input double ReversalThreshold = 0.5; // Reversal-Schwelle (50% Rückgang) input bool UseMAEProtection = true; // Maximum Adverse Excursion Schutz input double MAEThreshold = 150.0; // MAE Schwelle in Pips input int MAECheckBars = 5; // Bars für MAE-Prüfung //--- V-Shape Reversal Trading Parameters input bool UseVShapeReversalTrading = true; // V-Shape Reversal Trading aktivieren input double VShapeReversalStopLoss = 100.0; // Stop Loss für V-Shape Reversal Trades (Pips) input double VShapeReversalLotSize = 0.01; // Lot-Größe für V-Shape Trades (konservativer) input bool UseRSI50Crossover = false; // RSI 50 Crossover für Haupt-Trades verwenden input int RSICrossBars = 4; // Bars für RSI Crossover Bestätigung //--- Globale Variablen (Global Variables) int ema_handle; // EMA Indicator Handle int rsi_handle; // RSI Indicator Handle double ema_array[]; // Array für EMA double rsi_array[]; // Array für RSI datetime letzte_überwachung_zeit; // Zeit der letzten Überwachung bool überwachung_aktiv = false; // Überwachungsstatus bool preis_trigger_aktiv = false; // Preis-Trigger Status bool steigung_trigger_aktiv = false; // Steigungs-Trigger Status int ticket = 0; // Trade Ticket CTrade trade; // CTrade Objekt int trades_in_current_crossover = 0; // Anzahl Trades im aktuellen Crossover bool crossover_detected = false; // Crossover erkannt datetime trade_open_time = 0; // Zeitpunkt des Trade-Öffnens double entry_price = 0; // Einstiegspreis für MAE-Prüfung double max_favorable_excursion = 0; // Maximale günstige Bewegung double max_adverse_excursion = 0; // Maximale ungünstige Bewegung double trigger_price = 0; // Preis beim Trigger für Pullback-Prüfung bool is_vshape_trade = false; // Ist aktueller Trade ein V-Shape Reversal Trade double last_rsi = 50.0; // Letzter RSI-Wert für Crossover-Erkennung bool rsi_crossed_above_50 = false; // RSI über 50 gekreuzt bool rsi_crossed_below_50 = false; // RSI unter 50 gekreuzt //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- CTrade konfigurieren (Configure CTrade) trade.SetExpertMagicNumber(MagicNumber); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_IOC); //--- EMA Indicator Handle erstellen (Create EMA indicator handle) ema_handle = iMA(_Symbol, Timeframe, EMA_Periode, 0, MODE_EMA, PRICE_CLOSE); if(ema_handle == INVALID_HANDLE) { Print("Fehler beim Erstellen des EMA Indicators"); return(INIT_FAILED); } //--- RSI Indicator Handle erstellen (Create RSI indicator handle) if(UseRSIFilter || UseVShapeReversalTrading || UseRSI50Crossover) { rsi_handle = iRSI(_Symbol, Timeframe, RSIPeriod, PRICE_CLOSE); if(rsi_handle == INVALID_HANDLE) { Print("Fehler beim Erstellen des RSI Indicators"); return(INIT_FAILED); } ArraySetAsSeries(rsi_array, true); // Initialisiere RSI Tracking (Initialize RSI tracking) if(UseRSI50Crossover) { BerechneRSI(); if(ArraySize(rsi_array) > 0) { last_rsi = rsi_array[0]; rsi_crossed_above_50 = (last_rsi > 50.0); rsi_crossed_below_50 = (last_rsi < 50.0); } } } //--- Arrays initialisieren (Initialize arrays) ArraySetAsSeries(ema_array, true); //--- Arrays mit aktuellen Werten füllen (Fill arrays with current values) BerechneEMA(); if(UseRSIFilter) { BerechneRSI(); } Print("EMA EA initialisiert - Periode: ", EMA_Periode, " Timeframe: ", EnumToString(Timeframe), " Handle: ", ema_handle); if(UseRSIFilter) { Print("RSI Filter aktiviert - Periode: ", RSIPeriod); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- Indicator Handle freigeben (Release indicator handle) if(ema_handle != INVALID_HANDLE) { IndicatorRelease(ema_handle); } if((UseRSIFilter || UseVShapeReversalTrading || UseRSI50Crossover) && rsi_handle != INVALID_HANDLE) { IndicatorRelease(rsi_handle); } Print("EA beendet - Grund: ", reason); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Bar-Daten oder Tick-Daten verwenden (Use bar data or tick data) if(UseBarData) { //--- Nur bei neuen Bars ausführen (Only execute on new bars) static datetime last_bar_time = 0; datetime current_bar_time = iTime(_Symbol, Timeframe, 0); if(current_bar_time == last_bar_time) { return; // Kein neuer Bar, nichts tun } last_bar_time = current_bar_time; } //--- EMA Werte berechnen (Calculate EMA values) BerechneEMA(); //--- RSI Werte berechnen (Calculate RSI values) if(UseRSIFilter || UseVShapeReversalTrading || UseRSI50Crossover) { BerechneRSI(); //--- RSI Crossover Tracking für Haupt-Trades (RSI Crossover tracking for main trades) if(UseRSI50Crossover && ArraySize(rsi_array) >= 2) { double current_rsi = rsi_array[0]; double previous_rsi = rsi_array[1]; // Prüfe RSI Crossover über 50 (Check RSI crossover above 50) if(previous_rsi <= 50.0 && current_rsi > 50.0) { rsi_crossed_above_50 = true; rsi_crossed_below_50 = false; Print("TRACE: RSI über 50 gekreuzt - Vorher: ", previous_rsi, " Jetzt: ", current_rsi); } // Prüfe RSI Crossover unter 50 (Check RSI crossover below 50) else if(previous_rsi >= 50.0 && current_rsi < 50.0) { rsi_crossed_below_50 = true; rsi_crossed_above_50 = false; Print("TRACE: RSI unter 50 gekreuzt - Vorher: ", previous_rsi, " Jetzt: ", current_rsi); } last_rsi = current_rsi; } } //--- Debug: Aktuelle Werte ausgeben (Debug: Output current values) if(ArraySize(ema_array) > 0) { double aktueller_close = iClose(_Symbol, Timeframe, 0); double ema_aktuell = ema_array[0]; double ema_vorher = ema_array[1]; double preis_abstand = MathAbs(aktueller_close - ema_aktuell) / _Point; double steigung = (ema_aktuell - ema_vorher) / _Point; if(UseBarData) { Print("=== DEBUG INFO (Neuer Bar) ==="); Print("Bar Zeit: ", TimeToString(iTime(_Symbol, Timeframe, 0))); } else { Print("=== DEBUG INFO (Tick) ==="); } Print("Aktueller Close: ", aktueller_close); Print("EMA: ", ema_aktuell); Print("Preis-Abstand: ", preis_abstand, " Pips"); Print("EMA Steigung: ", steigung, " Pips"); Print("Differenz Close-EMA: ", aktueller_close - ema_aktuell); Print("Preis-Trigger: ", preis_trigger_aktiv, " Steigungs-Trigger: ", steigung_trigger_aktiv); Print("Überwachung aktiv: ", überwachung_aktiv); Print("Position offen: ", PositionSelect(_Symbol)); Print("Trades im aktuellen Crossover: ", trades_in_current_crossover, "/", MaxTradesPerCrossover); Print("=================="); } //--- Überwachung prüfen (Check monitoring) if(überwachung_aktiv) { if(UseBarData) { // Bar-basierte Überwachungszeit int bars_since_monitoring = iBarShift(_Symbol, Timeframe, letzte_überwachung_zeit); int timeout_bars = (int)(ÜberwachungTimeout / PeriodSeconds(Timeframe)); if(bars_since_monitoring > timeout_bars) { überwachung_aktiv = false; preis_trigger_aktiv = false; steigung_trigger_aktiv = false; Print("Überwachung beendet - Bar-basierte Zeitüberschreitung (", bars_since_monitoring, " Bars)"); } } else { // Tick-basierte Überwachungszeit if(TimeCurrent() - letzte_überwachung_zeit > ÜberwachungTimeout) { überwachung_aktiv = false; preis_trigger_aktiv = false; steigung_trigger_aktiv = false; Print("Überwachung beendet - Tick-basierte Zeitüberschreitung"); } } } //--- Trigger-Bedingungen prüfen (Check trigger conditions) PrüfeTrigger(); //--- Trade Management (Trade management) VerwalteTrades(); //--- MAE Protection prüfen (Check MAE protection) if(UseMAEProtection && PositionSelect(_Symbol)) { PrüfeMAE(); } } //+------------------------------------------------------------------+ //| EMA Berechnung (EMA Calculation) | //+------------------------------------------------------------------+ void BerechneEMA() { //--- EMA Werte vom Indicator kopieren (Copy EMA values from indicator) int copied = CopyBuffer(ema_handle, 0, 0, 3, ema_array); if(copied <= 0) { Print("TRACE: Fehler beim Kopieren der EMA Werte - Copied: ", copied); return; } Print("TRACE: EMA Werte kopiert: ", copied, " Bars"); Print("TRACE: EMA [0]: ", ema_array[0], " [1]: ", ema_array[1], " [2]: ", ema_array[2]); } //+------------------------------------------------------------------+ //| RSI Berechnung (RSI Calculation) | //+------------------------------------------------------------------+ void BerechneRSI() { if(!UseRSIFilter || rsi_handle == INVALID_HANDLE) return; //--- RSI Werte vom Indicator kopieren (Copy RSI values from indicator) int copied = CopyBuffer(rsi_handle, 0, 0, 3, rsi_array); if(copied <= 0) { Print("TRACE: Fehler beim Kopieren der RSI Werte - Copied: ", copied); return; } Print("TRACE: RSI Werte kopiert: ", copied, " Bars"); Print("TRACE: RSI [0]: ", rsi_array[0], " [1]: ", rsi_array[1], " [2]: ", rsi_array[2]); } //+------------------------------------------------------------------+ //| Trigger-Bedingungen prüfen (Check trigger conditions) | //+------------------------------------------------------------------+ void PrüfeTrigger() { if(ArraySize(ema_array) < 2) { Print("TRACE: Array zu klein - Größe: ", ArraySize(ema_array)); return; } //--- Aktuelle Werte (Current values) double aktueller_preis = SymbolInfoDouble(_Symbol, SYMBOL_BID); double aktueller_ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double aktueller_close = iClose(_Symbol, Timeframe, 0); double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; //--- EMA Werte in Variablen (EMA values in variables) double ema_aktuell = ema_array[0]; double ema_vorher = ema_array[1]; //--- EMA Crossover Erkennung (EMA Crossover Detection) // Prüfe ob Preis die EMA kreuzt (Check if price crosses EMA) static double last_close = 0; static double last_ema = 0; if(last_close != 0 && last_ema != 0) { bool crossover_bullish = (last_close <= last_ema) && (aktueller_close > ema_aktuell); bool crossover_bearish = (last_close >= last_ema) && (aktueller_close < ema_aktuell); //--- Neues Crossover-Ereignis erkannt (New crossover event detected) if(crossover_bullish || crossover_bearish) { trades_in_current_crossover = 0; // Reset trade counter Print("TRACE: EMA Crossover erkannt - ", (crossover_bullish ? "BULLISH" : "BEARISH"), " - Trade-Counter zurückgesetzt"); Print("TRACE: Vorher: Close=", last_close, " EMA=", last_ema, " Jetzt: Close=", aktueller_close, " EMA=", ema_aktuell); } } //--- Aktuelle Werte für nächsten Vergleich speichern (Save current values for next comparison) last_close = aktueller_close; last_ema = ema_aktuell; //--- Preisbewegung zur EMA prüfen (Check price action to EMA) double preis_abstand = MathAbs(aktueller_close - ema_aktuell) / _Point / pips_multiplier; Print("TRACE: Preis-Abstand: ", preis_abstand, " Pips (Schwelle: ", PreisSchwelle, ")"); Print("TRACE: Close: ", aktueller_close, " EMA: ", ema_aktuell); Print("TRACE: Trades im aktuellen Crossover: ", trades_in_current_crossover, "/", MaxTradesPerCrossover); if(preis_abstand > PreisSchwelle && !preis_trigger_aktiv) { preis_trigger_aktiv = true; Print("TRACE: Preis-Trigger aktiviert: ", preis_abstand, " Pips"); } //--- EMA Steigung prüfen (Check EMA slope) double steigung = (ema_aktuell - ema_vorher) / _Point / pips_multiplier; Print("TRACE: EMA Steigung: ", steigung, " Pips (Schwelle: ", SteigungSchwelle, ")"); if(MathAbs(steigung) > SteigungSchwelle && !steigung_trigger_aktiv) { steigung_trigger_aktiv = true; Print("TRACE: Steigungs-Trigger aktiviert: ", steigung, " Pips"); } //--- Überwachung starten wenn beide Trigger aktiv sind (Start monitoring when both triggers are active) if(preis_trigger_aktiv && steigung_trigger_aktiv && !überwachung_aktiv) { überwachung_aktiv = true; trigger_price = aktueller_close; // Preis beim Trigger speichern für Pullback-Prüfung if(UseBarData) { letzte_überwachung_zeit = iTime(_Symbol, Timeframe, 0); // Aktuelle Bar-Zeit Print("TRACE: Überwachung gestartet - Beide Trigger aktiv (Bar: ", TimeToString(letzte_überwachung_zeit), ")"); } else { letzte_überwachung_zeit = TimeCurrent(); // Aktuelle Tick-Zeit Print("TRACE: Überwachung gestartet - Beide Trigger aktiv (Tick)"); } } //--- Trade platzieren wenn Überwachung aktiv und Preis über/unter EMA (Place trade when monitoring active and price above/below EMA) if(überwachung_aktiv) { bool bullish_signal = aktueller_close > ema_aktuell; bool bearish_signal = aktueller_close < ema_aktuell; Print("TRACE: Signal Check - Bullish: ", bullish_signal, " Bearish: ", bearish_signal); Print("TRACE: Close: ", aktueller_close, " EMA: ", ema_aktuell); Print("TRACE: Differenz: ", aktueller_close - ema_aktuell); //--- Trade-Limit prüfen (Check trade limit) if(trades_in_current_crossover >= MaxTradesPerCrossover) { Print("TRACE: Trade-Limit erreicht (", MaxTradesPerCrossover, ") - Kein neuer Trade"); return; } //--- Neue Strategie: V-Shape Reversal Trading + RSI 50 Crossover für Haupt-Trades if(!PositionSelect(_Symbol)) { //--- 1. Prüfe auf V-Shape Reversal Pattern (Check for V-Shape Reversal Pattern) if(UseVShapeReversalTrading) { ENUM_ORDER_TYPE vshape_direction = PrüfeVShapePattern(aktueller_close, ema_aktuell); if(vshape_direction == ORDER_TYPE_BUY) { // V-Shape erkannt: Preis war hoch, jetzt fallend -> REVERSE TRADE (SELL) Print("TRACE: V-SHAPE REVERSAL erkannt - REVERSE TRADE: VERKAUF"); if(PlatziereVShapeTrade(ORDER_TYPE_SELL, aktueller_close, ema_aktuell)) { trades_in_current_crossover++; entry_price = aktueller_close; max_favorable_excursion = 0; max_adverse_excursion = 0; is_vshape_trade = true; } return; // V-Shape Trade platziert, keine weiteren Trades } else if(vshape_direction == ORDER_TYPE_SELL) { // V-Shape erkannt: Preis war niedrig, jetzt steigend -> REVERSE TRADE (BUY) Print("TRACE: V-SHAPE REVERSAL erkannt - REVERSE TRADE: KAUF"); if(PlatziereVShapeTrade(ORDER_TYPE_BUY, aktueller_close, ema_aktuell)) { trades_in_current_crossover++; entry_price = aktueller_close; max_favorable_excursion = 0; max_adverse_excursion = 0; is_vshape_trade = true; } return; // V-Shape Trade platziert, keine weiteren Trades } } //--- 2. Haupt-Trend Trade: Warte auf RSI 50 Crossover (Main Trend Trade: Wait for RSI 50 Crossover) if(bullish_signal) { // Prüfe RSI 50 Crossover für KAUF (Check RSI 50 crossover for BUY) bool rsi_ready = true; if(UseRSI50Crossover) { rsi_ready = rsi_crossed_above_50 && (ArraySize(rsi_array) > 0 && rsi_array[0] > 50.0); if(!rsi_ready) { Print("TRACE: KAUF-Signal wartet auf RSI 50 Crossover - RSI: ", (ArraySize(rsi_array) > 0 ? rsi_array[0] : 0)); } } if(rsi_ready) { Print("TRACE: Versuche KAUF-Trade zu platzieren (Trade #", trades_in_current_crossover + 1, ")"); if(PlatziereTrade(ORDER_TYPE_BUY)) { trades_in_current_crossover++; entry_price = aktueller_close; max_favorable_excursion = 0; max_adverse_excursion = 0; is_vshape_trade = false; rsi_crossed_above_50 = false; // Reset nach Trade } } } else if(bearish_signal) { // Prüfe RSI 50 Crossover für VERKAUF (Check RSI 50 crossover for SELL) bool rsi_ready = true; if(UseRSI50Crossover) { rsi_ready = rsi_crossed_below_50 && (ArraySize(rsi_array) > 0 && rsi_array[0] < 50.0); if(!rsi_ready) { Print("TRACE: VERKAUF-Signal wartet auf RSI 50 Crossover - RSI: ", (ArraySize(rsi_array) > 0 ? rsi_array[0] : 0)); } } if(rsi_ready) { Print("TRACE: Versuche VERKAUF-Trade zu platzieren (Trade #", trades_in_current_crossover + 1, ")"); if(PlatziereTrade(ORDER_TYPE_SELL)) { trades_in_current_crossover++; entry_price = aktueller_close; max_favorable_excursion = 0; max_adverse_excursion = 0; is_vshape_trade = false; rsi_crossed_below_50 = false; // Reset nach Trade } } } } else if(PositionSelect(_Symbol)) { Print("TRACE: Position bereits offen - kein neuer Trade"); } } } //+------------------------------------------------------------------+ //| V-Shape Pattern Detection | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE PrüfeVShapePattern(double aktueller_preis, double ema_aktuell) { if(!UseVShapeReversalTrading || ArraySize(rsi_array) < 3) return WRONG_VALUE; double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; double current_rsi = rsi_array[0]; double previous_rsi = rsi_array[1]; double rsi_before = rsi_array[2]; //--- Hole Preis-Historie für V-Shape Erkennung (Get price history for V-Shape detection) double close_0 = iClose(_Symbol, Timeframe, 0); double close_1 = iClose(_Symbol, Timeframe, 1); double close_2 = iClose(_Symbol, Timeframe, 2); double close_3 = iClose(_Symbol, Timeframe, 3); if(close_1 == 0 || close_2 == 0 || close_3 == 0) return WRONG_VALUE; //--- V-Shape Top Pattern: Preis war hoch (RSI überkauft), jetzt fallend (V-Shape Top Pattern) // Pattern: Preis steigt -> erreicht Hoch -> fällt (RSI: hoch -> fällt) bool vshape_top = false; if(current_rsi < previous_rsi && previous_rsi > RSIOverbought) { // RSI war überkauft und fällt jetzt if(close_0 < close_1 && close_1 < close_2) { // Preis fällt kontinuierlich double price_drop = (close_2 - close_0) / _Point / pips_multiplier; if(price_drop > 100.0) // Mindest-Fall von 100 Pips { vshape_top = true; Print("TRACE: V-SHAPE TOP erkannt - RSI fällt von ", previous_rsi, " zu ", current_rsi); Print("TRACE: Preis fällt von ", close_2, " zu ", close_0, " (", price_drop, " Pips)"); } } } //--- V-Shape Bottom Pattern: Preis war niedrig (RSI überverkauft), jetzt steigend (V-Shape Bottom Pattern) // Pattern: Preis fällt -> erreicht Tief -> steigt (RSI: niedrig -> steigt) bool vshape_bottom = false; if(current_rsi > previous_rsi && previous_rsi < RSIOversold) { // RSI war überverkauft und steigt jetzt if(close_0 > close_1 && close_1 > close_2) { // Preis steigt kontinuierlich double price_rise = (close_0 - close_2) / _Point / pips_multiplier; if(price_rise > 100.0) // Mindest-Anstieg von 100 Pips { vshape_bottom = true; Print("TRACE: V-SHAPE BOTTOM erkannt - RSI steigt von ", previous_rsi, " zu ", current_rsi); Print("TRACE: Preis steigt von ", close_2, " zu ", close_0, " (", price_rise, " Pips)"); } } } if(vshape_top) return ORDER_TYPE_SELL; // Reverse Trade: Verkauf bei V-Shape Top else if(vshape_bottom) return ORDER_TYPE_BUY; // Reverse Trade: Kauf bei V-Shape Bottom return WRONG_VALUE; // Kein V-Shape erkannt } //+------------------------------------------------------------------+ //| V-Shape Reversal Trade platzieren (Place V-Shape Reversal Trade)| //+------------------------------------------------------------------+ bool PlatziereVShapeTrade(ENUM_ORDER_TYPE order_type, double aktueller_preis, double ema_aktuell) { double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; double stop_loss_pips = VShapeReversalStopLoss; double stop_loss_price = 0; Print("TRACE: Versuche V-SHAPE REVERSAL Trade zu platzieren - Typ: ", (order_type == ORDER_TYPE_BUY) ? "KAUF" : "VERKAUF"); Print("TRACE: Lot: ", VShapeReversalLotSize, " Stop Loss: ", stop_loss_pips, " Pips"); //--- Berechne Stop Loss (Calculate Stop Loss) if(order_type == ORDER_TYPE_BUY) { stop_loss_price = aktueller_preis - (stop_loss_pips * _Point * pips_multiplier); } else { stop_loss_price = aktueller_preis + (stop_loss_pips * _Point * pips_multiplier); } bool success = false; if(order_type == ORDER_TYPE_BUY) { success = trade.Buy(VShapeReversalLotSize, _Symbol, 0, stop_loss_price, 0, "V-Shape Reversal Trade"); } else { success = trade.Sell(VShapeReversalLotSize, _Symbol, 0, stop_loss_price, 0, "V-Shape Reversal Trade"); } if(success) { ticket = (int)trade.ResultOrder(); Print("TRACE: V-SHAPE Trade erfolgreich platziert: ", (order_type == ORDER_TYPE_BUY) ? "KAUF" : "VERKAUF", " Ticket: ", ticket); Print("TRACE: Stop Loss: ", stop_loss_price); //--- Trade-Öffnungszeit speichern (Save trade opening time) trade_open_time = iTime(_Symbol, Timeframe, 0); Print("TRACE: Trade-Öffnungszeit: ", TimeToString(trade_open_time)); //--- Überwachung zurücksetzen (Reset monitoring) überwachung_aktiv = false; preis_trigger_aktiv = false; steigung_trigger_aktiv = false; return true; } else { Print("TRACE: Fehler beim Platzieren des V-SHAPE Trades - Retcode: ", trade.ResultRetcode()); Print("TRACE: Fehlerbeschreibung: ", trade.ResultRetcodeDescription()); return false; } } //+------------------------------------------------------------------+ //| Trade platzieren (Place trade) | //+------------------------------------------------------------------+ bool PlatziereTrade(ENUM_ORDER_TYPE order_type) { Print("TRACE: Versuche Trade zu platzieren - Typ: ", (order_type == ORDER_TYPE_BUY) ? "KAUF" : "VERKAUF"); Print("TRACE: Lot: ", LotGröße); bool success = false; if(order_type == ORDER_TYPE_BUY) { success = trade.Buy(LotGröße, _Symbol, 0, 0, 0, "EMA Crossover Trade"); } else { success = trade.Sell(LotGröße, _Symbol, 0, 0, 0, "EMA Crossover Trade"); } if(success) { ticket = (int)trade.ResultOrder(); Print("TRACE: Trade erfolgreich platziert: ", (order_type == ORDER_TYPE_BUY) ? "KAUF" : "VERKAUF", " Ticket: ", ticket); //--- Trade-Öffnungszeit speichern (Save trade opening time) trade_open_time = iTime(_Symbol, Timeframe, 0); Print("TRACE: Trade-Öffnungszeit: ", TimeToString(trade_open_time)); //--- Überwachung zurücksetzen (Reset monitoring) überwachung_aktiv = false; preis_trigger_aktiv = false; steigung_trigger_aktiv = false; return true; } else { Print("TRACE: Fehler beim Platzieren des Trades - Retcode: ", trade.ResultRetcode()); Print("TRACE: Fehlerbeschreibung: ", trade.ResultRetcodeDescription()); return false; } } //+------------------------------------------------------------------+ //| Trades verwalten (Manage trades) | //+------------------------------------------------------------------+ void VerwalteTrades() { if(!PositionSelect(_Symbol)) return; double position_profit = PositionGetDouble(POSITION_PROFIT); double position_open_price = PositionGetDouble(POSITION_PRICE_OPEN); double current_price = PositionGetDouble(POSITION_PRICE_CURRENT); ENUM_POSITION_TYPE position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; double trailing_stop_pips = TrailingStop; //--- Für V-Shape Trades: Tighter Trailing Stop (For V-Shape trades: Tighter trailing stop) if(is_vshape_trade) { trailing_stop_pips = VShapeReversalStopLoss * 0.5; // 50% des Stop Loss als Trailing Print("TRACE: V-Shape Trade - Verwendeter Trailing Stop: ", trailing_stop_pips, " Pips"); } //--- Gleitender Stop (Trailing Stop) - nur wenn Position im Profit ist if(position_profit > 0) // Only apply trailing stop when in profit { if(position_type == POSITION_TYPE_BUY) { double new_stop_loss = current_price - (trailing_stop_pips * _Point * pips_multiplier); double current_stop_loss = PositionGetDouble(POSITION_SL); // Only move stop loss if new stop is higher than current stop if(new_stop_loss > current_stop_loss) { ÄndereStopLoss(new_stop_loss); } } else if(position_type == POSITION_TYPE_SELL) { double new_stop_loss = current_price + (trailing_stop_pips * _Point * pips_multiplier); double current_stop_loss = PositionGetDouble(POSITION_SL); // Only move stop loss if new stop is lower than current stop if(new_stop_loss < current_stop_loss || current_stop_loss == 0) { ÄndereStopLoss(new_stop_loss); } } } //--- Ausstieg bei Preis unter/über EMA (Exit when price below/above EMA) if(ArraySize(ema_array) >= 1) { double aktueller_close = iClose(_Symbol, Timeframe, 0); double ema_aktuell = ema_array[0]; bool exit_bullish = (position_type == POSITION_TYPE_SELL && aktueller_close > ema_aktuell); bool exit_bearish = (position_type == POSITION_TYPE_BUY && aktueller_close < ema_aktuell); if(exit_bullish || exit_bearish) { Print("TRACE: Ausstiegssignal - Close: ", aktueller_close, " EMA: ", ema_aktuell); SchließePosition("EMA Crossover Exit"); Print("TRACE: Position geschlossen - Trade-Counter bleibt bei ", trades_in_current_crossover); } } //--- Profit-Prüfung nach X Bars (Profit check after X bars) if(CloseUnprofitableTrades && trade_open_time != 0 && PositionSelect(_Symbol)) { Print("TRACE: Profit-Prüfung aktiviert - CloseUnprofitableTrades: ", CloseUnprofitableTrades); PrüfeProfitNachBars(); } else if(!CloseUnprofitableTrades) { Print("TRACE: Profit-Prüfung deaktiviert - CloseUnprofitableTrades: ", CloseUnprofitableTrades); } } //+------------------------------------------------------------------+ //| Profit-Prüfung nach X Bars (Profit check after X bars) | //+------------------------------------------------------------------+ void PrüfeProfitNachBars() { if(!PositionSelect(_Symbol)) { return; // Keine Position offen } datetime current_bar_time = iTime(_Symbol, Timeframe, 0); int bars_since_trade_open = iBarShift(_Symbol, Timeframe, trade_open_time); Print("TRACE: Bars seit Trade-Öffnung: ", bars_since_trade_open, "/", ProfitCheckBars); //--- Prüfe ob genügend Bars vergangen sind (Check if enough bars have passed) if(bars_since_trade_open >= ProfitCheckBars) { double position_profit = PositionGetDouble(POSITION_PROFIT); double position_volume = PositionGetDouble(POSITION_VOLUME); ENUM_POSITION_TYPE position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); Print("TRACE: Profit-Prüfung nach ", ProfitCheckBars, " Bars"); Print("TRACE: Position Profit: ", position_profit, " USD"); //--- Schließe Position wenn nicht im Profit (Close position if not in profit) if(position_profit <= 0) { Print("TRACE: Position nicht im Profit - Schließe Position"); SchließePosition("Profit Check - Unprofitable"); //--- Trade-Öffnungszeit zurücksetzen (Reset trade opening time) trade_open_time = 0; Print("TRACE: Trade-Öffnungszeit zurückgesetzt"); } else { Print("TRACE: Position im Profit - Behalte Position"); //--- Trade-Öffnungszeit zurücksetzen um weitere Prüfungen zu vermeiden (Reset to avoid further checks) trade_open_time = 0; } } } //+------------------------------------------------------------------+ //| Stop Loss ändern (Modify Stop Loss) | //+------------------------------------------------------------------+ void ÄndereStopLoss(double new_stop_loss) { Print("TRACE: Versuche Stop Loss zu ändern auf: ", new_stop_loss); bool success = trade.PositionModify(_Symbol, new_stop_loss, PositionGetDouble(POSITION_TP)); if(success) { Print("TRACE: Stop Loss erfolgreich geändert auf: ", new_stop_loss); } else { Print("TRACE: Fehler beim Ändern des Stop Loss - Retcode: ", trade.ResultRetcode()); Print("TRACE: Fehlerbeschreibung: ", trade.ResultRetcodeDescription()); } } //+------------------------------------------------------------------+ //| Position schließen (Close position) | //+------------------------------------------------------------------+ void SchließePosition(string reason = "Unbekannt") { Print("TRACE: Versuche Position zu schließen - Grund: ", reason); bool success = trade.PositionClose(_Symbol); if(success) { Print("TRACE: Position erfolgreich geschlossen - Grund: ", reason); //--- Reset MAE tracking (Reset MAE tracking) entry_price = 0; max_favorable_excursion = 0; max_adverse_excursion = 0; is_vshape_trade = false; } else { Print("TRACE: Fehler beim Schließen der Position - Retcode: ", trade.ResultRetcode()); Print("TRACE: Fehlerbeschreibung: ", trade.ResultRetcodeDescription()); } } //+------------------------------------------------------------------+ //| V-Shape Reversal Protection Check | //+------------------------------------------------------------------+ bool PrüfeVShapeSchutz(ENUM_ORDER_TYPE order_type, double aktueller_preis, double ema_aktuell) { double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; //--- 1. RSI Filter: Vermeide Einstieg bei extremen RSI-Werten (RSI Filter: Avoid entry at extreme RSI values) if(UseRSIFilter) { if(ArraySize(rsi_array) < 1) { Print("TRACE: RSI Array zu klein für Filter"); return false; } double current_rsi = rsi_array[0]; if(order_type == ORDER_TYPE_BUY) { // Vermeide Einstieg wenn RSI überkauft (Avoid entry when RSI overbought) if(current_rsi > RSIOverbought) { Print("TRACE: RSI Filter blockiert KAUF - RSI: ", current_rsi, " > ", RSIOverbought); return false; } } else if(order_type == ORDER_TYPE_SELL) { // Vermeide Einstieg wenn RSI überverkauft (Avoid entry when RSI oversold) if(current_rsi < RSIOversold) { Print("TRACE: RSI Filter blockiert VERKAUF - RSI: ", current_rsi, " < ", RSIOversold); return false; } } Print("TRACE: RSI Filter bestanden - RSI: ", current_rsi); } //--- 2. Momentum Confirmation: Prüfe ob Momentum in Richtung des Trades zeigt (Momentum Confirmation) if(UseMomentumConfirmation) { if(!PrüfeMomentum(order_type)) { Print("TRACE: Momentum-Bestätigung fehlgeschlagen"); return false; } Print("TRACE: Momentum-Bestätigung erfolgreich"); } //--- 3. Pullback Confirmation: Warte auf Pullback statt Einstieg am Extrem (Pullback Confirmation) if(UsePullbackConfirmation && trigger_price != 0) { double price_movement = MathAbs(aktueller_preis - trigger_price) / _Point / pips_multiplier; double distance_to_ema = MathAbs(aktueller_preis - ema_aktuell) / _Point / pips_multiplier; double initial_distance = MathAbs(trigger_price - ema_aktuell) / _Point / pips_multiplier; if(initial_distance > 0) { double pullback_ratio = distance_to_ema / initial_distance; // Erlaube Einstieg nur wenn Preis zurück zur EMA gezogen ist (Allow entry only if price pulled back toward EMA) if(pullback_ratio > (1.0 - PullbackThreshold)) { Print("TRACE: Pullback-Bestätigung fehlgeschlagen - Ratio: ", pullback_ratio, " (benötigt < ", (1.0 - PullbackThreshold), ")"); return false; } Print("TRACE: Pullback-Bestätigung erfolgreich - Ratio: ", pullback_ratio); } } return true; } //+------------------------------------------------------------------+ //| Momentum Confirmation Check | //+------------------------------------------------------------------+ bool PrüfeMomentum(ENUM_ORDER_TYPE order_type) { if(MomentumBars < 1) return true; //--- Prüfe ob die letzten Bars Momentum in Richtung des Trades zeigen (Check if recent bars show momentum in trade direction) double close_0 = iClose(_Symbol, Timeframe, 0); double close_n = iClose(_Symbol, Timeframe, MomentumBars); if(close_n == 0) return true; // Nicht genug Daten (Not enough data) if(order_type == ORDER_TYPE_BUY) { // Für KAUF: Preis sollte höher sein als vor N Bars (For BUY: Price should be higher than N bars ago) if(close_0 <= close_n) { Print("TRACE: Momentum fehlt für KAUF - Close[0]: ", close_0, " Close[", MomentumBars, "]: ", close_n); return false; } } else if(order_type == ORDER_TYPE_SELL) { // Für VERKAUF: Preis sollte niedriger sein als vor N Bars (For SELL: Price should be lower than N bars ago) if(close_0 >= close_n) { Print("TRACE: Momentum fehlt für VERKAUF - Close[0]: ", close_0, " Close[", MomentumBars, "]: ", close_n); return false; } } return true; } //+------------------------------------------------------------------+ //| Maximum Adverse Excursion Check | //+------------------------------------------------------------------+ void PrüfeMAE() { if(!PositionSelect(_Symbol) || entry_price == 0) return; double current_price = PositionGetDouble(POSITION_PRICE_CURRENT); ENUM_POSITION_TYPE position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; double current_excursion = 0; if(position_type == POSITION_TYPE_BUY) { current_excursion = (current_price - entry_price) / _Point / pips_multiplier; } else if(position_type == POSITION_TYPE_SELL) { current_excursion = (entry_price - current_price) / _Point / pips_multiplier; } //--- Update maximale Bewegungen (Update maximum movements) if(current_excursion > max_favorable_excursion) { max_favorable_excursion = current_excursion; } if(current_excursion < -max_adverse_excursion) { max_adverse_excursion = -current_excursion; } //--- Prüfe ob MAE-Schwelle überschritten wurde (Check if MAE threshold exceeded) if(max_adverse_excursion > MAEThreshold) { // Prüfe ob genug Bars vergangen sind (Check if enough bars have passed) datetime current_bar_time = iTime(_Symbol, Timeframe, 0); int bars_since_entry = iBarShift(_Symbol, Timeframe, trade_open_time); if(bars_since_entry >= MAECheckBars) { double position_profit = PositionGetDouble(POSITION_PROFIT); // Schließe nur wenn Position nicht im Profit ist (Close only if position not in profit) if(position_profit <= 0) { Print("TRACE: MAE-Schwelle überschritten - MAE: ", max_adverse_excursion, " Pips (Schwelle: ", MAEThreshold, ")"); Print("TRACE: Position Profit: ", position_profit, " - Schließe Position"); SchließePosition("MAE Protection - Excessive Adverse Excursion"); } else { Print("TRACE: MAE-Schwelle überschritten aber Position im Profit - MAE: ", max_adverse_excursion, " Profit: ", position_profit); } } } } //+------------------------------------------------------------------+ //| Early Reversal Detection | //+------------------------------------------------------------------+ bool PrüfeFrüheReversal(ENUM_POSITION_TYPE position_type, double aktueller_preis, double ema_aktuell) { if(!UseEarlyReversalDetection || entry_price == 0) return false; double pips_multiplier = (_Digits == 3 || _Digits == 5) ? 10.0 : 1.0; double price_to_ema = MathAbs(aktueller_preis - ema_aktuell) / _Point / pips_multiplier; double entry_to_ema = MathAbs(entry_price - ema_aktuell) / _Point / pips_multiplier; if(entry_to_ema == 0) return false; //--- Prüfe ob Preis sich zu weit zurück zur EMA bewegt hat (Check if price moved too far back toward EMA) double reversal_ratio = price_to_ema / entry_to_ema; if(reversal_ratio < ReversalThreshold) { // Preis hat sich mehr als X% zurück zur EMA bewegt - mögliche Reversal (Price moved more than X% back toward EMA - possible reversal) Print("TRACE: Frühe Reversal erkannt - Ratio: ", reversal_ratio, " (Schwelle: ", ReversalThreshold, ")"); // Prüfe ob Position im Verlust ist (Check if position is in loss) if(PositionSelect(_Symbol)) { double position_profit = PositionGetDouble(POSITION_PROFIT); if(position_profit <= 0) { Print("TRACE: Reversal erkannt und Position im Verlust - Schließe Position"); return true; } } } return false; } //+------------------------------------------------------------------+