Untitled
unknown
plain_text
2 months ago
14 kB
4
Indexable
//+------------------------------------------------------------------+ //| SmartBTC_EA_fixed.mq4 | //| Expert Advisor con stop-loss corretto a ±0.01 in profitto | //+------------------------------------------------------------------+ #property strict // Parametri di input input double RiskPercent = 1.5; // Percentuale di rischio per trade input double InitialStopLossPercentage= 0.1; // Stop-Loss iniziale (0.1%) input double DynamicStopLossPercentage= 0.05; // Trailing Stop-Loss dinamico (0.05%) input double MaxDrawdown = 5.0; // Drawdown massimo % per bloccare operazioni input double MinATRThreshold = 0.0005;// Soglia minima di ATR input double MaxATRThresholdMultiplier= 10.0; // Moltiplicatore massima ATR input int MinVolumeThreshold = 100; // Soglia volume minimo input bool EnableBreakoutStrategy = true; // Abilita strategia breakout se ATR alto input bool EnableMultiTimeframeConfirmation = true; // Conferma multi-timeframe input bool EnableRSIFilter = true; // Abilita filtro RSI input int RSI_Period = 14; // Periodo RSI input double RSI_Buy_Level = 35.0; // Livello RSI per BUY input double RSI_Sell_Level = 65.0; // Livello RSI per SELL input int MaxTradesInInterval = 3; // Numero max operazioni in un intervallo input int TradeIntervalSeconds = 300; // Intervallo di tempo in secondi per i trade input double TrailingStopDistance = 0.01; // Distanza del trailing stop al seguito del prezzo // Variabili globali double atrValue; double accountEquityStart; datetime lastOrderTime = 0; int tradesOpened = 0; //+------------------------------------------------------------------+ //| Expert initialization | //+------------------------------------------------------------------+ int OnInit() { accountEquityStart = AccountEquity(); Print("SmartBTC_EA_v5 inizializzato correttamente!"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Calcolo Stop Loss iniziale dinamico | //+------------------------------------------------------------------+ double CalculateDynamicStopLoss(bool isBuy) { double stopLoss = 0.0; if(isBuy) stopLoss = Bid - (Bid * InitialStopLossPercentage / 100.0); else stopLoss = Ask + (Ask * InitialStopLossPercentage / 100.0); Print("Stop Loss calcolato: ", stopLoss); return(stopLoss); } //+------------------------------------------------------------------+ //| Gestione Trailing Stop (con spostamento forzato a ±0,01) | //+------------------------------------------------------------------+ void ManageTrailingStop() { // Scorri tutti gli ordini aperti for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // Controlla che l'ordine appartenga al simbolo corrente if(OrderSymbol() != Symbol()) continue; double newStop = 0.0; // ================================================================= // ORDINE BUY // ================================================================= if(OrderType() == OP_BUY) { // Se l'ordine è in profitto (Bid > prezzo di apertura) if(Bid > OrderOpenPrice()) { // Sposta SUBITO lo stop a Bid - TrailingStopDistance newStop = Bid - TrailingStopDistance; newStop = NormalizeDouble(newStop, Digits); // Aggiorna lo stop se è diverso dall'attuale if(OrderStopLoss() != newStop) { Print("Ordine BUY in profitto. Forzo stop a: ", DoubleToString(newStop, Digits)); if(!OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0, clrGreen)) { Print("Errore nella modifica dell'ordine BUY: ", GetLastError()); } } } else { // Non in profitto: trailing stop dinamico (percentuale sul prezzo) newStop = Bid - (Bid * DynamicStopLossPercentage / 100.0); newStop = NormalizeDouble(newStop, Digits); // Aggiorna solo se migliora il vecchio stop (o se non era impostato) if(OrderStopLoss() == 0 || newStop > OrderStopLoss()) { Print("Trailing Stop BUY aggiornato a: ", DoubleToString(newStop, Digits)); if(!OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0, clrGreen)) { Print("Errore modifica trailing BUY: ", GetLastError()); } } } } // ================================================================= // ORDINE SELL // ================================================================= else if(OrderType() == OP_SELL) { // Se l'ordine è in profitto (Ask < prezzo di apertura) if(Ask < OrderOpenPrice()) { // Sposta SUBITO lo stop a Ask + TrailingStopDistance newStop = Ask + TrailingStopDistance; newStop = NormalizeDouble(newStop, Digits); // Aggiorna lo stop se è diverso dall'attuale if(OrderStopLoss() != newStop) { Print("Ordine SELL in profitto. Forzo stop a: ", DoubleToString(newStop, Digits)); if(!OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0, clrRed)) { Print("Errore nella modifica dell'ordine SELL: ", GetLastError()); } } } else { // Non in profitto: trailing stop dinamico (percentuale sul prezzo) newStop = Ask + (Ask * DynamicStopLossPercentage / 100.0); newStop = NormalizeDouble(newStop, Digits); // Aggiorna solo se migliora il vecchio stop (o se non era impostato) if(OrderStopLoss() == 0 || newStop < OrderStopLoss()) { Print("Trailing Stop SELL aggiornato a: ", DoubleToString(newStop, Digits)); if(!OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0, clrRed)) { Print("Errore modifica trailing SELL: ", GetLastError()); } } } } } } } //+------------------------------------------------------------------+ //| Determinazione del Trend | //+------------------------------------------------------------------+ int DetermineTrend() { double maShort = iMA(NULL, 0, 5, 0, MODE_EMA, PRICE_CLOSE, 0); double maLong = iMA(NULL, 0, 20, 0, MODE_EMA, PRICE_CLOSE, 0); if(maShort > maLong) { Print("Trend rilevato: BUY"); return(OP_BUY); } else if(maShort < maLong) { Print("Trend rilevato: SELL"); return(OP_SELL); } Print("Nessun trend rilevato."); return(-1); } //+------------------------------------------------------------------+ //| Conferma Multi-Timeframe del Trend | //+------------------------------------------------------------------+ bool ConfirmMultiTimeframeTrend(int trend) { double maShortM1 = iMA(NULL, PERIOD_M1, 5, 0, MODE_EMA, PRICE_CLOSE, 0); double maLongM1 = iMA(NULL, PERIOD_M1, 20, 0, MODE_EMA, PRICE_CLOSE, 0); double maShortM5 = iMA(NULL, PERIOD_M5, 5, 0, MODE_EMA, PRICE_CLOSE, 0); double maLongM5 = iMA(NULL, PERIOD_M5, 20, 0, MODE_EMA, PRICE_CLOSE, 0); if(trend == OP_BUY && (maShortM1 > maLongM1) && (maShortM5 > maLongM5)) { Print("Trend BUY confermato su M1 e M5."); return(true); } if(trend == OP_SELL && (maShortM1 < maLongM1) && (maShortM5 < maLongM5)) { Print("Trend SELL confermato su M1 e M5."); return(true); } Print("Trend non confermato nei timeframe superiori."); return(false); } //+------------------------------------------------------------------+ //| Verifica dei livelli RSI per conferma operazione | //+------------------------------------------------------------------+ bool CheckRSIConditions(int trend) { double rsiValue = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, 0); Print("Valore RSI corrente: ", rsiValue); if(trend == OP_BUY && rsiValue <= RSI_Buy_Level) { Print("Condizione RSI per BUY soddisfatta."); return(true); } if(trend == OP_SELL && rsiValue >= RSI_Sell_Level) { Print("Condizione RSI per SELL soddisfatta."); return(true); } Print("Condizioni RSI non soddisfatte."); return(false); } //+------------------------------------------------------------------+ //| Apertura Ordine | //+------------------------------------------------------------------+ bool OpenOrder(int orderType, double lotSize, double stopLoss, double takeProfit) { int ticket; if(orderType == OP_BUY) { ticket = OrderSend(Symbol(), OP_BUY, lotSize, Ask, 3, stopLoss, takeProfit, "BTC Buy", 0, 0, clrBlue); Print("Tentativo di apertura ordine BUY."); } else { ticket = OrderSend(Symbol(), OP_SELL, lotSize, Bid, 3, stopLoss, takeProfit, "BTC Sell", 0, 0, clrRed); Print("Tentativo di apertura ordine SELL."); } if(ticket < 0) { int errorCode = GetLastError(); Print("Errore nell'apertura dell'ordine: ", errorCode); if(errorCode == 134) Print("Errore 134: Margine non sufficiente."); if(errorCode == 131) Print("Errore 131: Volume del lotto non valido."); if(errorCode == 146) Print("Errore 146: Modifica ordine rifiutata."); return(false); } Print("Ordine aperto con successo. Ticket: ", ticket); return(true); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Calcolo ATR e volume atrValue = iATR(NULL, 0, 14, 0); long currVolume = iVolume(NULL, 0, 0); Print("ATR attuale: ", atrValue, ", Volume attuale: ", currVolume); // Se ATR è sotto soglia minima if(atrValue <= MinATRThreshold) { Print("Volatilità troppo bassa (ATR: ", atrValue, "), nessun ordine aperto."); return; } // Se ATR è oltre soglia massima if(atrValue > (MinATRThreshold * MaxATRThresholdMultiplier)) { if(EnableBreakoutStrategy) { Print("Volatilità alta, strategia breakout attiva, procedo col trade."); } else { Print("Volatilità eccessiva (ATR: ", atrValue, "), evitato il trade."); return; } } // Verifica se il volume è sufficiente if(currVolume < MinVolumeThreshold) { Print("Volume troppo basso (", currVolume, "), nessun ordine aperto."); return; } // Verifica drawdown massimo if(AccountEquity() < (accountEquityStart * (1 - MaxDrawdown / 100.0))) { Print("Drawdown massimo raggiunto. Blocco temporaneo delle operazioni."); return; } // Verifica limite di operazioni in un intervallo if(TimeCurrent() - lastOrderTime < TradeIntervalSeconds && tradesOpened >= MaxTradesInInterval) { Print("Limite di operazioni raggiunto nell'intervallo."); return; } // Determina il trend int trend = DetermineTrend(); if(trend != -1 && (!EnableMultiTimeframeConfirmation || ConfirmMultiTimeframeTrend(trend))) { // Se RSI è attivo, controlla i livelli if(!EnableRSIFilter || CheckRSIConditions(trend)) { double stopLoss, takeProfit; if(trend == OP_BUY) { stopLoss = CalculateDynamicStopLoss(true); takeProfit = Bid + (atrValue * 4); if(OpenOrder(OP_BUY, 0.25, stopLoss, takeProfit)) { lastOrderTime = TimeCurrent(); tradesOpened++; } } else if(trend == OP_SELL) { stopLoss = CalculateDynamicStopLoss(false); takeProfit = Ask - (atrValue * 4); if(OpenOrder(OP_SELL, 0.25, stopLoss, takeProfit)) { lastOrderTime = TimeCurrent(); tradesOpened++; } } } else { Print("Condizioni RSI non soddisfatte, nessun ordine aperto."); } } else { Print("Condizioni non soddisfatte per aprire un ordine."); } // Gestione dello Stop Loss dinamico e trailing stop ManageTrailingStop(); } //+------------------------------------------------------------------+ //| OnDeinit | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { EventKillTimer(); Print("EA terminato. Motivo: ", reason); } //+------------------------------------------------------------------+
Editor is loading...
Leave a Comment