Untitled

 avatar
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