Is it possible to call one derived class into another derived class from the same Base/Parent Class ? if yes how to instantiate the 1st class into 2nd class ?

 

Hi Friend

I am trying to get Trend calculations in a derived class CTrend.mqh.

I want to use method of the above class to use into another derived class CBreakOut.mqh.

Both the derived classes are coming from same CStrategyBase.mqh class.

below I have tried to give some idea of what I am planning to do in terms of MQL Code.

The challenge I am facing is how to call/instantiate the CTrend into CBreakOut !!!

Your help will be highly appreciated.

Regards,


//+-----------------------------------------------------------------------------------------------------------------------------+
//| CLASS:        CStrategyBase.mqh
//| APPLICATION:  Parent BASE CLASS for Trading Strategies
//+-----------------------------------------------------------------------------------------------------------------------------+
class CStrategyBase {
protected:
  //--- member variables for Symbol, TimeFrames and RiskPerTrade related data
    string                                    mSymbol;
    ENUM_TIMEFRAMES         mTF_M01;             // Chart for Trade Entries, in most cases
    ENUM_TIMEFRAMES         mTF_M05;            // Chart for Trade Management and Entries sometimes
    ENUM_TIMEFRAMES         mTF_M15;             // Chart for Trend Direction
    int                                         mDigits;              // Digits (_Digits) for the mSymbol instrument
  //--- member variables for Strategy and Money Management
    int                 mMagic;
    string              mComment;
    double              mRiskPerTrade;
        //--- parametric constructor
        CStrategyBase(string pSymbol,ENUM_TIMEFRAMES pTF_M01,ENUM_TIMEFRAMES pTF_M05,ENUM_TIMEFRAMES pTF_M15,
                      double pRiskPerTrade=0.010);

};
//+-----------------------------------------------------------------------------------------------------------------------------+
//| CLASS:      CTrend.mqh
//| STRATEGY:   1st DERIVED Class from CStrategyBase.mqh
//+-----------------------------------------------------------------------------------------------------------------------------+
#include "sBase.mqh"
class CTrend final : CStrategyBase {
private:
        //--- for ATR
                CATR            atrH04,                                                                         atrD01;

public:
  //--- constructors, deconstructors and init method, if any
    CTrend(string pSymbol,ENUM_TIMEFRAMES pTF_M01,ENUM_TIMEFRAMES pTF_M05,ENUM_TIMEFRAMES pTF_M15,double pRiskPerTrade)
      : CStrategyBase(pSymbol,pTF_M01,pTF_M05,pTF_M15,pRiskPerTrade) {  }

}; // END of Class declaration
//+-----------------------------------------------------------------------------------------------------------------------------+
//| CLASS:      CBreakOut.mqh
//| STRATEGY:   2nd DERIVED Class from CStrategyBase.mqh
//+-----------------------------------------------------------------------------------------------------------------------------+
#include "sBase.mqh"
class CBreakOut final : CStrategyBase {
private:
  //--- member variables for strategy specific MagicNo
    int             mMagicBO;
    int             mMagicRM;
  //--- member methods to check if bandwidth <= mSqueezeLimit
                double          mHighest;
                double          mLowest;
                int             mSqueezeLimit;
        //--- PROBLEM ... how can I instantiate CTrend.mqh (1st Derived Class from CStrategyBase) into CBrekOut.mqh (2nd Derived Class from same CStrategyBase)
        //--- creating 1st Derived Class to enable me to use member/methods of CStrategyBase Class, and avoid repeating the same in derived class
        
public:
  //--- constructors, deconstructors and init method, if any
    CBreakOut(string pSymbol,ENUM_TIMEFRAMES pTF_M01,ENUM_TIMEFRAMES pTF_M05,ENUM_TIMEFRAMES pTF_M15,double pRiskPerTrade)
      : CStrategyBase(pSymbol,pTF_M01,pTF_M05,pTF_M15,pRiskPerTrade) {  }

}; // END of Class declaration
// This enables me to call only the CBreakout.mqh class only in the Expert Advisor
// CBreakOut.mqh has its own OnInit() and OnTick() methods, call to them in EA runs them perfectly without any error
//+-----------------------------------------------------------------------------------------------------------------------------+
//| EXPERT:       AKTTrade v1.00
//+-----------------------------------------------------------------------------------------------------------------------------+
  #include "../Include/Strategy/BreakOut.mqh"
//+-----------------------------------------------------------------------------------------------------------------------------+
//| INPUT:  Input for variable used in the expert advisor
//| NOTE:   Indicator parameters defaluted in CBase class (PRICE_CLOSE,VOLUME_TICK)
//+-----------------------------------------------------------------------------------------------------------------------------+
  input group               "EA Symbol & TimeFrames"
    input string              eSymbol = "US30";            // Expert's Instrument/Symbol
    input ENUM_TIMEFRAMES     eTF_M01 = PERIOD_M1;         // Expert's Time Frame Lower
    input ENUM_TIMEFRAMES     eTF_M05 = PERIOD_M5;         // Expert's Time Frame Trade (Working)
    input ENUM_TIMEFRAMES     eTF_M15 = PERIOD_M15;        // Expert's Time Frame Higher
  input group               "MoneyManagement"
    input double              RiskPerTrade = 0.010;        // Risk Per Trade 1.50% enter as 0.015
//+-----------------------------------------------------------------------------------------------------------------------------+
//| OBJECT:       Instantiation
//+-----------------------------------------------------------------------------------------------------------------------------+
  CBreakOut             breakout(eSymbol,eTF_M01,eTF_M05,eTF_M15,RiskPerTrade);
//+-----------------------------------------------------------------------------------------------------------------------------+
//| EXPERT:       OnInit() Initialization Function
//+-----------------------------------------------------------------------------------------------------------------------------+
int OnInit() {
        //---
        breakout.OnInit();
  //---
    return(INIT_SUCCEEDED);
} // END of function OnInit()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| EXPERT:       OnDeinit() DeInitialization Function
//+-----------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason) {
  //---
   
} // END of function OnDeinit()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| EXPERT:       OnTick() Tick Function
//+-----------------------------------------------------------------------------------------------------------------------------+
void OnTick() {
  //--- Check(s) to make sure EA Allowed to trade, if not then EXIT as no point in processing further
  //---
    breakout.OnTick();
   
} // END of function OnTick()
//+-----------------------------------------------------------------------------------------------------------------------------+


 

 
Polymorphism and/additionally/or either virtual functions or interfaces.

Have a base class pointer in the second derived class. Assign it a pointer to an object from the first derived class.


 
Bad design.
 
Alain Verleyen #:
Bad design.

any suggestion for improvement for good design ?

 
Dominik Egert #:
Polymorphism and/additionally/or either virtual functions or interfaces.

Have a base class pointer in the second derived class. Assign it a pointer to an object from the first derived class.


Hi Dominik

May I request a simple example for me to understand your concept ?

thanks

 
Let me try to conceptualize, if I find the time for code...

Try to think in terms of "is an" or "has an".

Principle:
A car is a vehicle.
A car has an engine.

Every vehicle has some kind of "engine" producing some type of thrust/propulsion.


Transfer to your situation.

Let me rename your base class to "movement'

Your movement is a trend.
A trend has a breakout.

So you derive the trend from movement, you give it the object breakout. (The breakout could be called signal.)

The coding to this is just technicals...

As long as you keep sticking to the basic "is an" and "has an" you should get working concepts.

For later, you can add the relationships into your design. Is child, is sister, is parent, is related and so on. To have compatibility, you use so called interfaces.

Interfaces are in general object descriptors.
Like in the original example with vehicles. You'd have an interface which defines basic functions which every object has in common. Like the remote control of an RC car. You can go forward, backward, left and right...

I hope this helps already. Coding this is just work and can be taken from documentation, and examples from the internet.
 
Dominik Egert #:
Let me try to conceptualize, if I find the time for code...

