MT5 EA ExpertMAMA.mq5

 

Hello,

I am running this ExpertMAMA and it is showing small but generally consistent profits.  It is a quite complex code but has been around at least since 2011.  The issue I am having is that every now and then it shows a large loss and when I review the code I could not figure out how to implement a stoploss (e.g. 10 points stoploss).  Has anyone used this with stoplosses?  Any ideas how to do so?  I attach the initial file that is called: Expert.mqh which references a stoploss but it is not clear to me how to fix a value.  By the way, if you want to play with it I can send you the main file and the remaining mqh files.  Again the performance results for June 2019-current day on S&P futures (even with the periodic big losses) is impressive!!


/+------------------------------------------------------------------+
//|                                                       Expert.mqh |
//|                   Copyright 2009-2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ExpertBase.mqh"
#include "ExpertTrade.mqh"
#include "ExpertSignal.mqh"
#include "ExpertMoney.mqh"
#include "ExpertTrailing.mqh"
//+------------------------------------------------------------------+
//| enumerations                                                     |
//+------------------------------------------------------------------+
//--- flags of expected events
enum ENUM_TRADE_EVENTS
  {
   TRADE_EVENT_NO_EVENT              =0,         // no expected events
   TRADE_EVENT_POSITION_OPEN         =0x1,       // flag of expecting the "opening of position" event
   TRADE_EVENT_POSITION_VOLUME_CHANGE=0x2,       // flag of expecting of the "modification of position volume" event
   TRADE_EVENT_POSITION_MODIFY       =0x4,       // flag of expecting of the "modification of stop order of position" event
   TRADE_EVENT_POSITION_CLOSE        =0x8,       // flag of expecting of the "closing of position" event
   TRADE_EVENT_POSITION_STOP_TAKE    =0x10,      // flag of expecting of the "triggering of stop order of position"
   TRADE_EVENT_ORDER_PLACE           =0x20,      // flag of expecting of the "placing of pending order" event
   TRADE_EVENT_ORDER_MODIFY          =0x40,      // flag of expecting of the "modification of pending order" event
   TRADE_EVENT_ORDER_DELETE          =0x80,      // flag of expecting of the "deletion of pending order" event
   TRADE_EVENT_ORDER_TRIGGER         =0x100      // flag of expecting of the "triggering of pending order" event
  };
//+------------------------------------------------------------------+
//| Macro definitions.                                               |
//+------------------------------------------------------------------+
//--- check the expectation of event
#define IS_WAITING_POSITION_OPENED         ((m_waiting_event&TRADE_EVENT_POSITION_OPEN)!=0)
#define IS_WAITING_POSITION_VOLUME_CHANGED ((m_waiting_event&TRADE_EVENT_POSITION_VOLUME_CHANGE)!=0)
#define IS_WAITING_POSITION_MODIFIED       ((m_waiting_event&TRADE_EVENT_POSITION_MODIFY)!=0)
#define IS_WAITING_POSITION_CLOSED         ((m_waiting_event&TRADE_EVENT_POSITION_CLOSE)!=0)
#define IS_WAITING_POSITION_STOP_TAKE      ((m_waiting_event&TRADE_EVENT_POSITION_STOP_TAKE)!=0)
#define IS_WAITING_ORDER_PLACED            ((m_waiting_event&TRADE_EVENT_ORDER_PLACE)!=0)
#define IS_WAITING_ORDER_MODIFIED          ((m_waiting_event&TRADE_EVENT_ORDER_MODIFY)!=0)
#define IS_WAITING_ORDER_DELETED           ((m_waiting_event&TRADE_EVENT_ORDER_DELETE)!=0)
#define IS_WAITING_ORDER_TRIGGERED         ((m_waiting_event&TRADE_EVENT_ORDER_TRIGGER)!=0)
//+------------------------------------------------------------------+
//| Class CExpert.                                                   |
//| Purpose: Base class expert advisor.                              |
//| Derives from class CExpertBase.                                  |
//+------------------------------------------------------------------+
class CExpert : public CExpertBase
  {
protected:
   int               m_period_flags;             // timeframe flags (as visible flags)
   int               m_max_orders;               // max number of orders (include position)
   MqlDateTime       m_last_tick_time;           // time of last tick
   datetime          m_expiration;               // time expiration order
   //--- history info
   int               m_pos_tot;                  // number of open positions
   int               m_deal_tot;                 // number of deals in history
   int               m_ord_tot;                  // number of pending orders
   int               m_hist_ord_tot;             // number of orders in history
   datetime          m_beg_date;                 // start date of history
   //---
   int               m_waiting_event;            // flags of expected trade events
   //--- trading objects
   CExpertTrade     *m_trade;                    // trading object
   CExpertSignal    *m_signal;                   // trading signals object
   CExpertMoney     *m_money;                    // money manager object
   CExpertTrailing  *m_trailing;                 // trailing stops object
   bool              m_check_volume;             // check and decrease trading volume before OrderSend
   //--- indicators
   CIndicators       m_indicators;               // indicator collection to fast recalculations
   //--- market objects
   CPositionInfo     m_position;                 // position info object
   COrderInfo        m_order;                    // order info object
   //--- flags of handlers
   bool              m_on_tick_process;          // OnTick will be processed       (default true)
   bool              m_on_trade_process;         // OnTrade will be processed      (default false)
   bool              m_on_timer_process;         // OnTimer will be processed      (default false)
   bool              m_on_chart_event_process;   // OnChartEvent will be processed (default false)
   bool              m_on_book_event_process;    // OnBookEvent will be processed  (default false)

public:
                     CExpert(void);
                    ~CExpert(void);
   //--- initialization
   bool              Init(string symbol,ENUM_TIMEFRAMES period,bool every_tick,ulong magic=0);
   void              Magic(ulong value);
   void              CheckVolumeBeforeTrade(const bool flag) { m_check_volume=flag; }
   //--- initialization trading objects
   virtual bool      InitSignal(CExpertSignal *signal=NULL);
   virtual bool      InitTrailing(CExpertTrailing *trailing=NULL);
   virtual bool      InitMoney(CExpertMoney *money=NULL);
   virtual bool      InitTrade(ulong magic,CExpertTrade *trade=NULL);
   //--- deinitialization
   virtual void      Deinit(void);
   //--- methods of setting adjustable parameters
   void              OnTickProcess(bool value)              { m_on_tick_process=value;        }
   void              OnTradeProcess(bool value)             { m_on_trade_process=value;       }
   void              OnTimerProcess(bool value)             { m_on_timer_process=value;       }
   void              OnChartEventProcess(bool value)        { m_on_chart_event_process=value; }
   void              OnBookEventProcess(bool value)         { m_on_book_event_process=value;  }
   int               MaxOrders(void)                  const { return(m_max_orders);           }
   void              MaxOrders(int value)                   { m_max_orders=value;             }
   //--- methods of access to protected data
   CExpertSignal    *Signal(void)                     const { return(m_signal);               }
   //--- method of verification of settings
   virtual bool      ValidationSettings();
   //--- method of creating the indicator and timeseries
   virtual bool      InitIndicators(CIndicators *indicators=NULL);
   //--- event handlers
   virtual void      OnTick(void);
   virtual void      OnTrade(void);
   virtual void      OnTimer(void);
   virtual void      OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
   virtual void      OnBookEvent(const string &symbol);

protected:
   //--- initialization
   virtual bool      InitParameters(void) { return(true); }
   //--- deinitialization
   virtual void      DeinitTrade(void);
   virtual void      DeinitSignal(void);
   virtual void      DeinitTrailing(void);
   virtual void      DeinitMoney(void);
   virtual void      DeinitIndicators(void);
   //--- refreshing 
   virtual bool      Refresh(void);
   //--- position select depending on netting or hedging
   virtual bool      SelectPosition(void);
   //--- processing (main method)
   virtual bool      Processing(void);
   //--- trade open positions check
   virtual bool      CheckOpen(void);
   virtual bool      CheckOpenLong(void);
   virtual bool      CheckOpenShort(void);
   //--- trade open positions processing
   virtual bool      OpenLong(double price,double sl,double tp);
   virtual bool      OpenShort(double price,double sl,double tp);
   //--- trade reverse positions check
   virtual bool      CheckReverse(void);
   virtual bool      CheckReverseLong(void);
   virtual bool      CheckReverseShort(void);
   //--- trade reverse positions processing
   virtual bool      ReverseLong(double price,double sl,double tp);
   virtual bool      ReverseShort(double price,double sl,double tp);
   //--- trade close positions check
   virtual bool      CheckClose(void);
   virtual bool      CheckCloseLong(void);
   virtual bool      CheckCloseShort(void);
   //--- trade close positions processing
   virtual bool      CloseAll(double lot);
   virtual bool      Close(void);
   virtual bool      CloseLong(double price);
   virtual bool      CloseShort(double price);
   //--- trailing stop check
   virtual bool      CheckTrailingStop(void);
   virtual bool      CheckTrailingStopLong(void);
   virtual bool      CheckTrailingStopShort(void);
   //--- trailing stop processing
   virtual bool      TrailingStopLong(double sl,double tp);
   virtual bool      TrailingStopShort(double sl,double tp);
   //--- trailing order check
   virtual bool      CheckTrailingOrderLong(void);
   virtual bool      CheckTrailingOrderShort(void);
   //--- trailing order processing
   virtual bool      TrailingOrderLong(double delta);
   virtual bool      TrailingOrderShort(double delta);
   //--- delete order check
   virtual bool      CheckDeleteOrderLong(void);
   virtual bool      CheckDeleteOrderShort(void);
   //--- delete order processing
   virtual bool      DeleteOrders(void);
   virtual bool      DeleteOrdersLong(void);
   virtual bool      DeleteOrdersShort(void);
   virtual bool      DeleteOrder(void);
   virtual bool      DeleteOrderLong(void);
   virtual bool      DeleteOrderShort(void);
   //--- lot for trade
   double            LotOpenLong(double price,double sl);
   double            LotOpenShort(double price,double sl);
   double            LotReverse(double sl);
   double            LotCheck(double volume,double price,ENUM_ORDER_TYPE order_type);
   //--- methods of working with trade history
   void              PrepareHistoryDate(void);
   void              HistoryPoint(bool from_check_trade=false);
   bool              CheckTradeState(void);
   //--- set/reset waiting events
   void              WaitEvent(ENUM_TRADE_EVENTS event)     { m_waiting_event|=event;  }
   void              NoWaitEvent(ENUM_TRADE_EVENTS event)   { m_waiting_event&=~event; }
   //--- trade events
   virtual bool      TradeEventPositionStopTake(void)       { return(true); }
   virtual bool      TradeEventOrderTriggered(void)         { return(true); }
   virtual bool      TradeEventPositionOpened(void)         { return(true); }
   virtual bool      TradeEventPositionVolumeChanged(void)  { return(true); }
   virtual bool      TradeEventPositionModified(void)       { return(true); }
   virtual bool      TradeEventPositionClosed(void)         { return(true); }
   virtual bool      TradeEventOrderPlaced(void)            { return(true); }
   virtual bool      TradeEventOrderModified(void)          { return(true); }
   virtual bool      TradeEventOrderDeleted(void)           { return(true); }
   virtual bool      TradeEventNotIdentified(void)          { return(true); }
   //--- timeframe functions
   void              TimeframeAdd(ENUM_TIMEFRAMES period);
   int               TimeframesFlags(MqlDateTime &time);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CExpert::CExpert(void) : m_period_flags(0),
                         m_expiration(0),
                         m_pos_tot(0),
                         m_deal_tot(0),
                         m_ord_tot(0),
                         m_hist_ord_tot(0),
                         m_beg_date(0),
                         m_trade(NULL),
                         m_signal(NULL),
                         m_money(NULL),
                         m_trailing(NULL),
                         m_check_volume(false),
                         m_on_tick_process(true),
                         m_on_trade_process(false),
                         m_on_timer_process(false),
                         m_on_chart_event_process(false),
                         m_on_book_event_process(false),
                         m_max_orders(1)
  {
   m_other_symbol      =true;
   m_other_period      =true;
   m_adjusted_point    =10;
   m_period            =WRONG_VALUE;
   m_last_tick_time.min=-1;
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CExpert::~CExpert(void)
  {
   Deinit();
  }
//+------------------------------------------------------------------+
//| Initialization and checking for input parameters                 |
//+------------------------------------------------------------------+
bool CExpert::Init(string symbol,ENUM_TIMEFRAMES period,bool every_tick,ulong magic)
  {
//--- returns false if the EA is initialized on a symbol/timeframe different from the current one
   if(symbol!=Symbol() || period!=Period())
     {
      PrintFormat(__FUNCTION__+": wrong symbol or timeframe (must be %s:%s)",symbol,EnumToString(period));
      return(false);
     }
//--- initialize common information
   if(m_symbol==NULL)
     {
      if((m_symbol=new CSymbolInfo)==NULL)
         return(false);
     }
   if(!m_symbol.Name(symbol))
      return(false);
   m_period    =period;
   m_every_tick=every_tick;
   m_magic     =magic;
   SetMarginMode();
   if(every_tick)
      TimeframeAdd(WRONG_VALUE);            // add all periods
   else
      TimeframeAdd(period);                 // add specified period
//--- tuning for 3 or 5 digits
   int digits_adjust=(m_symbol.Digits()==3 || m_symbol.Digits()==5) ? 10 : 1;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- initializing objects expert
   if(!InitTrade(magic))
     {
      Print(__FUNCTION__+": error initialization trade object");
      return(false);
     }
   if(!InitSignal())
     {
      Print(__FUNCTION__+": error initialization signal object");
      return(false);
     }
   if(!InitTrailing())
     {
      Print(__FUNCTION__+": error initialization trailing object");
      return(false);
     }
   if(!InitMoney())
     {
      Print(__FUNCTION__+": error initialization money object");
      return(false);
     }
   if(!InitParameters())
     {
      Print(__FUNCTION__+": error initialization parameters");
      return(false);
     }
//--- initialization for working with trade history
   PrepareHistoryDate();
   HistoryPoint();
//--- primary initialization is successful, pass to the phase of tuning
   m_init_phase=INIT_PHASE_TUNING;
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Sets magic number for object and its dependent objects           |
//+------------------------------------------------------------------+
void CExpert::Magic(ulong value)
  {
   if(m_trade!=NULL)
      m_trade.SetExpertMagicNumber(value);
   if(m_signal!=NULL)
      m_signal.Magic(value);
   if(m_money!=NULL)
      m_money.Magic(value);
   if(m_trailing!=NULL)
      m_trailing.Magic(value);
//---
   CExpertBase::Magic(value);
  }
//+------------------------------------------------------------------+
//| Initialization trade object                                      |
//+------------------------------------------------------------------+
bool CExpert::InitTrade(ulong magic,CExpertTrade *trade=NULL)
  {
//--- óäàëÿåì ñóùåñòâóþùèé îáúåêò
   if(m_trade!=NULL)
      delete m_trade;
//---
   if(trade==NULL)
     {
      if((m_trade=new CExpertTrade)==NULL)
         return(false);
     }
   else
      m_trade=trade;
//--- tune trade object
   m_trade.SetSymbol(GetPointer(m_symbol));
   m_trade.SetExpertMagicNumber(magic);
   m_trade.SetMarginMode();
//--- set default deviation for trading in adjusted points
   m_trade.SetDeviationInPoints((ulong)(3*m_adjusted_point/m_symbol.Point()));
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization signal object                                     |
//+------------------------------------------------------------------+
bool CExpert::InitSignal(CExpertSignal *signal)
  {
   if(m_signal!=NULL)
      delete m_signal;
//---
   if(signal==NULL)
     {
      if((m_signal=new CExpertSignal)==NULL)
         return(false);
     }
   else
      m_signal=signal;
//--- initializing signal object
   if(!m_signal.Init(GetPointer(m_symbol),m_period,m_adjusted_point))
      return(false);
   m_signal.EveryTick(m_every_tick);
   m_signal.Magic(m_magic);
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization trailing object                                   |
//+------------------------------------------------------------------+
bool CExpert::InitTrailing(CExpertTrailing *trailing)
  {
   if(m_trailing!=NULL)
      delete m_trailing;
//---
   if(trailing==NULL)
     {
      if((m_trailing=new CExpertTrailing)==NULL)
         return(false);
     }
   else
      m_trailing=trailing;
//--- initializing trailing object
   if(!m_trailing.Init(GetPointer(m_symbol),m_period,m_adjusted_point))
      return(false);
   m_trailing.EveryTick(m_every_tick);
   m_trailing.Magic(m_magic);
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization money object                                      |
//+------------------------------------------------------------------+
bool CExpert::InitMoney(CExpertMoney *money)
  {
   if(m_money!=NULL)
      delete m_money;
//---
   if(money==NULL)
     {
      if((m_money=new CExpertMoney)==NULL)
         return(false);
     }
   else
      m_money=money;
//--- initializing money object
   if(!m_money.Init(GetPointer(m_symbol),m_period,m_adjusted_point))
      return(false);
   m_money.EveryTick(m_every_tick);
   m_money.Magic(m_magic);
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Validation settings                                              |
//+------------------------------------------------------------------+
bool CExpert::ValidationSettings(void)
  {
   if(!CExpertBase::ValidationSettings())
      return(false);
//--- Check signal parameters
   if(!m_signal.ValidationSettings())
     {
      Print(__FUNCTION__+": error signal parameters");
      return(false);
     }
//--- Check trailing parameters
   if(!m_trailing.ValidationSettings())
     {
      Print(__FUNCTION__+": error trailing parameters");
      return(false);
     }
//--- Check money parameters
   if(!m_money.ValidationSettings())
     {
      Print(__FUNCTION__+": error money parameters");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization indicators                                        |
//+------------------------------------------------------------------+
bool CExpert::InitIndicators(CIndicators *indicators)
  {
//--- NULL always comes as the parameter, but here it's not significant for us
   CIndicators *indicators_ptr=GetPointer(m_indicators);
//--- gather information about using of timeseries
   m_used_series|=m_signal.UsedSeries();
   m_used_series|=m_trailing.UsedSeries();
   m_used_series|=m_money.UsedSeries();
//--- create required timeseries
   if(!CExpertBase::InitIndicators(indicators_ptr))
      return(false);
   m_signal.SetPriceSeries(m_open,m_high,m_low,m_close);
   m_signal.SetOtherSeries(m_spread,m_time,m_tick_volume,m_real_volume);
   if(!m_signal.InitIndicators(indicators_ptr))
     {
      Print(__FUNCTION__+": error initialization indicators of signal object");
      return(false);
     }
   m_trailing.SetPriceSeries(m_open,m_high,m_low,m_close);
   m_trailing.SetOtherSeries(m_spread,m_time,m_tick_volume,m_real_volume);
   if(!m_trailing.InitIndicators(indicators_ptr))
     {
      Print(__FUNCTION__+": error initialization indicators of trailing object");
      return(false);
     }
   m_money.SetPriceSeries(m_open,m_high,m_low,m_close);
   m_money.SetOtherSeries(m_spread,m_time,m_tick_volume,m_real_volume);
   if(!m_money.InitIndicators(indicators_ptr))
     {
      Print(__FUNCTION__+": error initialization indicators of money object");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Deinitialization expert                                          |
//+------------------------------------------------------------------+
void CExpert::Deinit(void)
  {
//--- delete trade class
   DeinitTrade();
//--- delete signal class
   DeinitSignal();
//--- delete trailing class
   DeinitTrailing();
//--- delete money class
   DeinitMoney();
//--- delete indicators collection
   DeinitIndicators();
  }
//+------------------------------------------------------------------+
//| Deinitialization trade object                                    |
//+------------------------------------------------------------------+
void CExpert::DeinitTrade(void)
  {
   if(m_trade!=NULL)
     {
      delete m_trade;
      m_trade=NULL;
     }
  }
//+------------------------------------------------------------------+
//| Deinitialization signal object                                   |
//+------------------------------------------------------------------+
void CExpert::DeinitSignal(void)
  {
   if(m_signal!=NULL)
     {
      delete m_signal;
      m_signal=NULL;
     }
  }
//+------------------------------------------------------------------+
//| Deinitialization trailing object                                 |
//+------------------------------------------------------------------+
void CExpert::DeinitTrailing(void)
  {
   if(m_trailing!=NULL)
     {
      delete m_trailing;
      m_trailing=NULL;
     }
  }
//+------------------------------------------------------------------+
//| Deinitialization money object                                    |
//+------------------------------------------------------------------+
void CExpert::DeinitMoney(void)
  {
   if(m_money!=NULL)
     {
      delete m_money;
      m_money=NULL;
     }
  }
//+------------------------------------------------------------------+
//| Deinitialization indicators                                      |
//+------------------------------------------------------------------+
void CExpert::DeinitIndicators(void)
  {
   m_indicators.Clear();
  }
//+------------------------------------------------------------------+
//| Refreshing data for processing                                   |
//+------------------------------------------------------------------+
bool CExpert::Refresh(void)
  {
   MqlDateTime time;
//--- refresh rates
   if(!m_symbol.RefreshRates())
      return(false);
//--- check need processing
   TimeToStruct(m_symbol.Time(),time);
   if(m_period_flags!=WRONG_VALUE && m_period_flags!=0)
      if((m_period_flags&TimeframesFlags(time))==0)
         return(false);
   m_last_tick_time=time;
//--- refresh indicators
   m_indicators.Refresh();
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Position select depending on netting or hedging                  |
//+------------------------------------------------------------------+
bool CExpert::SelectPosition(void)
  {
   bool res=false;
//---
   if(IsHedging())
      res=m_position.SelectByMagic(m_symbol.Name(),m_magic);
   else
      res=m_position.Select(m_symbol.Name());
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| Main function                                                    |
//+------------------------------------------------------------------+
bool CExpert::Processing(void)
  {
//--- calculate signal direction once
   m_signal.SetDirection();
//--- check if open positions
   if(SelectPosition())
     {
      //--- open position is available
      //--- check the possibility of reverse the position
      if(CheckReverse())
         return(true);
      //--- check the possibility of closing the position/delete pending orders
      if(!CheckClose())
        {
         //--- check the possibility of modifying the position
         if(CheckTrailingStop())
            return(true);
         //--- return without operations
         return(false);
        }
     }
//--- check if plased pending orders
   int total=OrdersTotal();
   if(total!=0)
     {
      for(int i=total-1; i>=0; i--)
        {
         m_order.SelectByIndex(i);
         if(m_order.Symbol()!=m_symbol.Name())
            continue;
         if(m_order.OrderType()==ORDER_TYPE_BUY_LIMIT || m_order.OrderType()==ORDER_TYPE_BUY_STOP)
           {
            //--- check the ability to delete a pending order to buy
            if(CheckDeleteOrderLong())
               return(true);
            //--- check the possibility of modifying a pending order to buy
            if(CheckTrailingOrderLong())
               return(true);
           }
         else
           {
            //--- check the ability to delete a pending order to sell
            if(CheckDeleteOrderShort())
               return(true);
            //--- check the possibility of modifying a pending order to sell
            if(CheckTrailingOrderShort())
               return(true);
           }
         //--- return without operations
         return(false);
        }
     }
//--- check the possibility of opening a position/setting pending order
   if(CheckOpen())
      return(true);
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| OnTick handler                                                   |
//+------------------------------------------------------------------+
void CExpert::OnTick(void)
  {
//--- check process flag
   if(!m_on_tick_process)
      return;
//--- updated quotes and indicators
   if(!Refresh())
      return;
//--- expert processing
   Processing();
  }
//+------------------------------------------------------------------+
//| OnTrade handler                                                  |
//+------------------------------------------------------------------+
void CExpert::OnTrade(void)
  {
//--- check process flag
   if(!m_on_trade_process)
      return;
   CheckTradeState();
  }
//+------------------------------------------------------------------+
//| OnTimer handler                                                  |
//+------------------------------------------------------------------+
void CExpert::OnTimer(void)
  {
//--- check process flag
   if(!m_on_timer_process)
      return;
  }
//+------------------------------------------------------------------+
//| OnChartEvent handler                                             |
//+------------------------------------------------------------------+
void CExpert::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- check process flag
   if(!m_on_chart_event_process)
      return;
  }
//+------------------------------------------------------------------+
//| OnBookEvent handler                                              |
//+------------------------------------------------------------------+
void CExpert::OnBookEvent(const string &symbol)
  {
//--- check process flag
   if(!m_on_book_event_process)
      return;
  }
//+------------------------------------------------------------------+
//| Check for position open or limit/stop order set                  |
//+------------------------------------------------------------------+
bool CExpert::CheckOpen(void)
  {
   if(CheckOpenLong())
      return(true);
   if(CheckOpenShort())
      return(true);
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for long position open or limit/stop order set             |
//+------------------------------------------------------------------+
bool CExpert::CheckOpenLong(void)
  {
   double   price=EMPTY_VALUE;
   double   sl=0.0;
   double   tp=0.0;
   datetime expiration=TimeCurrent();
//--- check signal for long enter operations
   if(m_signal.CheckOpenLong(price,sl,tp,expiration))
     {
      if(!m_trade.SetOrderExpiration(expiration))
         m_expiration=expiration;
      return(OpenLong(price,sl,tp));
     }
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for short position open or limit/stop order set            |
//+------------------------------------------------------------------+
bool CExpert::CheckOpenShort(void)
  {
   double   price=EMPTY_VALUE;
   double   sl=0.0;
   double   tp=0.0;
   datetime expiration=TimeCurrent();
//--- check signal for short enter operations
   if(m_signal.CheckOpenShort(price,sl,tp,expiration))
     {
      if(!m_trade.SetOrderExpiration(expiration))
         m_expiration=expiration;
      return(OpenShort(price,sl,tp));
     }
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Long position open or limit/stop order set                       |
//+------------------------------------------------------------------+
bool CExpert::OpenLong(double price,double sl,double tp)
  {
   if(price==EMPTY_VALUE)
      return(false);
//--- get lot for open
   double lot=LotOpenLong(price,sl);
//--- check lot for open
   lot=LotCheck(lot,price,ORDER_TYPE_BUY);
   if(lot==0.0)
      return(false);
//---
   return(m_trade.Buy(lot,price,sl,tp));
  }
//+------------------------------------------------------------------+
//| Short position open or limit/stop order set                      |
//+------------------------------------------------------------------+
bool CExpert::OpenShort(double price,double sl,double tp)
  {
   if(price==EMPTY_VALUE)
      return(false);
//--- get lot for open
   double lot=LotOpenShort(price,sl);
//--- check lot for open
   lot=LotCheck(lot,price,ORDER_TYPE_SELL);
   if(lot==0.0)
      return(false);
//---
   return(m_trade.Sell(lot,price,sl,tp));
  }
//+------------------------------------------------------------------+
//| Check for position reverse                                       |
//+------------------------------------------------------------------+
bool CExpert::CheckReverse(void)
  {
   if(m_position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of reverse the long position
      if(CheckReverseLong())
         return(true);
     }
   else
     {
      //--- check the possibility of reverse the short position
      if(CheckReverseShort())
         return(true);
     }
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for long position reverse                                  |
//+------------------------------------------------------------------+
bool CExpert::CheckReverseLong(void)
  {
   double   price=EMPTY_VALUE;
   double   sl=0.0;
   double   tp=0.0;
   datetime expiration=TimeCurrent();
//--- check signal for long reverse operations
   if(m_signal.CheckReverseLong(price,sl,tp,expiration))
      return(ReverseLong(price,sl,tp));
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for short position reverse                                 |
//+------------------------------------------------------------------+
bool CExpert::CheckReverseShort(void)
  {
   double   price=EMPTY_VALUE;
   double   sl=0.0;
   double   tp=0.0;
   datetime expiration=TimeCurrent();
//--- check signal for short reverse operations
   if(m_signal.CheckReverseShort(price,sl,tp,expiration))
      return(ReverseShort(price,sl,tp));
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Long position reverse                                            |
//+------------------------------------------------------------------+
bool CExpert::ReverseLong(double price,double sl,double tp)
  {
   if(price==EMPTY_VALUE)
      return(false);
//--- get lot for reverse
   double lot=LotReverse(sl);
//--- check lot
   if(lot==0.0)
      return(false);
//---
   bool result=true;
   if(IsHedging())
     {
      //--- first close existing position
      lot-=m_position.Volume();
      result=m_trade.PositionClose(m_position.Ticket());
     }
   if(result)
     {
      lot=LotCheck(lot,price,ORDER_TYPE_SELL);
      if(lot==0.0)
         result=false;
      else
         result=m_trade.Sell(lot,price,sl,tp);
     }
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Short position reverse                                           |
//+------------------------------------------------------------------+
bool CExpert::ReverseShort(double price,double sl,double tp)
  {
   if(price==EMPTY_VALUE)
      return(false);
//--- get lot for reverse
   double lot=LotReverse(sl);
//--- check lot
   if(lot==0.0)
      return(false);
//---
   bool result=true;
   if(IsHedging())
     {
      //--- first close existing position
      lot-=m_position.Volume();
      result=m_trade.PositionClose(m_position.Ticket());
     }
   if(result)
     {
      lot=LotCheck(lot,price,ORDER_TYPE_BUY);
      if(lot==0.0)
         result=false;
      else
         result=m_trade.Buy(lot,price,sl,tp);
     }
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Check for position close or limit/stop order delete              |
//+------------------------------------------------------------------+
bool CExpert::CheckClose(void)
  {
   double lot;
//--- position must be selected before call
   if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0)
      return(CloseAll(lot));
//--- check for position type
   if(m_position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of closing the long position / delete pending orders to buy
      if(CheckCloseLong())
        {
         DeleteOrdersLong();
         return(true);
        }
     }
   else
     {
      //--- check the possibility of closing the short position / delete pending orders to sell
      if(CheckCloseShort())
        {
         DeleteOrdersShort();
         return(true);
        }
     }
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for long position close or limit/stop order delete         |
//+------------------------------------------------------------------+
bool CExpert::CheckCloseLong(void)
  {
   double price=EMPTY_VALUE;
//--- check for long close operations
   if(m_signal.CheckCloseLong(price))
      return(CloseLong(price));
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for short position close or limit/stop order delete        |
//+------------------------------------------------------------------+
bool CExpert::CheckCloseShort(void)
  {
   double price=EMPTY_VALUE;
//--- check for short close operations
   if(m_signal.CheckCloseShort(price))
      return(CloseShort(price));
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Position close and orders delete                                 |
//+------------------------------------------------------------------+
bool CExpert::CloseAll(double lot)
  {
   bool result=false;
//--- check for close operations
   if(IsHedging())
      result=m_trade.PositionClose(m_position.Ticket());
   else
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
         result=m_trade.Sell(lot,0,0,0);
      else
         result=m_trade.Buy(lot,0,0,0);
     }
   result|=DeleteOrders();
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Position close                                                   |
//+------------------------------------------------------------------+
bool CExpert::Close(void)
  {
   return(m_trade.PositionClose(m_symbol.Name()));
  }
//+------------------------------------------------------------------+
//| Long position close                                              |
//+------------------------------------------------------------------+
bool CExpert::CloseLong(double price)
  {
   bool result=false;
//---
   if(price==EMPTY_VALUE)
      return(false);
   if(IsHedging())
      result=m_trade.PositionClose(m_position.Ticket());
   else
      result=m_trade.Sell(m_position.Volume(),price,0,0);
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Short position close                                             |
//+------------------------------------------------------------------+
bool CExpert::CloseShort(double price)
  {
   bool result=false;
//---
   if(price==EMPTY_VALUE)
      return(false);
   if(IsHedging())
      result=m_trade.PositionClose(m_position.Ticket());
   else
      result=m_trade.Buy(m_position.Volume(),price,0,0);
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Check for trailing stop/profit position                          |
//+------------------------------------------------------------------+
bool CExpert::CheckTrailingStop(void)
  {
//--- position must be selected before call
   if(m_position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of modifying the long position
      if(CheckTrailingStopLong())
         return(true);
     }
   else
     {
      //--- check the possibility of modifying the short position
      if(CheckTrailingStopShort())
         return(true);
     }
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for trailing stop/profit long position                     |
//+------------------------------------------------------------------+
bool CExpert::CheckTrailingStopLong(void)
  {
   double sl=EMPTY_VALUE;
   double tp=EMPTY_VALUE;
//--- check for long trailing stop operations
   if(m_trailing.CheckTrailingStopLong(GetPointer(m_position),sl,tp))
     {
      double position_sl=m_position.StopLoss();
      double position_tp=m_position.TakeProfit();
      if(sl==EMPTY_VALUE)
         sl=position_sl;
      else
         sl=m_symbol.NormalizePrice(sl);
      if(tp==EMPTY_VALUE)
         tp=position_tp;
      else
         tp=m_symbol.NormalizePrice(tp);
      if(sl==position_sl && tp==position_tp)
         return(false);
      //--- long trailing stop operations
      return(TrailingStopLong(sl,tp));
     }
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for trailing stop/profit short position                    |
//+------------------------------------------------------------------+
bool CExpert::CheckTrailingStopShort(void)
  {
   double sl=EMPTY_VALUE;
   double tp=EMPTY_VALUE;
//--- check for short trailing stop operations
   if(m_trailing.CheckTrailingStopShort(GetPointer(m_position),sl,tp))
     {
      double position_sl=m_position.StopLoss();
      double position_tp=m_position.TakeProfit();
      if(sl==EMPTY_VALUE)
         sl=position_sl;
      else
         sl=m_symbol.NormalizePrice(sl);
      if(tp==EMPTY_VALUE)
         tp=position_tp;
      else
         tp=m_symbol.NormalizePrice(tp);
      if(sl==position_sl && tp==position_tp)
         return(false);
      //--- short trailing stop operations
      return(TrailingStopShort(sl,tp));
     }
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Trailing stop/profit long position                               |
//+------------------------------------------------------------------+
bool CExpert::TrailingStopLong(double sl,double tp)
  {
   bool result;
//---
   if(IsHedging())
      result=m_trade.PositionModify(m_position.Ticket(),sl,tp);
   else
      result=m_trade.PositionModify(m_symbol.Name(),sl,tp);
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Trailing stop/profit short position                              |
//+------------------------------------------------------------------+
bool CExpert::TrailingStopShort(double sl,double tp)
  {
   bool result;
//---
   if(IsHedging())
      result=m_trade.PositionModify(m_position.Ticket(),sl,tp);
   else
      result=m_trade.PositionModify(m_symbol.Name(),sl,tp);
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Check for trailing long limit/stop order                         |
//+------------------------------------------------------------------+
bool CExpert::CheckTrailingOrderLong(void)
  {
   double price;
//--- check the possibility of modifying the long order
   if(m_signal.CheckTrailingOrderLong(GetPointer(m_order),price))
      return(TrailingOrderLong(m_order.PriceOpen()-price));
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for trailing short limit/stop order                        |
//+------------------------------------------------------------------+
bool CExpert::CheckTrailingOrderShort(void)
  {
   double price;
//--- check the possibility of modifying the short order
   if(m_signal.CheckTrailingOrderShort(GetPointer(m_order),price))
      return(TrailingOrderShort(m_order.PriceOpen()-price));
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Trailing long limit/stop order                                   |
//+------------------------------------------------------------------+
bool CExpert::TrailingOrderLong(double delta)
  {
   ulong  ticket=m_order.Ticket();
   double price =m_symbol.NormalizePrice(m_order.PriceOpen()-delta);
   double sl    =m_symbol.NormalizePrice(m_order.StopLoss()-delta);
   double tp    =m_symbol.NormalizePrice(m_order.TakeProfit()-delta);
//--- modifying the long order
   return(m_trade.OrderModify(ticket,price,sl,tp,m_order.TypeTime(),m_order.TimeExpiration()));
  }
//+------------------------------------------------------------------+
//| Trailing short limit/stop order                                  |
//+------------------------------------------------------------------+
bool CExpert::TrailingOrderShort(double delta)
  {
   ulong  ticket=m_order.Ticket();
   double price =m_symbol.NormalizePrice(m_order.PriceOpen()-delta);
   double sl    =m_symbol.NormalizePrice(m_order.StopLoss()-delta);
   double tp    =m_symbol.NormalizePrice(m_order.TakeProfit()-delta);
//--- modifying the short order
   return(m_trade.OrderModify(ticket,price,sl,tp,m_order.TypeTime(),m_order.TimeExpiration()));
  }
//+------------------------------------------------------------------+
//| Check for delete long limit/stop order                           |
//+------------------------------------------------------------------+
bool CExpert::CheckDeleteOrderLong(void)
  {
   double price;
//--- check the possibility of deleting the long order
   if(m_expiration!=0 && TimeCurrent()>m_expiration)
     {
      m_expiration=0;
      return(DeleteOrderLong());
     }
   if(m_signal.CheckCloseLong(price))
      return(DeleteOrderLong());
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Check for delete short limit/stop order                          |
//+------------------------------------------------------------------+
bool CExpert::CheckDeleteOrderShort(void)
  {
   double price;
//--- check the possibility of deleting the short order
   if(m_expiration!=0 && TimeCurrent()>m_expiration)
     {
      m_expiration=0;
      return(DeleteOrderShort());
     }
   if(m_signal.CheckCloseShort(price))
      return(DeleteOrderShort());
//--- return without operations
   return(false);
  }
//+------------------------------------------------------------------+
//| Delete all limit/stop orders                                     |
//+------------------------------------------------------------------+
bool CExpert::DeleteOrders(void)
  {
   bool result=true;
   int  total=OrdersTotal();
//---
   for(int i=total-1;i>=0;i--)
      if(m_order.Select(OrderGetTicket(i)))
        {
         if(m_order.Symbol()!=m_symbol.Name())
            continue;
         result&=DeleteOrder();
        }
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Delete all limit/stop long orders                                |
//+------------------------------------------------------------------+
bool CExpert::DeleteOrdersLong(void)
  {
   bool result=true;
   int  total=OrdersTotal();
//---
   for(int i=total-1;i>=0;i--)
      if(m_order.Select(OrderGetTicket(i)))
        {
         if(m_order.Symbol()!=m_symbol.Name())
            continue;
         if(m_order.OrderType()!=ORDER_TYPE_BUY_STOP &&
            m_order.OrderType()!=ORDER_TYPE_BUY_LIMIT)
            continue;
         result&=DeleteOrder();
        }
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Delete all limit/stop orders                                     |
//+------------------------------------------------------------------+
bool CExpert::DeleteOrdersShort(void)
  {
   bool result=true;
   int  total=OrdersTotal();
//---
   for(int i=total-1;i>=0;i--)
      if(m_order.Select(OrderGetTicket(i)))
        {
         if(m_order.Symbol()!=m_symbol.Name())
            continue;
         if(m_order.OrderType()!=ORDER_TYPE_SELL_STOP &&
            m_order.OrderType()!=ORDER_TYPE_SELL_LIMIT)
            continue;
         result&=DeleteOrder();
        }
//---
   return(result);
  }
//+------------------------------------------------------------------+
//| Delete limit/stop order                                          |
//+------------------------------------------------------------------+
bool CExpert::DeleteOrder(void)
  {
   return(m_trade.OrderDelete(m_order.Ticket()));
  }
//+------------------------------------------------------------------+
//| Delete long limit/stop order                                     |
//+------------------------------------------------------------------+
bool CExpert::DeleteOrderLong(void)
  {
   return(m_trade.OrderDelete(m_order.Ticket()));
  }
//+------------------------------------------------------------------+
//| Delete short limit/stop order                                    |
//+------------------------------------------------------------------+
bool CExpert::DeleteOrderShort(void)
  {
   return(m_trade.OrderDelete(m_order.Ticket()));
  }
//+------------------------------------------------------------------+
//| Method of getting the lot for open long position.                |
//+------------------------------------------------------------------+
double CExpert::LotOpenLong(double price,double sl)
  {
   return(m_money.CheckOpenLong(price,sl));
  }
//+------------------------------------------------------------------+
//| Method of getting the lot for open short position.               |
//+------------------------------------------------------------------+
double CExpert::LotOpenShort(double price,double sl)
  {
   return(m_money.CheckOpenShort(price,sl));
  }
//+------------------------------------------------------------------+
//| Method of getting the lot for reverse position.                  |
//+------------------------------------------------------------------+
double CExpert::LotReverse(double sl)
  {
   return(m_money.CheckReverse(GetPointer(m_position),sl));
  }
 
dclark24:

Hello,

I am running this ExpertMAMA and (...) performance results for June 2019-current day on S&P futures (even with the periodic big losses) is impressive!!


About the impressive losses you mentioned:

You want that someone here tells you why? 


Please tell us what have you already analysed on the code, what do you suppose is happening, what you are sure it is happening. 

Here we can talk about coding and help each other. 


But I don't think anybody will get your code and run it, and analyse it, and fix it, if you don't provide a more specific situation to be discussed and talked here about it.


help us, and we help you.

Reason: