should input variable be initialize in class?

 

Hi,

I'm currently learning about class for the first time. I have 2 strategy that using the same include variable file, one for long position and the other for short position. In variable file, some of the variable contains trade direction such as SymbolsLong and SymbolsShort and it is used only for respective strategy while other is not and used for both strategy. My question is should I create an object for every strategy that used by both strategy?

//example of variable needed in strategy

input   string                  InpSymbolsLong = "AUDCAD|EURUSD|GBPCHF";
input   string                  InpSymbolsShort = "EURCHF|CADCHF|NZDUSD";
input   ENUM_TIMEFRAME  	InpTimeframe = PERIOD_M15;
input   double                  InpVolume        = 0.1;

class     CStrategy {
        public:
                //should I initialize a class member to store the input variable above?
                ENUM_TIMEFRAME  InpTimeframe;                   
                double          InpVolume;      


        int OnInitEvent() {
                ...
        }


}
 
Luandre Ezra:

Hi,

I'm currently learning about class for the first time. I have 2 strategy that using the same include variable file, one for long position and the other for short position. In variable file, some of the variable contains trade direction such as SymbolsLong and SymbolsShort and it is used only for respective strategy while other is not and used for both strategy. My question is should I create an object for every strategy that used by both strategy?

i guess you have 2 obvious options - first one is to create 2 objects, each one holding either the InpSymbolsLong value or the InsymbolsShort value.

But another way is to pass the string to the object and let it react accordingly based on which string you pass - here is a simple example which hopefully illustrates both approaches.

Personally I would do option2 - just have one object and create as many methods as you need to control the entire scenario


//+------------------------------------------------------------------+
//|                                             458115-ClassInit.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+

//example of variable needed in strategy

#define  def_InpSymbolsLong   "AUDCAD|EURUSD|GBPCHF"
#define  def_InpSymbolsShort  "EURCHF|CADCHF|NZDUSD"

input   string                  InpSymbolsLong = def_InpSymbolsLong;
input   string                  InpSymbolsShort = def_InpSymbolsShort;
input   ENUM_TIMEFRAMES         InpTimeframe = PERIOD_M15;
input   double                  InpVolume        = 0.1;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class     CStrategy_option1
  {
public:
   //should I initialize a class member to store the input variable above?
   ENUM_TIMEFRAMES   InpTimeframe;
   double            InpVolume;
   string            InpSymbols;

   void              CStrategy_option1(string inpSym)   //Constructor
     {
      InpSymbols = inpSym;
     }

   int               OnInitEvent()
     {
      //...
      return(0);
     }
  };


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class     CStrategy_option2
  {
public:
   //should I initialize a class member to store the input variable above?
   ENUM_TIMEFRAMES   InpTimeframe;
   double            InpVolume;

   void              selectAction(string inpSym)
     {
      if(inpSym == def_InpSymbolsLong)
        {
         //execute Long code
        }
      else
         if(inpSym == def_InpSymbolsShort)
           {
            //execute Short code
           }

     }

   int               OnInitEvent()
     {
      //...
      return(0);
     }
  };





//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
//---

   CStrategy_option1 CStrategy_InpSymbolsLong(def_InpSymbolsLong);
   CStrategy_option1 CStrategy_InpSymbolsShort(def_InpSymbolsShort);


   CStrategy_option2 CStrategy_combo();
   CStrategy_combo.selectAction(def_InpSymbolsLong);
   CStrategy_combo.selectAction(def_InpSymbolsShort);
   
   

  }
//+------------------------------------------------------------------+
 

Thanks @R4tna C for your answer. My problem is revolve around whether I need to create an object for my variable. 

I have an input variable and a global variable that will be used to accommodate multi-symbol strategy. If I use code in the OnInit below, when I call StrategyLong.OnInitEvent() function first it will set the value to a long config file but when I call StrategyShort.OnInitEvent() function it will overwrite the GV value to what is written in the short file config file.

// input variable that will be overwrite
bool            InpCurrencyTradingAllowed = false;
TRADING_METHOD  InpTradingMethod = TREND_FOLLOWING;
double          InpTPCoef = 200;
double          InpSLCoef = 100;
int             InpOtherCloseCoef = 0;

// global variable for input variable
bool            CurrencyTradingAllowed[];
TRADING_METHOD  TradingMethod[];
double          TPCoef[];
double          SLCoef[];
int             OtherCloseCoef[];


int OnInit() {
   if(InpTradeSymbolsLong != "NONE")
      StrategyLong.OnInitEvent(InpTradeSymbolsLong, SymbolArrayLong, NumberOfTradeableSymbolsLong, SymbolsProcessedThisIterationLong, OpenPositionTicketLong, InpSettingsFileLong);
   if(InpTradeSymbolsShort != "NONE")
      StrategyShort.OnInitEvent(InpTradeSymbolsShort, SymbolArrayShort, NumberOfTradeableSymbolsShort, SymbolsProcessedThisIterationShort, OpenPositionTicketShort, InpSettingsFileShort);
   return (INIT_SUCCEEDED);
}

To fix this problem, I want to create a class member to save each value from a long strategy and short strategy

CStrategy {
    private:
        bool            m_CurrencyTradingAllowed[];
        TRADING_METHOD  m_TradingMethod[];
        double          m_TPCoef[];
        double          m_SLCoef[];
        int             m_OtherCloseCoef[];

        void InitConfigFile(string& SymbolArray[], int SymbolLoop, int numberOfTradeableSymbols, string FileName) {
             // assign GV to input variable
             CurrencyTradingAllowed[SymbolLoop] = InpCurrencyTradingAllowed;
             TradingMethod[SymbolLoop]          = InpTradingMethod;
             TPCoef[SymbolLoop]                 = InpTPCoef;
             SLCoef[SymbolLoop]                 = InpSLCoef;
             OtherCloseCoef[SymbolLoop]         = InpOtherCloseCoef;
                        
             // overwrite GV to value in config file
             InitLoadFile();
             
	     m_CurrencyTradingAllowed[SymbolLoop] = CurrencyTradingAllowed[SymbolLoop];
	     m_TradingMethod[SymbolLoop] = TradingMethod[SymbolLoop];
	     m_TPCoef[SymbolLoop] = TPCoef[SymbolLoop];
	     m_SLCoef[SymbolLoop] = SLCoef[SymbolLoop];
	     m_OtherCloseCoef[SymbolLoop] = OtherCloseCoefp[SymbolLoop];
        }
                
        // function to look into config file and overwrite the variable
        InitLoadFile(string& SymbolArray[], int SymbolLoop, int numberOfTradeableSymbols, string FileName) {
            ...
	    CurrencyTradingAllowed[SymbolLoop] = currencyTradingAllowed;	// currencyTradingAllowed value from strategy config file
	    TradingMethod[SymbolLoop]          = tradingMethod;			// tradingMethod value from strategy config file
            TPCoef[SymbolLoop]                 = tpCoef;			// tpCoef value from strategy config file
            SLCoef[SymbolLoop]                 = slCoef;			// slCoef value from strategy config file
            OtherCloseCoef[SymbolLoop]         = otherCloseCoef;		// otherCloseCoef value from strategy config file
            ...
        }       
                        
};

I tried using this code to set the class member but all GV for long strategy still overwritten by short strategy.

 
Luandre Ezra #:

I tried using this code to set the class member but all GV for long strategy still overwritten by short strategy.

Sounds like you have gone for the 2 object approach which is fine, but I only glanced at your code and not sure if I understand your explanation fully. 

But it seems you have a conflict with single global variable being shared and overwritten - so why not store that data as an attribute/property of each object, so it is coupled with the object and thus will not conflict with the other objects usage?

That could be better than using a global variable - worth checking out

 
R4tna C #:

But it seems you have a conflict with single global variable being shared and overwritten - so why not store that data as an attribute/property of each object, so it is coupled with the object and thus will not conflict with the other objects usage?

Hi @R4tna C! Yes this is what I'm currently facing on!. Could you elaborate more about this part

 
Luandre Ezra #:

Yes this is what I'm currently facing on!. Could you elaborate more about this part

Create a variable inside the object - and push the value into the object. 

e.g. if you need to store a unique filepath for each object:

CStrategy {
    private:
        bool            m_CurrencyTradingAllowed[];
        TRADING_METHOD  m_TradingMethod[];
        double          m_TPCoef[];
        double          m_SLCoef[];
        int             m_OtherCloseCoef[];
        string      m_filepath;

StrategyLong.m_filepath will contain the long file path 

StrategyShort.m_filepath will contain the short file path 


No chance of confusion or overwrite - remove the global variable and refer to this property of each object as needed


 
R4tna C #:

Create a variable inside the object - and push the value into the object. 

e.g. if you need to store a unique filepath for each object:

StrategyLong.m_filepath will contain the long file path 

StrategyShort.m_filepath will contain the short file path 


No chance of confusion or overwrite - remove the global variable and refer to this property of each object as needed


This is my input variable for this strategy,

input string                        LongStrategyDesc           = "--------- Long Strategy ----------";                  // -
input string                        InpTradeSymbolsLong        = "CURRENT";                                             // Symbol(s) - CURRENT | ALLCUR | CURRENCY NAME | NONE
input TRADE_DIRECTION               InpTradeDirectionLong      = LONG_ONLY;                                             // Trade direction
input string                        InpSettingsFileLong        = "D:\\Configuration EA files\\10 trend following\\StdDev_X_RVI Long Config.ini";             // Name input file, blank = not used
input string                        ShortStrategyDesc          = "--------- Short Strategy ----------";                 // -
input string                        InpTradeSymbolsShort       = "CURRENT";                         // Symbol(s)
input TRADE_DIRECTION               InpTradeDirectionShort     = SHORT_ONLY;                                             // Trade direction
input string                        InpSettingsFileShort       = "D:\\Configuration EA files\\10 trend following\\StdDev_X_RVI Short Config.ini";             // Name input file, blank = not used
input ENUM_TIMEFRAMES               InpTradeTimeframe          = PERIOD_M15;                                            // Trading timeframe
input ENUM_BAR_PROCESSING_METHOD    InpBarProcessingMethod     = ONLY_PROCESS_TICKS_FROM_NEW_TRADE_TF_BAR;              // EA bar processing method
input bool                          InpCurrencyTradingAllowed  = false;                                                 // Is trade allowed for specified currency
input TRADING_METHOD                InpTradingMethod           = TREND_FOLLOWING;                                     // Trading method

input group                         "Trade Setting"
input string                        GroupDesc2                 = "===== TRADE SETTING =====";
input string                        SectionDesc2               = "***** Volume or Lot setting *****";    // -
input VOLUME_MODE                   InpVolumeMode              = VOLUME_MODE_FIXED;                         // Lot mode
input double                        InpVolume                  = 0.01;                                   // Lots / money / equity divisor / percent
input string                        SectionDesc3               = "***** TP/SL/Trail Stop setting *****"; // -
input STOPLOSS_METHOD               InpStoplossMethod          = NONE1;                                  // Stoploss method
input double                        InpSLCoef                  = 0;                                      // Point/dollar/ATR mltp/bar(s)
input TAKE_PROFIT_METHOD            InpTakeProfitMethod        = NONE2;                                  // Take profit method
input double                        InpTPCoef                  = 0;                                      // Point/dollar/multiplier
input OTHER_CLOSE_METHOD            InpOtherCloseMethod        = NONE3;                                  // Other close method
input int                           InpOtherCloseCoef          = 0;                                      // *Close X next bar(s)
input string                        SectionDesc4               = "***** other general setting *****";    // -
input ulong                         InpSlippage                = 10;                                     // Slippage in points
input int                           InpMaxSpread               = 20;                                     // Maximum spread allowed
input ulong                         InpMagicNumber             = 1;                                      // Magic number

as you can see, some of the input variable has 2 input based on the strategy itself. This variable that will be change to whatever written in the config file.

 
Luandre Ezra #:

This is my input variable for this strategy,

as you can see, some of the input variable has 2 input based on the strategy itself. This variable that will be change to whatever written in the config file.

Not sure I follow you - but even if the variable needs to be changed to whatever the config file, you could hold that info "inside" the object and rely on that to correct rather than risking global variable conflicts

 

It's fixed!. Previously by creating variable inside object is a correct answer. I just need to use the variable in all of the parameter on other function and it works now. Thanks for your help @R4tna C

 
Luandre Ezra #:

It's fixed!. Previously by creating variable inside object is a correct answer. I just need to use the variable in all of the parameter on other function and it works now. Thanks for your help @R4tna C

Good - thanks for confirming

Reason: