Add TP validation via Inp_TPRiskATR, fix saveInterval in OnTrade, add SL/TP order validation

This commit is contained in:
pietro_giacobazzi
2026-06-14 09:38:54 +02:00
parent 6296cc36b2
commit dcf01418ea
+51 -30
View File
@@ -355,14 +355,37 @@ void ManagePositions(const MarketData &data, const FinalSignal &fs) {
}
int ticket = 0;
if(fs.direction == 1)
ticket = trade.Buy(lot, sym, ask, sl, 0); // TP=0: trailing stop
else
ticket = trade.Sell(lot, sym, bid, sl, 0);
// Calcolo TakeProfit opzionale (usiamo lo stesso fattoreATR per TP)
double tp = 0;
// TakeProfit: se impostato usa Inp_TPRiskATR, altrimenti usa lo stesso fattore di SL (dynamic)
double tpWidth = (Inp_TPRiskATR > 0) ? Inp_TPRiskATR : ((Inp_SLRiskATR > 0) ? Inp_SLRiskATR : orchestrator.AdaptiveSLWidth());
if(tpWidth > 0) {
tp = (fs.direction == 1) ? price + atr * tpWidth : price - atr * tpWidth;
tp = NormalizeDouble(tp, dig);
}
if(fs.direction == 1) {
// BUY validate SL and TP
if(sl <= 0 || sl >= ask) {
Print("Invalid BUY SL (", sl, ") order skipped");
} else if(tp > 0 && tp <= sl) {
Print("Invalid BUY TP (", tp, ") must be > SL order skipped");
} else {
ticket = trade.Buy(lot, sym, ask, sl, tp); // TP may be 0 (no TP)
}
} else {
// SELL validate SL and TP
if(sl <= 0 || sl <= bid) {
Print("Invalid SELL SL (", sl, ") order skipped");
} else if(tp > 0 && tp >= sl) {
Print("Invalid SELL TP (", tp, ") must be < SL order skipped");
} else {
ticket = trade.Sell(lot, sym, bid, sl, tp);
}
}
if(ticket > 0) {
orchestrator.OnTradeOpen(ticket, price, atr);
}
if(ticket > 0) {
orchestrator.OnTradeOpen(ticket, price, atr);
}
}
}
@@ -396,33 +419,31 @@ void LogSignal(const MarketData &data, const FinalSignal &fs) {
void OnTrade() {
static int onTradeCloses = 0;
static int saveInterval = 0;
if(saveInterval == 0) saveInterval = MathMax(orchestrator.TotalAgents(), orchestrator.TotalAgents() * 5);
if(saveInterval == 0) {
// Minimum 5 trades, scaled with number of agents
saveInterval = MathMax(5, orchestrator.TotalAgents() * 5);
}
if(!orchestrator.HasOpenTrade()) return;
int maxSlots = orchestrator.MaxTradeSlots();
for(int t = 0; t < maxSlots; t++) {
int tkt = orchestrator.GetTrackedTicket(t);
if(tkt < 0) break; // nessun altro trade attivo
bool found = false;
for(int p = PositionsTotal()-1; p >= 0; p--) {
if(posInfo.SelectByIndex(p)) {
if((int)posInfo.Ticket() == tkt) { found = true; break; }
}
}
int tkt = orchestrator.GetTrackedTicket(t);
if(tkt < 0) break; // no more active trades
bool found = false;
for(int p = PositionsTotal() - 1; p >= 0; p--) {
if(posInfo.SelectByIndex(p)) {
if((int)posInfo.Ticket() == tkt) { found = true; break; }
}
}
if(!found) {
// Trade chiuso da SL/TP (non da noi in ManagePositions)
bool isBuy = orchestrator.IsBuyTrade(tkt);
double closePrice = isBuy ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK);
orchestrator.OnTradeClose(tkt, closePrice);
onTradeCloses++;
Print("SL/TP chiuso trade #", tkt, " (totale SL/TP: ", onTradeCloses, ")");
if(onTradeCloses % saveInterval == 0)
orchestrator.SaveState(sym, Inp_TF);
}
// Trade closed by SL/TP (not by ManagePositions)
bool isBuy = orchestrator.IsBuyTrade(tkt);
double closePrice = isBuy ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK);
orchestrator.OnTradeClose(tkt, closePrice);
onTradeCloses++;
Print("SL/TP chiuso trade #", tkt, " (totale SL/TP: ", onTradeCloses, ")");
if(onTradeCloses % saveInterval == 0)
orchestrator.SaveState(sym, Inp_TF);
}
}
}