diff --git a/OrdersEA_Smart_Grid_BO.mq5 b/OrdersEA_Smart_Grid_BO.mq5 index ebf1814..752284f 100755 --- a/OrdersEA_Smart_Grid_BO.mq5 +++ b/OrdersEA_Smart_Grid_BO.mq5 @@ -5,12 +5,12 @@ //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Garfield Heron" #property link "https://fetcherpay.com" -#property version "5.0" +#property version "5.1" #include #include -#define VERSION "Version 5.0 Smart Grid Breakout BO MT5" +#define VERSION "Version 5.1 Smart Grid Breakout BO MT5" #define MAX_TRADES 600 #define MAX_LOG_TRADES 1200 @@ -71,6 +71,12 @@ input string BreakevenSettings = "=== Breakeven ==="; input bool InpUseBreakeven = false; // Move remaining SLs to breakeven after first TP hits input int InpBreakevenBufferPoints = 5; // Spread cushion above entry +//--- Trailing Stop (5.1) +input string TrailingSettings = "=== Trailing Stop ==="; +input bool InpUseTrailingStop = false; // Enable trailing stop on open positions +input int InpTrailStart = 1000; // Points of profit before trail activates +input int InpTrailStop = 500; // Trail distance behind price (points) + //--- Correlation Cap (4.3) input string CorrelationSettings = "=== Correlation Cap ==="; input int InpMaxLongSymbols = 0; // Max distinct symbols with open longs (0 = unlimited) @@ -806,6 +812,56 @@ void ApplyBreakeven() } } +//+------------------------------------------------------------------+ +//| Trailing Stop (5.1) | +//+------------------------------------------------------------------+ +void ApplyTrailingStop() + { + if(!InpUseTrailingStop) return; + if(InpTrailStart <= 0 || InpTrailStop <= 0) return; + + double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); + double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); + double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); + double trailStart = InpTrailStart * point; + double trailDist = InpTrailStop * point; + + for(int i = PositionsTotal() - 1; i >= 0; i--) + { + ulong ticket = PositionGetTicket(i); + if(ticket == 0) continue; + if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue; + if(PositionGetInteger(POSITION_MAGIC) != MagicNum) continue; + + long ptype = PositionGetInteger(POSITION_TYPE); + double open = PositionGetDouble(POSITION_PRICE_OPEN); + double curSL = PositionGetDouble(POSITION_SL); + double tp = PositionGetDouble(POSITION_TP); + double newSL; + + if(ptype == POSITION_TYPE_BUY) + { + if(bid - open < trailStart) continue; // profit threshold not reached + newSL = NormalizeDouble(bid - trailDist, _Digits); + if(newSL <= curSL) continue; // SL already at or ahead of trail + } + else if(ptype == POSITION_TYPE_SELL) + { + if(open - ask < trailStart) continue; + newSL = NormalizeDouble(ask + trailDist, _Digits); + if(curSL > 0 && newSL >= curSL) continue; // SL already at or ahead of trail + } + else continue; + + if(!trade.PositionModify(ticket, newSL, tp)) + PrintS("Trail modify failed #" + IntegerToString((int)ticket) + + " err=" + IntegerToString((int)trade.ResultRetcode())); + else + PrintS("Trail SL → " + DoubleToString(newSL, _Digits) + + " #" + IntegerToString((int)ticket)); + } + } + //+------------------------------------------------------------------+ //| Count partial TP fills since cycle start | //+------------------------------------------------------------------+ @@ -1184,6 +1240,8 @@ int OnInit() PrintS(VERSION + " initialized — Magic=" + IntegerToString(MagicNum) + " SL=" + (InpUseStopLoss ? "ON(" + IntegerToString(StopLoss) + ")" : "OFF") + + " Trail=" + (InpUseTrailingStop ? "ON(start=" + IntegerToString(InpTrailStart) + + "/dist=" + IntegerToString(InpTrailStop) + "pts)" : "OFF") + " AdaptiveEntry=" + (InpAdaptiveEntry ? "ON" : "OFF")); return INIT_SUCCEEDED; } @@ -1267,6 +1325,7 @@ void OnTick() CalcAvgPrice(); cyclePartialTPCount = CountPartialTPsSinceCycle(); ApplyBreakeven(); + ApplyTrailingStop(); lastStatsTime = TimeCurrent(); } diff --git a/bo-audnzd.set b/bo-audnzd.set index 7a3a376..ddbb6e0 100644 --- a/bo-audnzd.set +++ b/bo-audnzd.set @@ -27,6 +27,11 @@ ATRMultiplier=1.2 InpUseStopLoss=true StopLoss=180 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=40 LongLimit=0 diff --git a/bo-audusd.set b/bo-audusd.set index 0f5735b..5cd82b9 100644 --- a/bo-audusd.set +++ b/bo-audusd.set @@ -27,6 +27,11 @@ ATRMultiplier=1.5 InpUseStopLoss=true StopLoss=300 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=60 LongLimit=0 diff --git a/bo-eurchf.set b/bo-eurchf.set index 0153a65..0f4c97c 100644 --- a/bo-eurchf.set +++ b/bo-eurchf.set @@ -29,6 +29,11 @@ ATRMultiplier=1.2 InpUseStopLoss=true StopLoss=200 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=40 LongLimit=0 diff --git a/bo-eurgbp.set b/bo-eurgbp.set index 51df462..7b16695 100644 --- a/bo-eurgbp.set +++ b/bo-eurgbp.set @@ -27,6 +27,11 @@ ATRMultiplier=1.2 InpUseStopLoss=true StopLoss=200 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=40 LongLimit=0 diff --git a/bo-eurjpy.set b/bo-eurjpy.set index b3af3a5..d23dbaa 100644 --- a/bo-eurjpy.set +++ b/bo-eurjpy.set @@ -27,6 +27,11 @@ ATRMultiplier=1.7 InpUseStopLoss=true StopLoss=400 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=70 LongLimit=0 diff --git a/bo-eurusd.set b/bo-eurusd.set index 7a28997..18f30cf 100644 --- a/bo-eurusd.set +++ b/bo-eurusd.set @@ -27,6 +27,11 @@ ATRMultiplier=1.5 InpUseStopLoss=true StopLoss=300 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=60 LongLimit=0 diff --git a/bo-gbpjpy.set b/bo-gbpjpy.set index 927fa96..031a687 100644 --- a/bo-gbpjpy.set +++ b/bo-gbpjpy.set @@ -28,6 +28,11 @@ ATRMultiplier=2.2 InpUseStopLoss=true StopLoss=800 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=120 LongLimit=0 diff --git a/bo-gbpusd.set b/bo-gbpusd.set index 61a5a93..de99c41 100644 --- a/bo-gbpusd.set +++ b/bo-gbpusd.set @@ -27,6 +27,11 @@ ATRMultiplier=1.6 InpUseStopLoss=true StopLoss=350 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=70 LongLimit=0 diff --git a/bo-major.set b/bo-major.set index 6a24705..7bc5b82 100644 --- a/bo-major.set +++ b/bo-major.set @@ -29,6 +29,11 @@ ATRMultiplier=1.5 InpUseStopLoss=true StopLoss=300 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=60 LongLimit=0 diff --git a/bo-nzdusd.set b/bo-nzdusd.set index 459fc11..6e99dc7 100644 --- a/bo-nzdusd.set +++ b/bo-nzdusd.set @@ -27,6 +27,11 @@ ATRMultiplier=1.4 InpUseStopLoss=true StopLoss=280 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=55 LongLimit=0 diff --git a/bo-steady.set b/bo-steady.set index c6d1dcd..b10dd95 100644 --- a/bo-steady.set +++ b/bo-steady.set @@ -30,6 +30,11 @@ ATRMultiplier=1.2 InpUseStopLoss=true StopLoss=200 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=40 LongLimit=0 diff --git a/bo-usdcad.set b/bo-usdcad.set index 8430a9b..fc0f59e 100644 --- a/bo-usdcad.set +++ b/bo-usdcad.set @@ -27,6 +27,11 @@ ATRMultiplier=1.5 InpUseStopLoss=true StopLoss=300 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=60 LongLimit=0 diff --git a/bo-usdchf.set b/bo-usdchf.set index 809f1eb..a1bd835 100644 --- a/bo-usdchf.set +++ b/bo-usdchf.set @@ -28,6 +28,11 @@ ATRMultiplier=1.4 InpUseStopLoss=true StopLoss=280 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=55 LongLimit=0 diff --git a/bo-usdjpy.set b/bo-usdjpy.set index 20bc221..0898179 100644 --- a/bo-usdjpy.set +++ b/bo-usdjpy.set @@ -27,6 +27,11 @@ ATRMultiplier=1.5 InpUseStopLoss=true StopLoss=300 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=60 LongLimit=0 diff --git a/bo-volatile.set b/bo-volatile.set index aff4fc1..7420dab 100644 --- a/bo-volatile.set +++ b/bo-volatile.set @@ -29,6 +29,11 @@ ATRMultiplier=2.0 InpUseStopLoss=true StopLoss=800 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=100 LongLimit=0 diff --git a/bo-xagusd.set b/bo-xagusd.set index 24f1da1..2296254 100644 --- a/bo-xagusd.set +++ b/bo-xagusd.set @@ -28,6 +28,11 @@ ATRMultiplier=2.2 InpUseStopLoss=true StopLoss=1000 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=150 LongLimit=0 diff --git a/bo-xauusd.set b/bo-xauusd.set index 4c9f355..6ddda5e 100644 --- a/bo-xauusd.set +++ b/bo-xauusd.set @@ -28,6 +28,11 @@ ATRMultiplier=2.5 InpUseStopLoss=true StopLoss=1500 +; === Trailing Stop === +InpUseTrailingStop=true +InpTrailStart=1000 +InpTrailStop=500 + ; === Risk Management === TRADE_RANGE=200 LongLimit=0