Use Common Classes to Write MQL4 and MQL5 Experts
When I make videos about writing experts or indicators I usually make them for both MQL4 and MQL5. This naturally leads to some code that has to be conditional due to the differences. The conditional code that bothers me most is the difference in the way technical indicators are handled and I think dealing with the difference makes the videos more complicated.
I decided to create a toolbox, starting with the technical indicators, that would allow me to mostly write indicators and experts without worrying about the 4/5 differences.
This video introduces a base class to handle the inbuilt technical indicators and 2 child classes, MA and MACD.
Here is the code for the CIndicatorBase class used in the tutorial
/*
IndicatorBase.mqh
Copyright 2021, Orchard Forex
https://orchardforex.com
*/
#property copyright "Copyright 2021, Orchard Forex"
#property link "http://orchardforex.com"
#property version "1.00"
class CIndicatorBase {
private:
protected:
// Values used by MQL4
string mSymbol;
int mTimeframe;
// Handle and buffer used by MQL5
int mHandle;
double mBuffer[];
public:
CIndicatorBase();
~CIndicatorBase();
bool IsValid() { return(mHandle!=INVALID_HANDLE); }
int GetArray(int bufferNumber, int start, int count, double &arr[]); // Retrieve an array of values
virtual double GetValue(int bufferNumber, int index); // Retrieve a single value
virtual double GetValue(int index) { return(GetValue(0,index)); } // Some indicators have only 1 buffer
};
CIndicatorBase::CIndicatorBase() {
// child classes will set the handle
mHandle = 0;
ArraySetAsSeries(mBuffer, true);
}
CIndicatorBase::~CIndicatorBase() {
#ifdef __MQL5__
IndicatorRelease(mHandle);
#endif
}
#ifdef __MQL4__
// Just a blank function for the base class
double CIndicatorBase::GetValue(int bufferNumber, int index) {
return(0);
}
// For mql4 we have to build up the array from individual calls
int CIndicatorBase::GetArray(int bufferNumber,int start,int count,double &arr[]) {
ArraySetAsSeries(arr, true);
ArrayResize(arr, count);
for (int i=0; i<count; i++) {
arr[i] = GetValue(bufferNumber, i+start);
}
return(count);
}
#endif
#ifdef __MQL5__
// In mql5 get the array first then pull a single value
// Could be done by calling GetArray but there is no need
double CIndicatorBase::GetValue(int bufferNumber, int index) {
int result = CopyBuffer(mHandle, bufferNumber, index, 1, mBuffer);
if (result<1) return(0);
return(mBuffer[0]);
}
// For mql5 the array is the natural return
int CIndicatorBase::GetArray(int bufferNumber,int start,int count,double &arr[]) {
ArraySetAsSeries(arr, true);
int result = CopyBuffer(mHandle, bufferNumber, start, count, arr);
return(result);
}
#endif
This is the MACD class which can be used as a template for other indicator classes
/*
IndicatorMACD.mqh
Copyright 2021, Orchard Forex
https://orchardforex.com
*/
#property copyright "Copyright 2021, Orchard Forex"
#property link "http://orchardforex.com"
#property version "1.00"
#include "IndicatorBase.mqh"
/*
CIndicatorMACD
Usage: CIndicatorMACD MACD = new CIndicatorMACD(symbol, timeframe, fastPeriod, slowPeriod, signalPeriod, appliedPrice)
*/
class CIndicatorMACD : public CIndicatorBase {
private:
protected:
int mFastPeriod;
int mSlowPeriod;
int mSignalPeriod;
int mAppliedPrice;
public:
CIndicatorMACD(string symbol, int timeframe, int fastPeriod, int slowPeriod, int signalPeriod, int appliedPrice);
~CIndicatorMACD();
#ifdef __MQL4__
double GetValue(int bufferNumber, int index);
#endif
};
CIndicatorMACD::CIndicatorMACD(string symbol, int timeframe, int fastPeriod, int slowPeriod, int signalPeriod, int appliedPrice)
: CIndicatorBase() {
// Only needed for mql4 but no harm for mql5
mSymbol = symbol;
mTimeframe = timeframe;
mFastPeriod = fastPeriod;
mSlowPeriod = slowPeriod;
mSignalPeriod = signalPeriod;
mAppliedPrice = appliedPrice;
#ifdef __MQL5__
mHandle = iMACD(symbol, (ENUM_TIMEFRAMES)timeframe, fastPeriod, slowPeriod, signalPeriod, appliedPrice);
#endif
}
CIndicatorMACD::~CIndicatorMACD() {
}
#ifdef __MQL4__
double CIndicatorMACD::GetValue(int bufferNumber, int index) {
double result = iMACD(mSymbol, mTimeframe, mFastPeriod, mSlowPeriod, mSignalPeriod, mAppliedPrice, bufferNumber, index);
return(result);
}
#endif
Hi
How can I get a premium membership? How much is it cost / month and what are the benefits I will get from it ?
I am trying to look at the Subscription button, but it does not open any links for membership.
Thanks
The button to subscribe to premium membership is on the page http://orchardforex.com/orchard-forex-discord/
That page also describes the subscription cost and what we offer.
If the upgrade button is not working (perhaps a popup blocker or similar) use https://upgrade.chat/orchard-forex-server
hi, if i need my EA to trade only once per candle like when it reaches 10 points above / below open[0], how can i make that function because the newbar() function only work at the beginning of new candle not on my condition.