Verstärkte Gewinnarchitektur: Mehrschichtiger Kontoschutz
Inhaltsverzeichnis
- Einführung
- Überblick und Verständnis des Systems
- Die ersten Schritte
- Backtest-Ergebnisse
- Schlussfolgerung
Einführung
Im modernen algorithmischen Handel geht das Streben nach hohen Renditen unweigerlich mit einem erhöhten Risiko der Marktvolatilität, der Ausführungsunsicherheit und der systemischen Risiken einher, die das Kapital schnell aufzehren können. Um in einem solchen Umfeld erfolgreich zu sein, muss ein EA nicht nur gewinnbringende Gelegenheiten erkennen, sondern auch auf intelligente Weise regulieren, wie viel Risiko er in jedem Moment aufnimmt. An dieser Stelle wird der mehrschichtige Schutz von Konten unverzichtbar – ein architektonischer Ansatz, der adaptive Losgrößenbestimmung, volatilitätssensitives Engagement und Echtzeit-Performance-Überwachung in ein einheitliches Verteidigungskonzept einbindet. Anstatt sich auf eine einzige Absicherung zu verlassen, setzt das System auf mehrere koordinierte Ebenen, die sich dynamisch mit den Marktbedingungen entwickeln.
Indem wir den Schutz direkt in die Handelslogik einbauen – strukturell, verhaltensmäßig und systemisch –, ermöglichen wir dem EA, wachstumsstarke Strategien zu verfolgen und gleichzeitig eine disziplinierte Risikoposition beizubehalten. Er lernt, wann er sein Engagement ausweiten, wann sie es zurückfahren und wann sie es ganz einstellen muss, um ihr Kapital zu erhalten. Durch Mindestkapitalanforderungen, Auslöseschwellen, segmentierte Ausführungslogik, Handelsunterbrechungen und Erholungsprotokolle verhält sich das Handelssystem eher wie ein sich selbst regulierender Organismus als wie ein statisches Regelwerk. Das Ergebnis ist eine intelligente, widerstandsfähige Handelsarchitektur, die in der Lage ist, Chancen zu nutzen und gleichzeitig Bedrohungen in Echtzeit aktiv zu verwalten und zu neutralisieren.
Überblick und Verständnis des Systems
Der Expert Advisor wurde als hochentwickeltes automatisiertes Handelssystem für Gold (XAUUSD) konzipiert, das eine Martingale-Erholungsstrategie mit einem robusten, mehrschichtigen Kontoschutz kombiniert. Im Kern handelt es sich um einen risikogeführten Zyklus: Er identifiziert neue Trends anhand des Kreuzens der EMAs und platziert ein erstes Handelsgeschäft. Wenn dieser Handel verliert, tritt er in eine „Erholungsphase“ ein, in der er die Losgröße entsprechend der gewählten Martingal-Formel erhöht, um die Verluste auszugleichen, und diesen Prozess für eine begrenzte Anzahl von Schritten fortsetzt. Wenn ein Handel gewinnt, wird die Reihenfolge zurückgesetzt. Dieses Kernstück ist in ein umfassendes Sicherheitssystem eingebettet, das die katastrophalen Verluste verhindern soll, die normalerweise mit Martingale-Systemen verbunden sind. Zu den wichtigsten Schutzmechanismen gehören dynamische Kapital-Stopps, tägliche Verlustlimits, Handelsdrosselung und eine Unterbrechungsfunktion, die den gesamten Handel nach einer bestimmten Anzahl aufeinanderfolgender Verluste oder einem bestimmten Schwellenwert für den Drawdown stoppt.
Die Schutzlogik des EA funktioniert wie eine Reihe von Schutzschilden und Warndrähten, die Ihr Kapital bewachen. Stellen Sie sich das System wie ein hierarchisches Verteidigungssystem vor: Zunächst werden die einzelnen Handelsgeschäfte durch Slippage-Checks und volatilitätsangepasste Stop-Losses geschützt. Außerdem wird das Konto durch Echtzeit-Überwachungssysteme geschützt, die Ihr gesamtes Kapital überwachen. Wenn Ihr Drawdown gegenüber dem Höchstwert des Kontos einen bestimmten Prozentsatz übersteigt, kann das System den Handel vollständig unterbrechen. Zu den weiteren Schichten gehören die Begrenzung der Anzahl von Handelsgeschäften innerhalb eines Zeitfensters, um eine Überspekulation zu verhindern, und ein Erholungsprotokoll, das nach einer schweren Verlustsequenz das Risiko automatisch reduziert und eine Wartezeit oder eine Erholung des Kapitals vor der Wiederaufnahme des Handelsgeschäfts verlangt. Diese Struktur stellt sicher, dass der aggressive Martingale-Erholungsmechanismus stets durch vordefinierte, rationale Grenzen eingeschränkt wird, die der Kapitalerhaltung Vorrang einräumen.
Schließlich verwendet das System eine dauerhafte Zustandsverwaltung, um seine Verteidigungslogik über Marktsitzungen und Plattform-Neustarts hinweg beizubehalten. Anhand globaler Variablen erinnert es sich an seinen Höchstwert, an aufeinanderfolgende Verluste und daran, ob es sich in einer Erholungspause befindet. So kann der EA seine Regeln konsequent durchsetzen, nicht nur innerhalb eines einzelnen Laufs. Wenn er zum Beispiel an einem Freitag auf einen Unterbrecher trifft und pausiert, bleibt er auch am Montag pausiert und verhindert den sofortigen Wiedereintritt in riskante Bedingungen. Dieses Design verwandelt den EA von einem einfachen automatisierten Skript in ein widerstandsfähiges, zustandsfähiges Handelssystem, das methodisch nach Gewinn strebt und gleichzeitig grundlegend darauf ausgelegt ist, ungünstige Marktbedingungen zu überstehen und primär das Handelskonto zu schützen.

Die ersten Schritte
//+------------------------------------------------------------------+ //| GALEIT.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" //--- Include Libraries #include <Trade/Trade.mqh> //--- Global Variables CTrade trade; ulong lastTicket = 0; int martingaleStep = 0; double dailyProfit = 0.0; datetime lastTradeTime = 0; string tradeSequenceId = ""; //--- Global Variable Names #define GV_PEAK_EQUITY "GV_PeakEquity" #define GV_PAUSE_EA "GV_EA_Paused" #define GV_DD_LOCK_LEVEL "GV_DrawdownLockLevel" #define GV_CONSEC_LOSSES "GV_ConsecLosses" #define GV_TRADE_WINDOW_START "GV_TradeWindowStart" #define GV_TRADES_IN_WINDOW "GV_TradesInWindow" //--- Input Parameters input group "Trading Strategy" input int FastMAPeriod = 10; input int SlowMAPeriod = 50; input group "Martingale & Money Management" input double InitialLotSize = 0.01; input double LotMultiplier = 2.0; input int MaxMartingaleSteps = 5; input double RiskPercent = 2.0; input group "Volatility Management (ATR)" input int ATR_Period = 14; input double ATR_SL_Factor = 1.5; input double ATR_TP_Factor = 1.0; input group "Account Protection" input bool UseEquityStop = true; input double EquityStopPercent = 8.0; input bool UseDailyLossLimit = true; input double DailyLossPercent = 5.0; input bool UseMaxSpreadFilter = true; input int MaxSpreadPoints = 5; input group "Trailing Stop Parameters" input bool UseTrailingStop = true; input int BreakEvenAtPips = 500; input int TrailStartAtPips = 600; input int TrailStepPips = 100; input group "Circuit Breaker Settings" input int MaxConsecutiveLosses = 3; input double CircuitBreakerDD = 15.0; input group "Throttle Settings" input int MaxTradesPerHour = 10; input int ThrottleWindowSeconds = 3600; input group "Recovery Settings" input double RecoveryRiskReduction = 0.5; input double ResumeEquityPercent = 90.0; input int ResumeAfterSeconds = 86400;
Wir beginnen mit der Definition der wichtigsten globalen Variablen, auf die sich der EA stützen wird, um seinen internen Zustand und sein Handelsverhalten zu verfolgen. Dazu gehören Objekte wie die CTrade-Instanz für die Auftragsausführung, Variablen für die Speicherung des letzten Handelstickets, der Martingal-Progression und des täglichen Gewinns sowie Zeitverfolgungs- und Sequenzbezeichner. Unmittelbar danach deklarieren wir eine Reihe von globalen Variablennamen, die mit Hilfe des in MetaTrader integrierten GlobalVariable-Systems gespeichert werden. Diese ermöglichen es dem EA, wichtige risikobezogene Zustände beizubehalten, wie z. B. kapitalbezogene Spitzenwerte, Pausenbedingungen, Drawdown-Stufen, aufeinanderfolgende Verluste und Aktivitäten im Handelsfenster – selbst wenn MetaTrader neu gestartet oder der Chart neu geladen wird.
Im weiteren Verlauf führen wir gruppierte Eingabeparameter ein, die die Haupthandelsstrategie definieren und die Art und Weise, wie das System mit den Marktbedingungen interagiert. Als Nächstes werden Martingale- und Money-Management-Einstellungen wie die anfängliche Losgröße, der Losgrößen-Multiplikator, die maximalen Erholungsschritte und der Prozentsatz des Kapitalrisikos festgelegt. Der Bereich Volatilitätsmanagement beinhaltet ATR-basierte dynamische Stop-Loss- und Take-Profit-Berechnungen, die sicherstellen, dass der Ausstieg aus dem Handel automatisch mit der Marktvolatilität skaliert, anstatt feste Pip-Abstände zu verwenden.
Schließlich definieren wir mehrere Ebenen der Schutzlogik durch zusätzliche Eingangsgruppen. Der Abschnitt „Kontoschutz“ regelt Kapital-Stopps, tägliche Verlustlimits und Spread-Filterung – Instrumente, die den Handel unter gefährlichen oder kostspieligen Marktbedingungen verhindern sollen. Trailing-Stop-Parameter ermöglichen es dem EA, Gewinne dynamisch zu sichern, sobald ein Handel günstig wird. Die Einstellungen des Unterbrechers und der Drosselung setzen systemische Sicherheitsvorkehrungen durch und stoppen oder begrenzen den Handel, wenn die Bedingungen zu riskant werden oder die Handelsfrequenz zu hoch wird. Schließlich wird im Abschnitt „Erholung“ (recovery) dargelegt, wie sich der EA nach einer schützenden Abschaltung verhalten sollte, einschließlich der Frage, wie viel Risiko reduziert werden muss und unter welchen Bedingungen der Handel sicher wieder aufgenommen werden kann. Zusammengenommen bilden diese Einstellungen einen vielschichtigen, anpassungsfähigen und widerstandsfähigen Handelsrahmen.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { Print("GaleIT EA Initialized"); trade.SetExpertMagicNumber(12345); tradeSequenceId = GenerateTradeSequenceId(); // Initialize all protection systems InitAccountShields(); InitFailSafes(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Print("GaleIT EA Deinitialized - Reason: ", reason); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Update protection systems UpdatePeakEquity(); TryResumeFromRecovery(); // Check if trading is allowed if(!IsTradingAllowed()) return; // Check all safety limits if(!CheckSafetyLimits()) return; // Manage existing positions ManageExistingPositions(); // Check for new trading opportunities if(IsNewBar()) { CheckForNewTrade(); } ManageOpenTrades(); }
Die Initialisierungsphase beginnt in der Funktion OnInit(), in der der EA eine Startmeldung ausgibt, eine eindeutige Magic Number für die Handelsidentifikation festlegt und eine tradeSequenceId generiert, um die aktuelle Handelsreihe zu verfolgen. Dadurch wird sichergestellt, dass alle vom EA platzierten Handelsgeschäfte eindeutig gekennzeichnet und leicht zu verwalten sind. Der EA ruft dann zwei wichtige Initialisierungsfunktionen auf: InitAccountShields() und InitFailSafes(). Diese Funktionen bereiten alle Risikomanagement-Ebenen vor – wie Kapitalsperren, tägliche Verlustverfolgung, Unterbrecher und Erholungszustände –, sodass der EA mit aktivierten und synchronisierten Schutzsystemen in Betrieb geht.
Wenn der EA entfernt oder das Terminal heruntergefahren wird, protokolliert die Funktion OnDeinit() eine Nachricht, die zeigt, dass der EA deinitialisiert wurde, zusammen mit dem von MetaTrader bereitgestellten Code für den Grund. Diese Funktion führt zwar keine umfangreiche Logik aus, sorgt aber für Transparenz und Nachvollziehbarkeit, sodass der Händler oder Entwickler nachvollziehen kann, ob der EA manuell entfernt, neu geladen oder durch ein Systemereignis gestoppt wurde. Eine saubere Deinitialisierung trägt dazu bei, konsistente Zustände globaler Variablen aufrechtzuerhalten, und verringert das Risiko, dass sich veraltete Daten auf zukünftige Sitzungen auswirken.
Das zentrale Handelssystem läuft in OnTick(), das jedes Mal ausgeführt wird, wenn sich der Marktpreis ändert. Die ersten Maßnahmen betreffen die Sicherheit und die Erholung: Der EA aktualisiert den kapitalbezogenen Spitzenwert, um die Drawdown-Bedingungen zu verfolgen, und versucht, den Handel wieder aufzunehmen, wenn er zuvor einen Erholungs- oder Pausenzustand erreicht hat. Bevor der EA Handelsentscheidungen trifft, prüft er mit IsTradingAllowed(), ob der Handel erlaubt ist, und mit CheckSafetyLimits(), ob Sicherheitsgrenzen verletzt wurden. Wenn alles sicher ist, verwaltet der EA offene Positionen, passt Stopps an und bewertet die Handelslogik. Bei jedem neuen Balken wird CheckForNewTrade() aufgerufen, um auf der Grundlage der Strategieregeln nach Gelegenheiten zu suchen. Schließlich stellt ManageOpenTrades() sicher, dass Trailing-Stops, Breakeven-Regeln oder Teilausstiege korrekt ausgeführt werden, indem der gesamte Zyklus der Bewertung und Ausführung bei jedem Tick abgeschlossen wird.
//+------------------------------------------------------------------+ //| Check if trading is allowed | //+------------------------------------------------------------------+ bool IsTradingAllowed() { // Check if EA is paused by protection systems if(IsEAProtectedPaused()) return false; // Check circuit breaker if(CheckCircuitBreaker(MaxConsecutiveLosses, CircuitBreakerDD)) return false; // Check trade throttle if(!ThrottleAllowNewTrade(MaxTradesPerHour, ThrottleWindowSeconds)) return false; // Check spread filter if(UseMaxSpreadFilter) { long spread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD); if(spread > MaxSpreadPoints * 10) return false; } return true; } //+------------------------------------------------------------------+ //| Check safety limits | //+------------------------------------------------------------------+ bool CheckSafetyLimits() { // Equity Stop protection if(UseEquityStop) { double currentEquity = AccountInfoDouble(ACCOUNT_EQUITY); double currentBalance = AccountInfoDouble(ACCOUNT_BALANCE); double equityDropPercent = (1 - (currentEquity / currentBalance)) * 100; if(equityDropPercent >= EquityStopPercent) { Print("Equity stop triggered: ", equityDropPercent, "%"); CloseAllPositions(); ExpertRemove(); return false; } } // Daily loss limit if(UseDailyLossLimit) { double dailyLossLimit = (DailyLossPercent / 100) * AccountInfoDouble(ACCOUNT_BALANCE); if(dailyProfit <= -dailyLossLimit) { Print("Daily loss limit reached: ", dailyProfit); CloseAllPositions(); return false; } } return true; }
Die Funktion IsTradingAllowed() fungiert als erster Wächter des EA und bestimmt, ob es sicher ist, neue Handelsgeschäfte auszuführen. Zunächst wird geprüft, ob der EA durch Schutzmechanismen wie den Recovery-Modus oder Drawdown-Sperren angehalten wurde. Anschließend wird die Unterbrechungsfunktion überprüft, die den Handel nach zu vielen aufeinanderfolgenden Verlusten oder einem übermäßigen Drawdown unterbricht. Die Funktion setzt auch Drosselungsregeln durch, indem sie begrenzt, wie viele Handelsgeschäfte innerhalb eines bestimmten Zeitfensters getätigt werden können. Wenn der Spread-Filter aktiviert ist, wird schließlich überprüft, ob der aktuelle Marktspread den zulässigen Höchstwert nicht überschreitet. Nur wenn jede dieser Prüfungen bestanden wird, gibt der EA die Erlaubnis, mit Handelsbewertungen oder Eingaben fortzufahren.
Die Funktion CheckSafetyLimits() stellt eine zweite Verteidigungsebene dar, indem sie Regeln zum Schutz von Konten durch harte Stopps durchsetzt. Zunächst wird das Stop-Loss-System für das Kapital bewertet – ein Mechanismus, der den prozentualen Rückgang des Saldos zum Kapital berechnet. Wenn dieser Rückgang den konfigurierten Schwellenwert erreicht oder überschreitet, schließt der EA sofort alle offenen Positionen und entfernt sich selbst aus dem Chart, um weiteren Schaden zu verhindern. Als Nächstes prüft die Funktion das tägliche Verlustlimit und stellt sicher, dass der Handel gestoppt wird, sobald das Konto einen vordefinierten maximalen täglichen Drawdown erreicht hat. Wird eine dieser Bedingungen ausgelöst, wird der Handel gestoppt und der EA gibt „false“ zurück, was signalisiert, dass die Sicherheitsgrenzen überschritten wurden. Nur wenn beide Schutzmaßnahmen innerhalb sicherer Grenzen bleiben, erlaubt der EA die Fortsetzung des Handelszyklus.
//+------------------------------------------------------------------+ //| Check for new trade opportunity | //+------------------------------------------------------------------+ void CheckForNewTrade() { if(PositionsTotal() > 0) return; int signal = GetTradingSignal(); if(signal != 0) { double lotSize = CalculateLotSize(); double sl, tp; CalculateSLTP(signal, sl, tp); if(OpenPosition(signal, lotSize, sl, tp)) { lastTradeTime = TimeCurrent(); martingaleStep = 0; tradeSequenceId = GenerateTradeSequenceId(); } } } //+------------------------------------------------------------------+ //| Get trading signal | //+------------------------------------------------------------------+ int GetTradingSignal() { int fastMA = iMA(_Symbol, _Period, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE); int slowMA = iMA(_Symbol, _Period, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE); if(fastMA == INVALID_HANDLE || slowMA == INVALID_HANDLE) return 0; double fastMAValues[], slowMAValues[]; ArraySetAsSeries(fastMAValues, true); ArraySetAsSeries(slowMAValues, true); if(CopyBuffer(fastMA, 0, 0, 3, fastMAValues) < 3) { IndicatorRelease(fastMA); IndicatorRelease(slowMA); return 0; } if(CopyBuffer(slowMA, 0, 0, 3, slowMAValues) < 3) { IndicatorRelease(fastMA); IndicatorRelease(slowMA); return 0; } double currentFast = fastMAValues[0]; double currentSlow = slowMAValues[0]; double prevFast = fastMAValues[1]; double prevSlow = slowMAValues[1]; int signal = 0; if(prevFast <= prevSlow && currentFast > currentSlow) signal = 1; else if(prevFast >= prevSlow && currentFast < currentSlow) signal = -1; IndicatorRelease(fastMA); IndicatorRelease(slowMA); return signal; } //+------------------------------------------------------------------+ //| Calculate lot size | //+------------------------------------------------------------------+ double CalculateLotSize() { if(martingaleStep == 0) { // Use risk-based lot sizing for first trade double atr = GetATR(_Symbol, _Period, ATR_Period); double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double slPrice = currentPrice - (atr * ATR_SL_Factor); return CalculateLotFromRisk(_Symbol, currentPrice, slPrice, RiskPercent); } else { // Martingale recovery trade return NormalizeDouble(InitialLotSize * MathPow(LotMultiplier, martingaleStep), 2); } } //+------------------------------------------------------------------+ //| Calculate Stop Loss and Take Profit | //+------------------------------------------------------------------+ void CalculateSLTP(int signal, double &sl, double &tp) { double atr = GetATR(_Symbol, _Period, ATR_Period); double currentPrice = signal > 0 ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); if(signal > 0) { sl = currentPrice - (atr * ATR_SL_Factor); tp = currentPrice + (atr * ATR_TP_Factor); } else { sl = currentPrice + (atr * ATR_SL_Factor); tp = currentPrice - (atr * ATR_TP_Factor); } // Validate distances double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); double minDist = 100 * point; if(signal > 0) { if(currentPrice - sl < minDist) sl = currentPrice - minDist; if(tp - currentPrice < minDist) tp = currentPrice + minDist; } else { if(sl - currentPrice < minDist) sl = currentPrice + minDist; if(currentPrice - tp < minDist) tp = currentPrice - minDist; } int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); sl = NormalizeDouble(sl, digits); tp = NormalizeDouble(tp, digits); } //+------------------------------------------------------------------+ //| Open position | //+------------------------------------------------------------------+ bool OpenPosition(int signal, double lotSize, double sl, double tp) { double price = (signal > 0) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); ENUM_ORDER_TYPE orderType = (signal > 0) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; // Use protective execution return ExecuteProtectedOrder(_Symbol, orderType, lotSize, price, sl); } //+------------------------------------------------------------------+ //| Manage existing positions | //+------------------------------------------------------------------+ void ManageExistingPositions() { int totalPositions = PositionsTotal(); for(int i = totalPositions - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionGetString(POSITION_COMMENT) == tradeSequenceId) { double currentProfit = PositionGetDouble(POSITION_PROFIT); if(PositionGetInteger(POSITION_TIME_UPDATE) > lastTradeTime) { bool wasProfit = (currentProfit > 0); OnTradeClosed(wasProfit); if(!wasProfit) { martingaleStep++; if(martingaleStep > MaxMartingaleSteps) { Print("Max martingale steps reached. Activating recovery protocol."); double reducedRisk = RiskPercent; RecoveryProtocol(reducedRisk, RecoveryRiskReduction, ResumeEquityPercent, ResumeAfterSeconds); martingaleStep = 0; } } else { martingaleStep = 0; } dailyProfit += currentProfit; lastTradeTime = TimeCurrent(); } } } }
Das Handelssystem prüft zunächst, ob eine neue Position zulässig ist, indem es bestätigt, dass keine bestehenden Positionen offen sind. Wenn das Konto frei ist, fordert das System ein neues Handelssignal an, das durch eine Kreuzung des schnellen und des langsamen EMAs erzeugt wird. Sobald ein gültiges Signal erscheint, berechnet der EA dynamisch die Losgröße unter Verwendung einer ATR-basierten Risikoallokation für den ersten Handel oder eines strukturierten Martingal-Inkrements für Handelsgeschäfte zur Kapitalerholung. Anschließend berechnet es volatilitätsangepasste Stop-Loss- und Take-Profit-Levels auf der Grundlage von ATR-Multiplikatoren und stellt sicher, dass alle vom Broker geforderten Mindestabstände eingehalten werden. Wenn alles validiert ist, wird eine geschützte Ausführungsfunktion verwendet, um den Handel sicher zu platzieren, und die Handelssitzung wird mit Zeitstempeln und einer eindeutigen Sequenz-ID initialisiert.
Das Signal selbst ist von der klassischen Logik des gleitenden Mittelwerts abgeleitet, aber robuster gemacht, indem mehrere Pufferelemente gezogen werden, um ein echtes Kreuzen zu bestätigen, anstatt eine Fluktuation mit nur einem Tick. Die ATR ist von zentraler Bedeutung für die Sizing- und SL/TP-Berechnungen: Für neue Handelsgeschäfte definiert die ATR die risikobasierte Größenbestimmung über den Abstand zum Stop-Loss, und für Positionsausstiege definiert die ATR dynamische Gewinnziele und Verlustschwellen. Die SL/TP-Ausgaben sind auf die Symbolgenauigkeit normalisiert, durch Mindesthandelsabstände begrenzt und unterscheiden sich je nachdem, ob das System eine Kauf- (Aufwärtskreuzen) oder Verkaufsgelegenheit (Abwärtskreuzen) erhält.
Die Funktion ManageOpenTrades() ist für die intelligente Verwaltung offener Handelsgeschäfte und das Lernen aus deren Ergebnissen verantwortlich. Jedes Mal, wenn ein mit der aktuellen Sequenz verbundener Handel aktualisiert wird, wertet das System aus, ob der Handel mit Gewinn oder Verlust abgeschlossen wurde. Gewinnbringende Handelsgeschäfte setzen den Martingalschrittzähler zurück, während Verluste den Schrittzähler erhöhen und zusätzliche Martingaleingänge auslösen können – bis zu einem vordefinierten Limit. Wenn der Schrittzähler sein Maximum erreicht hat, aktiviert der EA ein Erholungsprotokoll, das das Risiko reduziert, den Handel anhält, bis sich das Kapital stabilisiert, und erst wieder aufnimmt, wenn sich die Marktbedingungen verbessern oder eine Abkühlungsphase verstrichen ist. Auf diese Weise entsteht ein sicherheitsbewusster Verstärkungszyklus, der eine kontrollierte Erholung nach Verlustserien anstrebt und gleichzeitig das Konto vor unkontrolliertem Risiko schützt.
double CalculateLotFromRisk(string symbol, double entry_price, double sl_price, double risk_percent) { if(risk_percent <= 0) return(InitialLotSize); double equity = AccountInfoDouble(ACCOUNT_EQUITY); double risk_amount = equity * (risk_percent / 100.0); double point = SymbolInfoDouble(symbol, SYMBOL_POINT); double sl_points = MathMax(1.0, MathAbs(entry_price - sl_price) / point); double tick_value = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); double tick_size = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); if(tick_value <= 0 || tick_size <= 0) return(InitialLotSize); double value_per_point_per_lot = tick_value / (tick_size / point); double risk_per_lot = sl_points * value_per_point_per_lot; if(risk_per_lot <= 0.0) return(InitialLotSize); double volume = risk_amount / risk_per_lot; double step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP); double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); double maxLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); if(step <= 0) step = 0.01; double normalized = MathFloor(volume / step) * step; if(normalized < minLot) normalized = minLot; if(normalized > maxLot) normalized = maxLot; return(NormalizeDouble(normalized, (int)MathMax(0, (int)(-MathLog10(step))))); } //+------------------------------------------------------------------+ //| STRUCTURAL ACCOUNT SHIELDS | //+------------------------------------------------------------------+ void InitAccountShields() { if(!GlobalVariableCheck(GV_PEAK_EQUITY)) GlobalVariableSet(GV_PEAK_EQUITY, AccountInfoDouble(ACCOUNT_EQUITY)); if(!GlobalVariableCheck(GV_PAUSE_EA)) GlobalVariableSet(GV_PAUSE_EA, 0.0); if(!GlobalVariableCheck(GV_DD_LOCK_LEVEL)) GlobalVariableSet(GV_DD_LOCK_LEVEL, 0.0); } void UpdatePeakEquity() { double current = AccountInfoDouble(ACCOUNT_EQUITY); double peak = GlobalVariableGet(GV_PEAK_EQUITY); if(current > peak) GlobalVariableSet(GV_PEAK_EQUITY, current); } double GetCurrentDrawdownPercent() { double peak = GlobalVariableGet(GV_PEAK_EQUITY); double equity = AccountInfoDouble(ACCOUNT_EQUITY); if(peak <= 0) return(0.0); return ((peak - equity) / peak) * 100.0; } bool IsEAProtectedPaused() { return (GlobalVariableGet(GV_PAUSE_EA) != 0.0); } //+------------------------------------------------------------------+ //| TRADE-LEVEL REINFORCEMENT | //+------------------------------------------------------------------+ bool ExecuteProtectedOrder(string symbol, ENUM_ORDER_TYPE type, double volume, double price, double sl_price) { if(IsEAProtectedPaused()) return false; double point = SymbolInfoDouble(symbol, SYMBOL_POINT); double allowableDeviationPoints = 10; if(type == ORDER_TYPE_BUY) { double ask = SymbolInfoDouble(symbol, SYMBOL_ASK); if(MathAbs(ask - price) / point > allowableDeviationPoints) return false; } else { double bid = SymbolInfoDouble(symbol, SYMBOL_BID); if(MathAbs(bid - price) / point > allowableDeviationPoints) return false; } double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); double maxLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); if(volume < minLot || volume > maxLot) return false; bool ok = false; if(type == ORDER_TYPE_BUY) ok = trade.Buy(volume, symbol, price, sl_price, 0, NULL); else if(type == ORDER_TYPE_SELL) ok = trade.Sell(volume, symbol, price, sl_price, 0, NULL); if(!ok) PrintFormat("Order failed: %s (err %d)", symbol, GetLastError()); return ok; } //+------------------------------------------------------------------+ //| SYSTEMIC FAIL-SAFES | //+------------------------------------------------------------------+ void InitFailSafes() { if(!GlobalVariableCheck(GV_CONSEC_LOSSES)) GlobalVariableSet(GV_CONSEC_LOSSES, 0); if(!GlobalVariableCheck(GV_TRADE_WINDOW_START)) GlobalVariableSet(GV_TRADE_WINDOW_START, TimeCurrent()); if(!GlobalVariableCheck(GV_TRADES_IN_WINDOW)) GlobalVariableSet(GV_TRADES_IN_WINDOW, 0); } void OnTradeClosed(bool wasProfit) { if(wasProfit) GlobalVariableSet(GV_CONSEC_LOSSES, 0); else GlobalVariableSet(GV_CONSEC_LOSSES, GlobalVariableGet(GV_CONSEC_LOSSES) + 1); GlobalVariableSet(GV_TRADES_IN_WINDOW, GlobalVariableGet(GV_TRADES_IN_WINDOW) + 1); } bool CheckCircuitBreaker(int maxConsecLosses, double drawdownThresholdPercent) { int consec = (int)GlobalVariableGet(GV_CONSEC_LOSSES); double dd = GetCurrentDrawdownPercent(); if(consec >= maxConsecLosses || dd >= drawdownThresholdPercent) { GlobalVariableSet(GV_PAUSE_EA, 1.0); Print("Circuit breaker engaged: consec=", consec, " dd=", dd); return true; } return false; } bool ThrottleAllowNewTrade(int maxTrades, int windowSeconds) { datetime start = (datetime)GlobalVariableGet(GV_TRADE_WINDOW_START); int count = (int)GlobalVariableGet(GV_TRADES_IN_WINDOW); datetime now = TimeCurrent(); if((now - start) > windowSeconds) { GlobalVariableSet(GV_TRADE_WINDOW_START, now); GlobalVariableSet(GV_TRADES_IN_WINDOW, 0); count = 0; } return (count < maxTrades); } void RecoveryProtocol(double &riskPercent, double reductionFactor, double resumeEquityPercentOfPeak, int resumeAfterSeconds) { riskPercent *= reductionFactor; GlobalVariableSet(GV_PAUSE_EA, 1.0); GlobalVariableSet("GV_RecoveryResumeTime", TimeCurrent() + resumeAfterSeconds); GlobalVariableSet("GV_ResumeEquityPercent", resumeEquityPercentOfPeak); } bool TryResumeFromRecovery() { double resumeTime = GlobalVariableGet("GV_RecoveryResumeTime"); if(resumeTime == 0) return false; if(TimeCurrent() < (datetime)resumeTime) return false; double resumePercent = GlobalVariableGet("GV_ResumeEquityPercent"); if(resumePercent <= 0) { GlobalVariableSet(GV_PAUSE_EA, 0.0); GlobalVariableSet("GV_RecoveryResumeTime", 0); return true; } double peak = GlobalVariableGet(GV_PEAK_EQUITY); double needed = peak * (resumePercent / 100.0); if(AccountInfoDouble(ACCOUNT_EQUITY) >= needed) { GlobalVariableSet(GV_PAUSE_EA, 0.0); GlobalVariableSet("GV_RecoveryResumeTime", 0); return true; } return false; }
Die Funktion CalculateLotFromRisk() stellt den Kern der dynamischen Risikokontrolle der Engine dar, indem sie einen nutzerdefinierten Risikoprozentsatz in eine exakte, volatilitätsabhängige Losgröße umwandelt. Sie berechnet das pro Handel zulässige monetäre Risiko auf der Grundlage des Kontokapitals, des Abstands zwischen Einstieg und Stop-Loss in Punkten und des Geldwerts des Symbols pro Punkt. Dadurch kann der EA die Positionen proportional zur Marktvolatilität und zur Risikotoleranz des Händlers anpassen. Um sicherzustellen, dass alle berechneten Volumina handelbar bleiben, werden Broker-Einschränkungen wie Mindest- und Höchstwerte sowie schrittweise Losgrößen-Inkremente angewendet. Die normalisierte Ausgabe gewährleistet Präzision, Konformität und eine konsistente Risikoallokation, insbesondere in sich schnell verändernden Märkten.
Als Nächstes wird mit dem Block „Structural Account Shields“ ein Schutzrahmen für die Überwachung der Gesundheit des Eigenkapitals und die Absicherung des Kontos gegen tiefe Einbrüche geschaffen. Beim Start zeichnet der EA den Höchststand des Kapitals auf, initialisiert die Schutzvariablen und aktualisiert dann den Höchststand dynamisch, sobald das Kapital einen neuen Höchststand erreicht. Mit diesen Werten misst das System den Drawdown in Echtzeit als Prozentsatz des Spitzenwerts, sodass der EA logische Entscheidungen auf der Grundlage des Kapitalstressniveaus treffen kann. Ein Pausen-Flag ist ebenfalls enthalten, sodass externe Module – wie z. B. Unterbrecher oder Erholungsprotokolle – alle Handelsoperationen vorübergehend einfrieren können, wenn ein Schutzschwellenwert überschritten wird.
Das System der Verstärkung von Handelsniveaus konzentriert sich auf die Validierung und Absicherung jedes Auftrags während der Ausführung. Bevor der EA einen Handel an den Server sendet, stellt er sicher, dass der Schutzmodus nicht aktiv ist, dass der Ausführungskurs nahe genug am aktuellen Geld-/Briefkurs liegt (um Slippage-Fallen zu vermeiden) und dass die Losgröße den Brokerregeln entspricht. Die Orders werden dann über das MQL5-Handelsobjekt mit optionaler SL-Platzierung für zusätzliche Sicherheit eröffnet. Wenn ein Handel fehlschlägt, protokolliert der EA das spezifische Symbol und den Fehlercode, was ein intelligenteres Debugging und adaptive Routinen ermöglicht. Dieses Modell der geschützten Ausführung stellt sicher, dass nur strukturell solide Handelsgeschäfte – mit dem richtigen Preis, der richtigen Größe und der richtigen Zulassung – den Markt erreichen.
Schließlich fungiert das Modul Systemic-Fail-Safes als Notfall-Stabilitätsmodul des EA, das das Handelsverhalten im Laufe der Zeit überwacht, um gefährliche Muster zu erkennen. Es verfolgt die aufeinanderfolgenden Verluste, die Anzahl der Handelsgeschäfte in einem gleitenden Zeitfenster und den aktuellen Drawdown. Unterbrechers lassen den Handel ruhen, wenn Verlustserien oder Drawdown-Schwellenwerte überschritten werden, um destruktive Spiralen zu verhindern. Die Drosselungslogik begrenzt, wie viele Handelsgeschäfte innerhalb eines bestimmten Zeitfensters getätigt werden können, und verhindert so ein Überhandeln in volatilen Phasen. Wenn sich die Bedingungen weiter verschlechtern, reduziert das Erholungsprotokoll das Risiko, unterbricht den Handel für eine Abkühlungsphase und wartet optional darauf, dass sich das Kapital auf einen bestimmten Prozentsatz des Höchststands erholt, bevor es wieder aufgenommen wird. So entsteht ein mehrschichtiges ausfallsicheres System, das das Kapital proaktiv schützt und es der EA ermöglicht, den Betrieb nur unter gesunden Bedingungen wieder aufzunehmen.
Backtest-Ergebnisse
Das Backtesting wurde für den Zeitrahmen M15 über ein etwa zweimonatiges Testfenster (01. Oktober 2025 bis 30. November 2025) mit den folgenden Einstellungen bewertet:
| Variabel | Eingabe Wert |
|---|---|
| FastMAPeriod | 20 |
| SlowMAPeriod | 160 |
| InitialLotSize | 1 |
| LotMultiplier | 5.2 |
| MaxMartingaleStep | 13 |
| RistPercent | 7.8 |
| ATR_Period | 69 |
| ATR_SL_Factor | 3.3 |
| ATR_TP_Factor | 9.8 |
| UseEquityStop | false |
| EquityStopPercentage | 27.2 |
| UseDailyLossLimit | true |
| DailyLossPercent | 12.7 |
| UseMaxSpreadFilter | true |
| MaxSpreadPoints | 25 |
| UseTrailingStop | true |
| BreakEvenAtPips | 500 |
| TrailStartAtPips | 600 |
| TrailStepPips | 100 |
| MaxConsecutiveLosses | 22 |
| CircuitBreaketDD | 115.5 |
| MaxTradesPerHour | 33 |
| ThrottleWindowSeconds | 21025 |
| RecoveryRiskReduction | 3.6 |
| ResumeEquityPercent | 135 |
| ResumeAfterSeconds | 845307 |


Schlussfolgerung
Zusammenfassend kann gesagt werden, dass wir ein umfassendes, mehrschichtiges System zum Schutz von Konten entwickelt haben, das eine dynamische Risikokontrolle, strukturelle Kapitalgarantien, eine Verstärkung der Ausführung auf Handelsebene und systemische Ausfallsicherheiten umfasst. Diese Architektur kombiniert risikobasierte Losgrößenbestimmung, Kontrolle der kapitalbezogenen Spitzenwerte, kontrollierte Drawdown-Sperren, Auftragsüberprüfung unter Berücksichtigung von Kursabweichungen, Handelsunterbrecher und Drosselungsmechanismen, um sicherzustellen, dass jeder Handel sowohl intelligent dimensioniert als auch verantwortungsvoll verwaltet wird. Durch die Integration dieser Komponenten in ein einheitliches Schutzsystem passt sich das System kontinuierlich an die Volatilität an, überwacht den Zustand des Kapitals und greift automatisch ein, wenn die Handelsbedingungen ungünstig werden.
Zusammenfassend kann gesagt werden, dass dieses mehrschichtige Schutzmodell den Händlern ein äußerst widerstandsfähiges, selbstregulierendes Umfeld bietet, das dem Kapitalerhalt Priorität einräumt und gleichzeitig eine starke Performance anstrebt. Der EA verlässt sich nicht auf ein einziges Verteidigungsmerkmal, sondern agiert innerhalb eines koordinierten Netzwerks von Schutzmechanismen, die emotionale Entscheidungen minimieren, katastrophale Verlustspiralen verhindern und eine nachhaltige Langlebigkeit des Handels gewährleisten. Dies gibt Händlern die Zuversicht, höhere Gewinne anzustreben, da sie wissen, dass das System darauf ausgelegt ist, das Risiko aktiv zu verwalten, die Performance zu stabilisieren und das Konto in allen Phasen des Marktverhaltens zu erhalten.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/20449
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Einführung in MQL5 (Teil 30): Beherrschung der API- und WebRequest-Funktion in MQL5 (IV)
ARIMA-Prognose-Indikator in MQL5
Implementierung von praktischen Modulen aus anderen Sprachen in MQL5 (Teil 05): Das Logging-Modul von Python, Log Like a Pro
Adaptive Smart Money Architektur (ASMA): Verschmelzung von SMC-Logik und Marktstimmung für dynamische Strategie-Wechsel
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.