Try to think in terms of "is an" or "has an".

Principle:
A car is a vehicle.
A car has an engine.

Every vehicle has some kind of "engine" producing some type of thrust/propulsion.


Transfer to your situation.

Let me rename your base class to "movement'

Your movement is a trend.
A trend has a breakout.

So you derive the trend from movement, you give it the object breakout. (The breakout could be called signal.)

The coding to this is just technicals...

As long as you keep sticking to the basic "is an" and "has an" you should get working concepts.

For later, you can add the relationships into your design. Is child, is sister, is parent, is related and so on. To have compatibility, you use so called interfaces.

Interfaces are in general object descriptors.
Like in the original example with vehicles. You'd have an interface which defines basic functions which every object has in common. Like the remote control of an RC car. You can go forward, backward, left and right...

I hope this helps already. Coding this is just work and can be taken from documentation, and examples from the internet.

Thanks a lot Dominik.

This is really a simplest explanation of Object Class. I really appreciate your time to explain that here.

I will definitely try to work on 'is an' and 'is has' concept in my programming.

Due to tremendous pressure to complete my EA with at least one strategy and go online, I have cut of the middle layer and remained to StrategyBASE (holding variables, indicator class instantiation and common methods e.g. TrailSL ) and BreakoutCLASS (to filter range, and methods to open breakout position). So I have shifted Trend (in this case Range) calculation within BreakoutClass. The idea is to have breakout calculations into breakoutClass and trend calculations in TrendClass (with position opening methods).

What I also feel that my four major inputs for all these class declaration are Symbol, 3 Time Frames and Risk Per Trade rate. I can try to instantiate them into BASE class only by calling it from EA. Then I can use default constructor (as against parametric) for class declaration in Sub Classes.

I will find some time to implement your method into CLASS created for TESTING Purpose, and if successful will shift it to my EA project.

Once again thanks a lot for giving me direction.

Regards and wish you nice weekend.

 
Welcome. NP.
There is one major limitation in MQL which I find very annoying, therefore I do not use OO but do all in procedural programming. MQL does not allow deriving from more than one class at the same time. This limits the whole OO concept to a single derive path and in my eyes limits the possibilities way to much.


 
Anil Varma - #:

Hi Dominik

May I request a simple example for me to understand your concept ?

thanks

If you search here for OOP and select articles you'll find lots of them about OOP and here is one for you: https://www.mql5.com/en/articles/351

The Basics of Object-Oriented Programming
The Basics of Object-Oriented Programming
  • www.mql5.com
You don't need to know what are polymorphism, encapsulation, etc. all about in to use object-oriented programming (OOP)... you may simply use these features. This article covers the basics of OOP with hands-on examples.
 
Dominik Egert #:
Welcome. NP.
There is one major limitation in MQL which I find very annoying, therefore I do not use OO but do all in procedural programming. MQL does not allow deriving from more than one class at the same time. This limits the whole OO concept to a single derive path and in my eyes limits the possibilities way to much.


Hi agree with the reason, Dominik, it is very limiting. But not with the conclusion, I think using procedural instead of the limited OOP is going way too far. 

There was an intention in metaquotes about 3 years ago to make the interface applied by a class in addition to class extension, seems easy to do and makes it much better for developing. Pitty the went off that.
 
Carl Schreiber #:

If you search here for OOP and select articles you'll find lots of them about OOP and here is one for you: https://www.mql5.com/en/articles/351

Hi Carl

thanks for your response, and I really articles about OOP. Being a non professional programmer, I have come a long way from procedural to OOP. Now I have stabilized using OOP and going to stick to it. I have seen many useful ways I could use it. The challenges comes in when I have a new idea to implement OOP and could not find article or some other material on forum or the net.

the article you have mentioned was one of the article I have gone through on OOP before moving to it.

As @Dominik Egert has mentioned "MQL does not allow deriving from more than one class at the same time." it seems my idea of working with layers will not work.

Regards

Reason: