v1.15: Add trailing stop implementation to Confluence EA

This commit is contained in:
2026-03-30 08:31:28 -04:00
parent baaac18b84
commit 53171c3c36

View File

@@ -5,7 +5,7 @@
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
#property copyright "Copyright 2025, Abbey Road Tech" #property copyright "Copyright 2025, Abbey Road Tech"
#property link "https://www.abbeyroadtech.com" #property link "https://www.abbeyroadtech.com"
#property version "1.14" #property version "1.15"
#property strict #property strict
#include <Trade\Trade.mqh> #include <Trade\Trade.mqh>
@@ -23,6 +23,9 @@ input double InpRiskPercent = 1.0; // Risk % per trade (1.0 = 1% of a
input int InpStopLoss = 100; // Stop Loss in points input int InpStopLoss = 100; // Stop Loss in points
input int InpTakeProfit = 200; // Take Profit in points input int InpTakeProfit = 200; // Take Profit in points
input bool InpUseTrailingStop = true; // Use trailing stop input bool InpUseTrailingStop = true; // Use trailing stop
input int InpTrailingStart = 50; // Points of profit before trailing begins
input int InpTrailingStop = 30; // Trailing stop distance in points
input int InpTrailingStep = 10; // Minimum step to move SL
input int InpMaxPositions = 3; // Max concurrent positions per symbol input int InpMaxPositions = 3; // Max concurrent positions per symbol
input group "=== Filters ===" input group "=== Filters ==="
@@ -82,14 +85,20 @@ int OnInit()
lastBarTime = iTime(_Symbol, _Period, 0); lastBarTime = iTime(_Symbol, _Period, 0);
Print("=== MultiSignal Confluence EA v1.12 Initialized ==="); Print("=== MultiSignal Confluence EA v1.15 Initialized ===");
Print("Symbol: ", _Symbol); Print("Symbol: ", _Symbol);
Print("Magic: ", InpMagicNumber); Print("Magic: ", InpMagicNumber);
Print("Min Confluence: ", InpMinConfluence); Print("Min Confluence: ", InpMinConfluence);
Print("Min Strength: ", InpMinStrength); Print("Min Strength: ", InpMinStrength);
Print("Volatility Filter: ", InpUseVolatilityFilter ? "ON" : "OFF"); Print("Volatility Filter: ", InpUseVolatilityFilter ? "ON" : "OFF");
Print("ADX Filter: ", InpUseADXFilter ? "ON" : "OFF"); Print("ADX Filter: ", InpUseADXFilter ? "ON" : "OFF");
Print("This EA trades DIRECTLY - no external indicator needed!"); Print("Trailing Stop: ", InpUseTrailingStop ? "ON" : "OFF");
if(InpUseTrailingStop)
{
Print(" Trailing Start: ", InpTrailingStart, " pts");
Print(" Trailing Stop: ", InpTrailingStop, " pts");
Print(" Trailing Step: ", InpTrailingStep, " pts");
}
return(INIT_SUCCEEDED); return(INIT_SUCCEEDED);
} }
@@ -685,9 +694,9 @@ void OnTick()
bool isNewBar = (currentBarTime != lastBarTime); bool isNewBar = (currentBarTime != lastBarTime);
// Update trailing stops on every tick // Update trailing stops on every tick
if(InpUseTrailingStop && !isNewBar) if(InpUseTrailingStop)
{ {
// Simple trailing stop logic can be added here UpdateTrailingStops();
} }
// Only process on new bar // Only process on new bar
@@ -770,4 +779,91 @@ void OnTick()
} }
} }
} }
//+------------------------------------------------------------------+
//| Update trailing stops for all open positions |
//+------------------------------------------------------------------+
void UpdateTrailingStops()
{
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double trailingStart = InpTrailingStart * point;
double trailingDist = InpTrailingStop * point;
double trailingStep = InpTrailingStep * point;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0) continue;
// Only process positions for this EA
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber) continue;
long posType = PositionGetInteger(POSITION_TYPE);
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double currentSL = PositionGetDouble(POSITION_SL);
double currentTP = PositionGetDouble(POSITION_TP);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
bool modify = false;
double newSL = 0;
if(posType == POSITION_TYPE_BUY)
{
// For BUY: trailing stop below price
double profit = bid - openPrice;
if(profit >= trailingStart)
{
newSL = NormalizeDouble(bid - trailingDist, _Digits);
// Only move if new SL is better and meets step requirement
if(newSL > currentSL + trailingStep || currentSL == 0)
{
modify = true;
}
}
}
else if(posType == POSITION_TYPE_SELL)
{
// For SELL: trailing stop above price
double profit = openPrice - ask;
if(profit >= trailingStart)
{
newSL = NormalizeDouble(ask + trailingDist, _Digits);
// Only move if new SL is better and meets step requirement
if(currentSL == 0 || newSL < currentSL - trailingStep)
{
modify = true;
}
}
}
if(modify)
{
// Ensure SL is valid (not too close to current price)
double minDist = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * point;
if(posType == POSITION_TYPE_BUY)
{
if(bid - newSL < minDist)
newSL = NormalizeDouble(bid - minDist, _Digits);
}
else
{
if(newSL - ask < minDist)
newSL = NormalizeDouble(ask + minDist, _Digits);
}
if(Trade.PositionModify(ticket, newSL, currentTP))
{
Print("✅ Trailing stop updated for #", ticket, " New SL: ", DoubleToString(newSL, _Digits));
}
else
{
Print("❌ Failed to update trailing stop for #", ticket, ": ", Trade.ResultRetcodeDescription());
}
}
}
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+