Untitled
unknown
plain_text
9 months ago
14 kB
5
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