MQL5 EA Wizard ON STEROIDS!

 

I am currently testing new and improved versions of standard indicators in the Wizard and I'm getting much better EAs. If you have improved versions, please share here so we can collectively benefit. I think it'd be better showing the code instead of attaching a file. This way we can discuss it and share ideas. I'll start with an advanced version of Signals of MA:

HOW TO INSTALL: copy and paste in a new mqh file inside the Include/Expert/Signal folder. DO NOT REPLACE ANY FILE! This one you can name it SignalsMA2.mqh. Then you close and reopen the editor and voilà. The new signal appears in the menu.

//+------------------------------------------------------------------+
//|                                                     SignalMA.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of indicator 'Moving Average Advanced'             |
//| Type=SignalAdvanced                                              |
//| Name=Moving Average                                              |
//| ShortName=MA                                                     |
//| Class=CSignalMA                                                  |
//| Page=signal_ma                                                   |
//| Parameter=PeriodMA,int,12,Period of averaging                    |
//| Parameter=Shift,int,0,Time shift                                 |
//| Parameter=Method,ENUM_MA_METHOD,MODE_SMA,Method of averaging     |
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series   |
//| Parameter=MinSlope,double,0.0001,Minimum MA slope to signal      |
//| Parameter=MinDistance,double,0.0002,Minimum price–MA gap to signal|
//| Parameter=Pattern_0,int,80,Weight for model 0 (price on side)    |
//| Parameter=Pattern_1,int,10,Weight for model 1 (cross opposite)   |
//| Parameter=Pattern_2,int,60,Weight for model 2 (cross same)       |
//| Parameter=Pattern_3,int,60,Weight for model 3 (piercing)         |
//| Parameter=Pattern_4,int,30,Weight for model 4 (Touch & Bounce)   |
//| Parameter=Pattern_5,int,30,Weight for model 5 (2‑bar Pullback)   |
//| Parameter=Pattern_6,int,40,Weight for model 6 (Engulfing)        |
//| Parameter=Pattern_7,int,50,Weight for model 7 (Steep Slope)      |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSignalMA.                                                 |
//| Moving Average signal generator con pesi e pattern personalizzati.|
//+------------------------------------------------------------------+
class CSignalMA : public CExpertSignal
  {
protected:
   CiMA               m_ma;             // indicator
   //--- MA settings
   int                m_ma_period;
   int                m_ma_shift;
   ENUM_MA_METHOD     m_ma_method;
   ENUM_APPLIED_PRICE m_ma_applied;
   //--- pattern weights
   int                m_pattern_0;
   int                m_pattern_1;
   int                m_pattern_2;
   int                m_pattern_3;
   int                m_pattern_4;
   int                m_pattern_5;
   int                m_pattern_6;
   int                m_pattern_7;
   //--- noise filters
   double             m_minSlope;
   double             m_minDistance;

public:
                       CSignalMA(void);
                      ~CSignalMA(void);
   //--- MA setters
   void                PeriodMA(int               v){ m_ma_period=v;      }
   void                Shift(int                v){ m_ma_shift=v;       }
   void                Method(ENUM_MA_METHOD    v){ m_ma_method=v;      }
   void                Applied(ENUM_APPLIED_PRICE v){ m_ma_applied=v;   }
   //--- pattern setters
   void                Pattern_0(int            v){ m_pattern_0=v;      }
   void                Pattern_1(int            v){ m_pattern_1=v;      }
   void                Pattern_2(int            v){ m_pattern_2=v;      }
   void                Pattern_3(int            v){ m_pattern_3=v;      }
   void                Pattern_4(int            v){ m_pattern_4=v;      }
   void                Pattern_5(int            v){ m_pattern_5=v;      }
   void                Pattern_6(int            v){ m_pattern_6=v;      }
   void                Pattern_7(int            v){ m_pattern_7=v;      }
   //--- filter setters
   void                MinSlope(double        v){ m_minSlope=v;       }
   void                MinDistance(double     v){ m_minDistance=v;    }

   //--- overrides
   virtual bool        ValidationSettings(void);
   virtual bool        InitIndicators(CIndicators *indicators);
   virtual int         LongCondition(void);
   virtual int         ShortCondition(void);

protected:
   bool                InitMA(CIndicators *indicators);
   double              MA(int ind)           { return m_ma.Main(ind);           }
   double              DiffMA(int ind)       { return MA(ind)-MA(ind+1);        }
   double              DiffCloseMA(int ind)  { return Close(ind)-MA(ind);       }
   double              DiffOpenMA(int ind)   { return Open(ind)-MA(ind);        }
   double              DiffHighMA(int ind)   { return High(ind)-MA(ind);        }
   double              DiffLowMA(int ind)    { return Low(ind)-MA(ind);         }
  };

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSignalMA::CSignalMA(void)
 : m_ma_period(12),
   m_ma_shift(0),
   m_ma_method(MODE_SMA),
   m_ma_applied(PRICE_CLOSE),
   m_pattern_0(80),
   m_pattern_1(10),
   m_pattern_2(60),
   m_pattern_3(60),
   m_pattern_4(30),
   m_pattern_5(30),
   m_pattern_6(40),
   m_pattern_7(50),
   m_minSlope(0.0001),
   m_minDistance(0.0002)
  {
   m_used_series = USE_SERIES_OPEN|USE_SERIES_HIGH|USE_SERIES_LOW|USE_SERIES_CLOSE;
  }

//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CSignalMA::~CSignalMA(void) {}

//+------------------------------------------------------------------+
//| Validate settings                                               |
//+------------------------------------------------------------------+
bool CSignalMA::ValidationSettings(void)
  {
   if(!CExpertSignal::ValidationSettings()) return(false);
   if(m_ma_period <= 0)
     { printf(__FUNCTION__+": MA period must be > 0"); return(false); }
   if(m_minSlope   <= 0.0)
     { printf(__FUNCTION__+": MinSlope must be > 0");     return(false); }
   if(m_minDistance<= 0.0)
     { printf(__FUNCTION__+": MinDistance must be > 0");  return(false); }
   // all patterns must be in [0..100]
   int pats[8] = {m_pattern_0,m_pattern_1,m_pattern_2,m_pattern_3,
                  m_pattern_4,m_pattern_5,m_pattern_6,m_pattern_7};
   for(int i=0; i<8; i++)
     if(pats[i]<0 || pats[i]>100)
       {
        printf(__FUNCTION__+": Pattern_%d out of range [0..100]",i);
        return(false);
       }
   return(true);
  }

//+------------------------------------------------------------------+
//| Initialize indicators                                           |
//+------------------------------------------------------------------+
bool CSignalMA::InitIndicators(CIndicators *indicators)
  {
   if(!CExpertSignal::InitIndicators(indicators)) return(false);
   return InitMA(indicators);
  }

//+------------------------------------------------------------------+
//| Initialize MA                                                   |
//+------------------------------------------------------------------+
bool CSignalMA::InitMA(CIndicators *indicators)
  {
   if(!indicators || !indicators.Add(GetPointer(m_ma)))
     { printf(__FUNCTION__+": error adding MA"); return(false); }
   if(!m_ma.Create(m_symbol.Name(), m_period,
                   m_ma_period, m_ma_shift,
                   m_ma_method, m_ma_applied))
     { printf(__FUNCTION__+": error creating MA"); return(false); }
   return true;
  }

