Compilation error while trying new approach to use CLASS(s) for a multi symbol Expert

 

Dear Fellow Members

I am trying to use, possibly a new approach with classes to create a multi symbol expert advisor. The main logic of it is explained below:

  1. The ArunFX.mq5, the expert will have different parameters and create instances of ExpertBase class for each symbol;
  2. The ExpertBase.mqh class will act as an Expert to do all trade activities for the defined symbol;
  3. The StrategyBase.mqh class (derived from CommonBase Class) will act as parameters collector from ExpertBase.mqh and call CommonBase.mqh to set all indicator parameters and other member variables values through a call to its 'Parametric Constructor' method.
    1. The reason I choose to work this way is because I found that variables defined in the constructor are globally available to derived class(s) as opposed to using SetParam() in which case values are not available in derived classes.
    2. This class will also have common trade methods (e.g. Open Position, Close Position etc) and will run on its own for these operations.
  4. The StrategyTest.mqh is the actual strategy class to generate signals to open / close position and call StrategyBase.OpenPosition() for the purpose.
    1. It is derived class of StrategyBase, and indirectly of CommonBase.
    2. This will enable it to access indicator parameters from the CommonBase class, without having to define again.
    3. This will be useful in case of multiple strategies using some or all indicators which are common in each strategy.
  5. The CommonBase class is the global container to hold all parameters values.

The challenge I am facing is the compilation error on CommonBase and StrategyBase class. It looks like I am making error in defining the constructor methods in these class(s), or if something else then I hope the expert will figure it out.

I am open to hear any additional suggestions, to implement or improve on my above logic.

MyAglo zip file is attached for the complete code and below are the codes for CCommonBase and CStrategyBase Classes. Some sections have been deleted from the code below to overcome the 64000 characters limit, but the zip file have complete code.

The compilation errors are also provided below.

Look forward to hear from experts here for possible solution. Thanks a lot in advance.

#include <Object.mqh>
#include "../../FrameWork.mqh"

#define _INIT_CHECK_FAIL                                                                                                        \
   if(mInitResult != INIT_SUCCEEDED )                                           return (mInitResult);
#define _INIT_ERROR(msg)                                                                                                        return ( InitError(msg,INIT_PARAMETERS_INCORRECT));
#define _INIT_ASSERT(condition,msg)                                                     \
   if(!condition)                                                                                                                               return ( InitError(msg,INIT_FAILED) );

class CCommonBase : public CObject {


        public:                                                                 // TO BE CALLED FROM CStrategyBase CLASS AND SET PARAMETERS
                CCommonBase(string pSymbol,double pRiskPerSymbol,double pRiskPerTrade,
                                                                int pAroon_Period,int pAroon_ThldUP);
         ~CCommonBase();
                CCommonBase(string pSymbol) { mSymbol = pSymbol; }

        protected:      // METHODS
                string                                  mInitMessage;
                int                                     mInitResult;
                int                                                                     InitError(string initMessage,int initResult);

        public:                 // PROPERTIES
                int                                                             InitResult()    { return(mInitResult); }
                string                                                          InitMessage() { return(mInitMessage); }

        protected:
          string                                        mSymbol;
          int                                                   mDigits;
                ENUM_APPLIED_VOLUME             mAppliedVolume;

                double                                                          mRiskPerSymbol;
                double                                                          mRiskPerTrade;
        protected:
                // INDICATOR: iAroon
                int                                                                             mAroon_Period;                                                                          // NO OF BARS TO LOOK BACK FOR HIGHEST/LOWEST PRICES
                int                                                                             mAroon_ThldUP;                                                                          // UPPER THRESHOLD TO IDENTIFY STRONG TREND
                int                                                                             mAroon_ThldMP;                                                                          // MID POINT OF RANGE BOUND INDICATOR MP = (MAX 100 + MIN 0) / 2
                int                                                                             mAroon_ThldDN;                                                                          // LOWER THRESHOLD TO IDENTIFY RANGING MARKET

}; // END of Class declaration

CCommonBase::CCommonBase(string pSymbol,double pRiskPerSymbol,double pRiskPerTrade,
                                                                                                 int pAroon_Period,int pAroon_ThldUP) {

        // ASSIGN / DEFAULT MEMBER VARIABLE VALUES
          mSymbol = pSymbol;
          mDigits = (int)SymbolInfoInteger(mSymbol,SYMBOL_DIGITS);
                mAppliedVolume = VOLUME_TICK; // SET DEFAULT APPLIED VOLUME TYPE (GetVolume() USES iVolumes() WHICH RETURNS ONLY TICK VOLUME)

                // RISK MANAGEMENT VARIABLES
                mRiskPerSymbol  = NormalizeDouble(pRiskPerSymbol/100,3);                                // RISK @1.50% SAVED AS 0.015
                mRiskPerTrade           = NormalizeDouble(pRiskPerTrade/100,3);                                 // RISK @0.50% SAVED AS 0.005
        //+---------------------------------------------------------------------------------------------------------------------------+
        //| NOTE:  Parameter values defined in PARAMETRIC CONSTRUCTOR are available globally to the derived class(s). Thus avoid need
        //|                              to redefine them again on each derived class. As against using SetParam() which is not part of the constructor.
        //+---------------------------------------------------------------------------------------------------------------------------+
                //+---------------------------------------------------------------------------------------------------------------------------+
                //| FILTER TREND: iAroon INDICATOR
                //+---------------------------------------------------------------------------------------------------------------------------+
                        mAroon_Period = pAroon_Period;
                        mAroon_ThldUP = pAroon_ThldUP;
                        mAroon_ThldMP = (100 + 0) / 2;
                        mAroon_ThldDN = 100 - mAroon_ThldUP;
        //+---------------------------------------------------------------------------------------------------------------------------+
        //| HARDLY ANYTHING GO WRONG HERE, WE RETURN
        //+---------------------------------------------------------------------------------------------------------------------------+
                InitError("",INIT_SUCCEEDED);
                PrintFormat("[%s] %s mInitResult[%i] mInitMessage[%s]",(string)mSymbol,(string)__FUNCTION__,mInitResult,mInitMessage);
                //return(INIT_SUCCEEDED);

} // END of method CCommonBase()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:       ~CCommonBase()
//| APPLICATION:  
//+-----------------------------------------------------------------------------------------------------------------------------+
CCommonBase::~CCommonBase(void) {


} // END of method ~CCommonBase()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:       InitError()
//| APPLICATION:  
//+-----------------------------------------------------------------------------------------------------------------------------+
int CCommonBase::InitError(string initMessage,int initResult) {

                mInitMessage = initMessage;
                mInitResult  = initResult;

                if(initMessage != "") {
                        PrintFormat("[%s] %s  initResult[%i]  initMessage[%s]",(string)mSymbol,(string)__FUNCTION__,initResult,initMessage);
                }

                return(initResult);

} // END of method InitError()
//+-----------------------------------------------------------------------------------------------------------------------------+
#include "CommonBase.mqh"
//+-----------------------------------------------------------------------------------------------------------------------------+
//| CLASS:        CStrategyBase.mqh
//| APPLICATION:  STRATEGY BASE CLASS WITH COMMON TRADE OPERATION METHODS
//+-----------------------------------------------------------------------------------------------------------------------------+
class CStrategyBase : protected CCommonBase {

        //+---------------------------------------------------------------------------------------------------------------------------+
  //| CONSTRUCTOR AND DECONSTRUCTOR
        //+---------------------------------------------------------------------------------------------------------------------------+
        public:
                // PARAMETRIC CONSTRUCTOR TO BE CALLED FROM CExpertBase CLASS AND TO SET PARAMETERS IN CCommonBase CLASS
                CStrategyBase(string pSymbol,double pRiskPerSymbol,double pRiskPerTrade,
                                                                        int pAroon_Period,int pAroon_ThldUP);
                // DEFAULT DECONSTRUCTOR METHOD
         ~CStrategyBase();
                // DEFAULT CONSTRUCTOR TO BE CALLED FROM INDIVIDUAL STRATEGY CLASS(s) TO ACCESS GLOBAL PARAMETER VALUES FROM CCommonBase
                CStrategyBase(string pSymbol) : CCommonBase(pSymbol) { }

        public:
                virtual int                                     OnInit();
                virtual void                                    OnDeinit(const int reason)              { return; }
                virtual void                                    OnTick();
        //+---------------------------------------------------------------------------------------------------------------------------+
  //| NEW CONNECTION TO BROKER FOR FIRST TIME
        //+---------------------------------------------------------------------------------------------------------------------------+
        protected:
                bool                    mFirstTime;                                                                                             // REPLACE WITH mConnected ... RECEIVED FIRST TICK AFTER CONNECTION
                MqlTick                 mLastTick;
                virtual void            RunSetup() { return; }

        protected:
                // MEMBER VARIABLES FOR MAGIC NO OF DIFFERENT STRATEGY
          int                   mMagic;
        protected:
          ENUM_TIMEFRAMES               mTFH01;

        protected:
                virtual bool                                    IsNewBarH01();                                          datetime        mPrevTimeH01;

}; // END Of Class DEFINITION

CStrategyBase::CStrategyBase(string pSymbol,double pRiskPerSymbol,double pRiskPerTrade,
                                                                                                                 int pAroon_Period,int pAroon_ThldUP)
                : CCommonBase(pSymbol,pRiskPerSymbol,pRiskPerTrade,
                                                                        pAroon_Period,pAroon_ThldUP) {

                string vFunction = "[" + (string)mSymbol + "] " + (string)__FUNCTION__;

                // IF ERROR IN INITIALIZING CBaseCommon CLASS
                if(InitResult() != INIT_SUCCEEDED) {
                        PrintFormat("%s InitResult[%i] InitMessage[%s]",vFunction,InitResult(),InitMessage());
                        // return(InitResult()); ... Gives Error 'void' function returns a value
                }
          mTFH01        = PERIOD_H1;                                    mPrevTimeH01 = WRONG_VALUE;

}; // END Of method CStrategyBase()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| EXPERT:       OnInit() Tick Function
//+-----------------------------------------------------------------------------------------------------------------------------+
CStrategyBase::~CStrategyBase(void) {

} // END of function OnInit()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| EXPERT:       OnTick() Tick Function
//+-----------------------------------------------------------------------------------------------------------------------------+
void CStrategyBase::OnTick() {


} // END of function OnTick()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:      IsNewBarH01()
//+-----------------------------------------------------------------------------------------------------------------------------+
bool CStrategyBase::IsNewBarH01() {

  datetime vCurrTime = (datetime)SeriesInfoInteger(mSymbol,mTFH01,SERIES_LASTBAR_DATE);

  if(mPrevTimeH01 != vCurrTime)                 { mPrevTimeH01 = vCurrTime;             return(true); } 
  return(false);

} // End of method IsNewBarH01()
//+-----------------------------------------------------------------------------------------------------------------------------+
ERROR WHEN COMPILING 'CStrategyBase.mqh'
'CStrategyBase' - unexpected token, probably type is missing?   ExpertBase.mqh  38      3
'*' - semicolon expected        ExpertBase.mqh  38      21
'cStrategyBase' - undeclared identifier ExpertBase.mqh  79      10
'cStrategyBase' - object pointer expected       ExpertBase.mqh  79      10
'cStrategyBase' - undeclared identifier ExpertBase.mqh  88      3
'=' - illegal operation use     ExpertBase.mqh  88      17
'cStrategyBase' - undeclared identifier ExpertBase.mqh  100     3


ERROR WHEN COMPILING 'CCommonBase.mqh'
'CCommonBase' - declaration without type        StrategyBase.mqh        6       33
'CCommonBase' - syntax error    StrategyBase.mqh        6       33
'CCommonBase' - struct member undefined StrategyBase.mqh        113     5
'mSymbol' - undeclared identifier       StrategyBase.mqh        116     36
'InitResult' - undeclared identifier    StrategyBase.mqh        119     6
')' - expression expected       StrategyBase.mqh        119     17
'InitResult' - cannot convert enum      StrategyBase.mqh        119     6
'InitResult' - undeclared identifier    StrategyBase.mqh        120     62
')' - expression expected       StrategyBase.mqh        120     73
'InitMessage' - undeclared identifier   StrategyBase.mqh        120     75
')' - expression expected       StrategyBase.mqh        120     87
'mSymbol' - undeclared identifier       StrategyBase.mqh        137     35
implicit conversion from 'number' to 'string'   StrategyBase.mqh        137     35
'mSymbol' - undeclared identifier       StrategyBase.mqh        145     41
implicit conversion from 'number' to 'string'   StrategyBase.mqh        145     41
'CCommonBase' - struct member undefined StrategyBase.mqh        18      35
'mSymbol' - undeclared identifier       StrategyBase.mqh        171     22
implicit conversion from 'number' to 'string'   StrategyBase.mqh        171     22
'mSymbol' - undeclared identifier       StrategyBase.mqh        173     66
'mAroon_Period' - undeclared identifier StrategyBase.mqh        173     74
'mAroon_ThldUP' - undeclared identifier StrategyBase.mqh        173     88
'mAroon_ThldDN' - undeclared identifier StrategyBase.mqh        173     102
'mSymbol' - undeclared identifier       StrategyBase.mqh        48      74
implicit conversion from 'number' to 'string'   StrategyBase.mqh        48      74
'mDigits' - undeclared identifier       StrategyBase.mqh        48      94
'mSymbol' - undeclared identifier       StrategyBase.mqh        49      72
implicit conversion from 'number' to 'string'   StrategyBase.mqh        49      72
'mDigits' - undeclared identifier       StrategyBase.mqh        49      92
'mSymbol' - undeclared identifier       StrategyBase.mqh        56      37
implicit conversion from 'number' to 'string'   StrategyBase.mqh        56      37
'mSymbol' - undeclared identifier       StrategyBase.mqh        58      35
'mSymbol' - undeclared identifier       StrategyBase.mqh        58      63
implicit conversion from 'number' to 'string'   StrategyBase.mqh        58      63
implicit conversion from 'number' to 'string'   StrategyBase.mqh        58      35
'mSymbol' - undeclared identifier       StrategyBase.mqh        61      36
implicit conversion from 'number' to 'string'   StrategyBase.mqh        61      36
'mSymbol' - undeclared identifier       StrategyBase.mqh        63      34
'mSymbol' - undeclared identifier       StrategyBase.mqh        63      61
implicit conversion from 'number' to 'string'   StrategyBase.mqh        63      61
implicit conversion from 'number' to 'string'   StrategyBase.mqh        63      34
'mSymbol' - undeclared identifier       StrategyBase.mqh        65      91
implicit conversion from 'number' to 'string'   StrategyBase.mqh        65      91
'mSymbol' - undeclared identifier       StrategyBase.mqh        66      93
implicit conversion from 'number' to 'string'   StrategyBase.mqh        66      93
'mSymbol' - undeclared identifier       StrategyBase.mqh        182     52
implicit conversion from 'number' to 'string'   StrategyBase.mqh        182     52
'mSymbol' - undeclared identifier       StrategyBase.mqh        193     52
implicit conversion from 'number' to 'string'   StrategyBase.mqh        193     52
'mSymbol' - undeclared identifier       StrategyBase.mqh        204     52
implicit conversion from 'number' to 'string'   StrategyBase.mqh        204     52
'mSymbol' - undeclared identifier       StrategyBase.mqh        215     52
implicit conversion from 'number' to 'string'   StrategyBase.mqh        215     52
'mSymbol' - undeclared identifier       StrategyBase.mqh        226     52
implicit conversion from 'number' to 'string'   StrategyBase.mqh        226     52
Files:
MyAlgo.zip  39 kb
 
Couple of months have passed by after you posted the topic - are you still looking for the information and advice?

Multi symbol expert advisor - is nothing new or interesting, so nobody is anxious to dive into your zip file.  

What's your biggest stumbling block? If you break it down into smaller pieces people would be more eager to help.  
Reason: