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 link "https://www.abbeyroadtech.com"
|
||||
#property version "1.14"
|
||||
#property version "1.15"
|
||||
#property strict
|
||||
|
||||
#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 InpTakeProfit = 200; // Take Profit in points
|
||||
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 group "=== Filters ==="
|
||||
@@ -82,14 +85,20 @@ int OnInit()
|
||||
|
||||
lastBarTime = iTime(_Symbol, _Period, 0);
|
||||
|
||||
Print("=== MultiSignal Confluence EA v1.12 Initialized ===");
|
||||
Print("=== MultiSignal Confluence EA v1.15 Initialized ===");
|
||||
Print("Symbol: ", _Symbol);
|
||||
Print("Magic: ", InpMagicNumber);
|
||||
Print("Min Confluence: ", InpMinConfluence);
|
||||
Print("Min Strength: ", InpMinStrength);
|
||||
Print("Volatility Filter: ", InpUseVolatilityFilter ? "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);
|
||||
}
|
||||
@@ -685,9 +694,9 @@ void OnTick()
|
||||
bool isNewBar = (currentBarTime != lastBarTime);
|
||||
|
||||
// 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
|
||||
@@ -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