//+------------------------------------------------------------------+
//| LongCondition                                                   |
//+------------------------------------------------------------------+
int CSignalMA::LongCondition(void)
  {
   int result = 0, idx = StartIndex();
   // --- noise filters
   if(fabs(DiffMA(idx)) < m_minSlope)      return(0);
   if(fabs(DiffCloseMA(idx)) < m_minDistance) return(0);
   // --- original patterns
   if(DiffCloseMA(idx) < 0.0)
     {
      if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx) > 0.0 && DiffMA(idx) > 0.0)
        { result = m_pattern_1; m_base_price = 0.0; }
     }
   else
     {
      if(IS_PATTERN_USAGE(0)) result = m_pattern_0;
      if(DiffMA(idx)>0.0)
        {
         if(DiffOpenMA(idx)<0.0 && IS_PATTERN_USAGE(2))
           { result = m_pattern_2; m_base_price = m_symbol.NormalizePrice(MA(idx)); }
         else if(DiffLowMA(idx)<0.0 && IS_PATTERN_USAGE(3))
           { result = m_pattern_3; m_base_price = 0.0; }
        }
     }
   // --- custom patterns (if ancora zero)
   if(result==0 && IS_PATTERN_USAGE(4) && Low(idx) <= MA(idx) && Close(idx+1) > MA(idx+1))
     { result = m_pattern_4; m_base_price = 0.0; }
   if(result==0 && IS_PATTERN_USAGE(5)
       && Close(idx+2)>MA(idx+2)
       && Close(idx+1)<MA(idx+1)
       && Close(idx)  >MA(idx))
     { result = m_pattern_5; m_base_price = m_symbol.NormalizePrice(MA(idx)); }
   bool bullishEngulf = Open(idx+1)>Close(idx+1)
                     && Open(idx)  <Close(idx)
                     && Close(idx) >Open(idx+1)
                     && Open(idx)  <Close(idx+1);
   if(result==0 && IS_PATTERN_USAGE(6) && bullishEngulf && DiffCloseMA(idx)<0.0)
     { result = m_pattern_6; m_base_price = 0.0; }
   double slope = (MA(idx)-MA(idx+5)) / 5.0;
   if(result==0 && IS_PATTERN_USAGE(7) && slope > m_minSlope*2)
     { result = m_pattern_7; m_base_price = 0.0; }

   return result;
  }

//+------------------------------------------------------------------+
//| ShortCondition                                                  |
//+------------------------------------------------------------------+
int CSignalMA::ShortCondition(void)
  {
   int result = 0, idx = StartIndex();
   // --- noise filters
   if(fabs(DiffMA(idx)) < m_minSlope)      return(0);
   if(fabs(DiffCloseMA(idx)) < m_minDistance) return(0);
   // --- original patterns
   if(DiffCloseMA(idx) > 0.0)
     {
      if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
        { result = m_pattern_1; m_base_price = 0.0; }
     }
   else
     {
      if(IS_PATTERN_USAGE(0)) result = m_pattern_0;
      if(DiffMA(idx)<0.0)
        {
         if(DiffOpenMA(idx)>0.0 && IS_PATTERN_USAGE(2))
           { result = m_pattern_2; m_base_price = m_symbol.NormalizePrice(MA(idx)); }
         else if(DiffHighMA(idx)>0.0 && IS_PATTERN_USAGE(3))
           { result = m_pattern_3; m_base_price = 0.0; }
        }
     }
   // --- custom patterns
   if(result==0 && IS_PATTERN_USAGE(4) && High(idx) >= MA(idx) && Close(idx+1) < MA(idx+1))
     { result = m_pattern_4; m_base_price = 0.0; }
   if(result==0 && IS_PATTERN_USAGE(5)
       && Close(idx+2)<MA(idx+2)
       && Close(idx+1)>MA(idx+1)
       && Close(idx)  <MA(idx))
     { result = m_pattern_5; m_base_price = m_symbol.NormalizePrice(MA(idx)); }
   bool bearishEngulf = Open(idx+1)<Close(idx+1)
                     && Open(idx)  >Close(idx)
                     && Close(idx) <Open(idx+1)
                     && Open(idx)  >Close(idx+1);
   if(result==0 && IS_PATTERN_USAGE(6) && bearishEngulf && DiffCloseMA(idx)>0.0)
     { result = m_pattern_6; m_base_price = 0.0; }
   double slopeS = (MA(idx)-MA(idx+5)) / 5.0;
   if(result==0 && IS_PATTERN_USAGE(7) && slopeS < -m_minSlope*2)
     { result = m_pattern_7; m_base_price = 0.0; }

   return result;
  }
//+------------------------------------------------------------------+