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
+34 -13
View File
@@ -355,10 +355,33 @@ void ManagePositions(const MarketData &data, const FinalSignal &fs) {
} }
int ticket = 0; int ticket = 0;
if(fs.direction == 1) // Calcolo TakeProfit opzionale (usiamo lo stesso fattoreATR per TP)
ticket = trade.Buy(lot, sym, ask, sl, 0); // TP=0: trailing stop double tp = 0;
else // TakeProfit: se impostato usa Inp_TPRiskATR, altrimenti usa lo stesso fattore di SL (dynamic)
ticket = trade.Sell(lot, sym, bid, sl, 0); 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) { if(ticket > 0) {
orchestrator.OnTradeOpen(ticket, price, atr); orchestrator.OnTradeOpen(ticket, price, atr);
@@ -396,30 +419,28 @@ void LogSignal(const MarketData &data, const FinalSignal &fs) {
void OnTrade() { void OnTrade() {
static int onTradeCloses = 0; static int onTradeCloses = 0;
static int saveInterval = 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; if(!orchestrator.HasOpenTrade()) return;
int maxSlots = orchestrator.MaxTradeSlots(); int maxSlots = orchestrator.MaxTradeSlots();
for(int t = 0; t < maxSlots; t++) { for(int t = 0; t < maxSlots; t++) {
int tkt = orchestrator.GetTrackedTicket(t); int tkt = orchestrator.GetTrackedTicket(t);
if(tkt < 0) break; // nessun altro trade attivo if(tkt < 0) break; // no more active trades
bool found = false; bool found = false;
for(int p = PositionsTotal()-1; p >= 0; p--) { for(int p = PositionsTotal() - 1; p >= 0; p--) {
if(posInfo.SelectByIndex(p)) { if(posInfo.SelectByIndex(p)) {
if((int)posInfo.Ticket() == tkt) { found = true; break; } if((int)posInfo.Ticket() == tkt) { found = true; break; }
} }
} }
if(!found) { if(!found) {
// Trade chiuso da SL/TP (non da noi in ManagePositions) // Trade closed by SL/TP (not by ManagePositions)
bool isBuy = orchestrator.IsBuyTrade(tkt); bool isBuy = orchestrator.IsBuyTrade(tkt);
double closePrice = isBuy ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK); double closePrice = isBuy ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK);
orchestrator.OnTradeClose(tkt, closePrice); orchestrator.OnTradeClose(tkt, closePrice);
onTradeCloses++; onTradeCloses++;
Print("SL/TP chiuso trade #", tkt, " (totale SL/TP: ", onTradeCloses, ")"); Print("SL/TP chiuso trade #", tkt, " (totale SL/TP: ", onTradeCloses, ")");
if(onTradeCloses % saveInterval == 0) if(onTradeCloses % saveInterval == 0)
orchestrator.SaveState(sym, Inp_TF); orchestrator.SaveState(sym, Inp_TF);
} }