v1.15: Add trailing stop implementation to Confluence EA
This commit is contained in:
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
|
|||||||
Reference in New Issue
Block a user