EA per implementare MACD

 

Ciao A Tutti!

sto cercando di costruire un EA che implementi una strategia di trading basata su MACD, premetto che mi sto servendo dell'AI non sarei in grado di farlo da solo ma sto provando ad imparare... l'ea generato sino ora riconosce abbastanza bene gli incroci MACD dal basso verso l'alto e viceversa, ma non appena inserisco (o meglio lo inserisce l'AI) la condizione che gli incroci rialzisti si verifichino con MACD minore di zero e viceversa il prodotto è un EA che perde moltissimi incroci buoni. di seguito incollo prima  il codice "funzionante" quindi senza controllo del segno di macd e poi quello che non ne vuole saper con il controllo sul segno. inutile dire che vi sarei molto grato se qualcuno riuscisse a daremi qualche suggerimento. grazie a tutti!!!


//+------------------------------------------------------------------+
//|                                           MACD_9_8_2025_rev2.mq5 |
//|                                      Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.05"
#property description "Expert Advisor basato sull'incrocio di MACD."
#property strict

//--- We include the trading library to simplify operations
#include <Trade\Trade.mqh>

//--- Global variables
CTrade trade;
int macd_handle;

//--- Static variables for bar control
static datetime last_bar_time = 0;

//--- User input parameters
input ENUM_TIMEFRAMES Inp_Timeframe = PERIOD_M5; // Timeframe (from M1 to H1)
input int Inp_MACD_Fast_Period = 12; // Fast MACD EMA period
input int Inp_MACD_Slow_Period = 26; // Slow MACD EMA period
input int Inp_MACD_Signal_Period = 9; // MACD Signal SMA period
input double Inp_Lots = 0.1; // Lot volume
input int Inp_TakeProfit_Points = 500; // Take Profit in points
input int Inp_StopLoss_Points = 250; // Stop Loss in points
input int Inp_Max_Positions = 1; // Maximum number of open positions

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- We create the handle for the MACD indicator
   macd_handle = iMACD(_Symbol, Inp_Timeframe, Inp_MACD_Fast_Period, Inp_MACD_Slow_Period, Inp_MACD_Signal_Period, PRICE_CLOSE);
   
   if(macd_handle == INVALID_HANDLE)
     {
      Print("Error creating the MACD indicator. Error: ", GetLastError());
      return(INIT_FAILED);
     }

//--- We add the MACD indicator to the chart
   ChartIndicatorAdd(0, 0, macd_handle);
     
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Release the MACD indicator handle
   if(macd_handle != INVALID_HANDLE)
      IndicatorRelease(macd_handle);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- We check that the previous bar on the specified timeframe has closed
   if(!IsNewBar(Inp_Timeframe))
     {
      return;
     }

//--- We check the number of open positions
   if(PositionsTotal() >= Inp_Max_Positions)
     {
      return;
     }

//--- Arrays for MACD and Signal values
   double macd_buffer[2];
   double signal_buffer[2];
   
//--- We copy the MACD and Signal indicator values for the last two closed candles
   if(CopyBuffer(macd_handle, 0, 1, 2, macd_buffer) <= 0 || CopyBuffer(macd_handle, 1, 1, 2, signal_buffer) <= 0)
     {
      Print("Error copying indicator data. Error: ", GetLastError());
      return;
     }
     
//--- We calculate the difference between MACD and Signal for the last two closed candles
   double macd_diff0 = macd_buffer[0] - signal_buffer[0]; // Candle 0 (the most recent)
   double macd_diff1 = macd_buffer[1] - signal_buffer[1]; // Candle 1 (previous)

//--- Logic for a LONG position: bullish crossover
//--- The difference between MACD and Signal goes from negative or zero to positive
   if(macd_diff1 <= 0 && macd_diff0 > 0)
     {
      Print("Bullish crossover detected! Opening a LONG position.");
      OpenLongPosition();
     }
//--- Logic for a SHORT position: bearish crossover
//--- The difference between MACD and Signal goes from positive or zero to negative
   else if(macd_diff1 >= 0 && macd_diff0 < 0)
     {
      Print("Bearish crossover detected! Opening a SHORT position.");
      OpenShortPosition();
     }
  }
//+------------------------------------------------------------------+
//| Checks if a new bar has started on the specified timeframe |
//+------------------------------------------------------------------+
bool IsNewBar(ENUM_TIMEFRAMES timeframe)
  {
   datetime current_bar_time = iTime(_Symbol, timeframe, 0); 
   if(current_bar_time != last_bar_time)
     {
      last_bar_time = current_bar_time;
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//| Function to open a LONG position                           |
//+------------------------------------------------------------------+
void OpenLongPosition()
  {
   MqlTick tick;
   SymbolInfoTick(_Symbol, tick);
   
   double stop_loss = NormalizeDouble(tick.bid - Inp_StopLoss_Points * _Point, _Digits);
   double take_profit = NormalizeDouble(tick.bid + Inp_TakeProfit_Points * _Point, _Digits);
   
   if(!trade.Buy(Inp_Lots, _Symbol, tick.ask, stop_loss, take_profit))
     {
      Print("Error opening a LONG position. Error: ", GetLastError());
     }
  }
//+------------------------------------------------------------------+
//| Function to open a SHORT position                          |
//+------------------------------------------------------------------+
void OpenShortPosition()
  {
   MqlTick tick;
   SymbolInfoTick(_Symbol, tick);
   
   double stop_loss = NormalizeDouble(tick.ask + Inp_StopLoss_Points * _Point, _Digits);
   double take_profit = NormalizeDouble(tick.ask - Inp_TakeProfit_Points * _Point, _Digits);
   
   if(!trade.Sell(Inp_Lots, _Symbol, tick.bid, stop_loss, take_profit))
     {
      Print("Error opening a SHORT position. Error: ", GetLastError());
     }
  }
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//--- This function is activated on every trading event
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
//---
  }
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=0.0;
//---

//---
   return(ret);
  }
//+------------------------------------------------------------------+
//| TesterInit function                                              |
//+------------------------------------------------------------------+
void OnTesterInit()
  {
//---
  }
//+------------------------------------------------------------------+
//| TesterPass function                                              |
//+------------------------------------------------------------------+
void OnTesterPass()
  {
//---
  }
//+------------------------------------------------------------------+
//| TesterDeinit function                                            |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
//---
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int32_t id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
//---
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                           MACD_9_8_2025_rev2.mq5 |
//|                                      Copyright 2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.15"
#property description "Expert Advisor basato sull'incrocio di MACD con controllo sul segno."
#property strict

//--- Includiamo la libreria di trading per semplificare le operazioni
#include <Trade\Trade.mqh>

//--- Variabili globali
CTrade trade;
int macd_handle;

//--- Variabili statiche per il controllo della barra
static datetime last_bar_time = 0;

//--- Parametri di input per l'utente
input ENUM_TIMEFRAMES Inp_Timeframe = PERIOD_M5; // Timeframe (da M1 a H1)
input int Inp_MACD_Fast_Period = 12; // Periodo EMA veloce del MACD
input int Inp_MACD_Slow_Period = 26; // Periodo EMA lenta del MACD
input int Inp_MACD_Signal_Period = 9; // Periodo SMA del segnale MACD
input double Inp_Lots = 0.1; // Volume del lotto
input int Inp_TakeProfit_Points = 500; // Take Profit in punti
input int Inp_StopLoss_Points = 250; // Stop Loss in punti
input int Inp_Max_Positions = 1; // Numero massimo di posizioni aperte

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Creiamo l'handle per l'indicatore MACD
   macd_handle = iMACD(_Symbol, Inp_Timeframe, Inp_MACD_Fast_Period, Inp_MACD_Slow_Period, Inp_MACD_Signal_Period, PRICE_CLOSE);
   
   if(macd_handle == INVALID_HANDLE)
     {
      Print("Errore nella creazione dell'indicatore MACD. Errore: ", GetLastError());
      return(INIT_FAILED);
     }

//--- Aggiungiamo l'indicatore MACD al grafico
   ChartIndicatorAdd(0, 0, macd_handle);
     
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Rilascia l'handle dell'indicatore MACD
   if(macd_handle != INVALID_HANDLE)
      IndicatorRelease(macd_handle);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Controlliamo che la barra precedente sul timeframe specificato sia stata chiusa
   if(!IsNewBar(Inp_Timeframe))
     {
      return;
     }

//--- Controlliamo il numero di posizioni aperte
   if(PositionsTotal() >= Inp_Max_Positions)
     {
      return;
     }

//--- Array per i valori MACD e Signal
   double macd_buffer[2];
   double signal_buffer[2];
   
//--- Copiamo i valori dell'indicatore MACD e Signal per le ultime due candele chiuse
   if(CopyBuffer(macd_handle, 0, 1, 2, macd_buffer) <= 0 || CopyBuffer(macd_handle, 1, 1, 2, signal_buffer) <= 0)
     {
      Print("Errore nella copia dei dati dell'indicatore. Errore: ", GetLastError());
      return;
     }
     
//--- Calcoliamo la differenza tra MACD e Signal per le ultime due candele chiude
   double macd_diff0 = macd_buffer[0] - signal_buffer[0]; // Candela 0 (la più recente)
   double macd_diff1 = macd_buffer[1] - signal_buffer[1]; // Candela 1 (precedente)

//--- Logica per una posizione LONG: incrocio rialzista e MACD sull'ultima candela chiusa minore di zero
   if(macd_diff1 <= 0 && macd_diff0 > 0 && macd_buffer[0] < 0)
     {
      Print("Incrocio rialzista rilevato con MACD negativo! Apertura di una posizione LONG.");
      OpenLongPosition();
     }
//--- Logica per una posizione SHORT: incrocio ribassista e MACD sull'ultima candela chiusa maggiore di zero
   else if(macd_diff1 >= 0 && macd_diff0 < 0 && macd_buffer[0] > 0)
     {
      Print("Incrocio ribassista rilevato con MACD positivo! Apertura di una posizione SHORT.");
      OpenShortPosition();
     }
  }
//+------------------------------------------------------------------+
//| Controlla se è iniziata una nuova barra sul timeframe specificato |
//+------------------------------------------------------------------+
bool IsNewBar(ENUM_TIMEFRAMES timeframe)
  {
   datetime current_bar_time = iTime(_Symbol, timeframe, 0); 
   if(current_bar_time != last_bar_time)
     {
      last_bar_time = current_bar_time;
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//| Funzione per aprire una posizione LONG                           |
//+------------------------------------------------------------------+
void OpenLongPosition()
  {
   MqlTick tick;
   SymbolInfoTick(_Symbol, tick);
   
   double stop_loss = NormalizeDouble(tick.bid - Inp_StopLoss_Points * _Point, _Digits);
   double take_profit = NormalizeDouble(tick.bid + Inp_TakeProfit_Points * _Point, _Digits);
   
   if(!trade.Buy(Inp_Lots, _Symbol, tick.ask, stop_loss, take_profit))
     {
      Print("Errore nell'apertura di una posizione LONG. Errore: ", GetLastError());
     }
  }
//+------------------------------------------------------------------+
//| Funzione per aprire una posizione SHORT                          |
//+------------------------------------------------------------------+
void OpenShortPosition()
  {
   MqlTick tick;
   SymbolInfoTick(_Symbol, tick);
   
   double stop_loss = NormalizeDouble(tick.ask + Inp_StopLoss_Points * _Point, _Digits);
   double take_profit = NormalizeDouble(tick.ask - Inp_TakeProfit_Points * _Point, _Digits);
   
   if(!trade.Sell(Inp_Lots, _Symbol, tick.bid, stop_loss, take_profit))
     {
      Print("Errore nell'apertura di una posizione SHORT. Errore: ", GetLastError());
     }
  }
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//--- Questa funzione si attiva ad ogni evento di trading
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
//---
  }
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=0.0;
//---

//---
   return(ret);
  }
//+------------------------------------------------------------------+
//| TesterInit function                                              |
//+------------------------------------------------------------------+
void OnTesterInit()
  {
//---
  }
//+------------------------------------------------------------------+
//| TesterPass function                                              |
//+------------------------------------------------------------------+
void OnTesterPass()
  {
//---
  }
//+------------------------------------------------------------------+
//| TesterDeinit function                                            |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
//---
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int32_t id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
//---
  }
//+------------------------------------------------------------------+