Organize project in different folders

This commit is contained in:
Nkondog A. Venceslas
2022-11-28 16:07:29 +01:00
parent 2f87fb5e3f
commit cbb412a720
244 changed files with 9 additions and 4 deletions
@@ -0,0 +1,71 @@
/*
CommonBase.mqh
For framework version 1.0
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
class CCommonBase {
private:
protected: // Members
int mDigits;
string mSymbol;
ENUM_TIMEFRAMES mTimeframe;
string mInitMessage;
int mInitResult;
protected: // Constructors
//
// Constructors
//
CCommonBase() { Init(_Symbol, (ENUM_TIMEFRAMES)_Period); }
CCommonBase(string symbol) { Init(symbol, (ENUM_TIMEFRAMES)_Period); }
CCommonBase(int timeframe) { Init(_Symbol, (ENUM_TIMEFRAMES)timeframe); }
CCommonBase(ENUM_TIMEFRAMES timeframe) { Init(_Symbol, timeframe); }
CCommonBase(string symbol, int timeframe) { Init(symbol, (ENUM_TIMEFRAMES)timeframe); }
CCommonBase(string symbol, ENUM_TIMEFRAMES timeframe) { Init(symbol, timeframe); }
//
// Destructors
//
~CCommonBase() {};
int Init(string symbol, ENUM_TIMEFRAMES timeframe);
protected: // Functions
int InitError(string initMessage, int initResult)
{ mInitMessage = initMessage;
mInitResult = initResult;
return(initResult); }
public: // Properties
int InitResult() { return(mInitResult); }
string InitMessage() { return(mInitMessage); }
public: // Functions
bool TradeAllowed() { return(SymbolInfoInteger(mSymbol, SYMBOL_TRADE_MODE)!=SYMBOL_TRADE_MODE_DISABLED); }
};
int CCommonBase::Init(string symbol, ENUM_TIMEFRAMES timeframe) {
InitError("", INIT_SUCCEEDED);
mSymbol = symbol;
mTimeframe = timeframe;
mDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
return(INIT_SUCCEEDED);
}
@@ -0,0 +1,193 @@
/*
ExpertBase.mqh
For framework version 1.0
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#include "CommonBase.mqh"
#include "Signals/SignalBase.mqh"
#include "Trade/Trade.mqh"
class CExpertBase : public CCommonBase {
protected:
int mMagicNumber;
string mTradeComment;
double mVolume;
datetime mLastBarTime;
datetime mBarTime;
CSignalBase *mEntrySignal;
CSignalBase *mExitSignal;
CTradeCustom Trade;
private:
protected:
virtual bool LoopMain(bool newBar, bool firstTime);
protected:
int Init(int magicNumber, string tradeComment);
public:
//
// Constructors
//
CExpertBase() : CCommonBase()
{ Init(0, ""); }
CExpertBase(string symbol, int timeframe, int magicNumber, string tradeComment)
: CCommonBase(symbol, timeframe)
{ Init(magicNumber, tradeComment); }
CExpertBase(string symbol, ENUM_TIMEFRAMES timeframe, int magicNumber, string tradeComment)
: CCommonBase(symbol, timeframe)
{ Init(magicNumber, tradeComment); }
CExpertBase(int magicNumber, string tradeComment)
: CCommonBase()
{ Init(magicNumber, tradeComment); }
//
// Destructors
//
~CExpertBase();
public: // Default properties
//
// Assign the default values to the expert
//
virtual void SetVolume(double volume) { mVolume = volume; }
virtual void SetTradeComment(string comment) { mTradeComment = comment; }
virtual void SetMagic(int magicNumber) { mMagicNumber = magicNumber;
Trade.SetExpertMagicNumber(magicNumber); }
public: // Setup
virtual void AddEntrySignal(CSignalBase *signal) { mEntrySignal=signal; }
virtual void AddExitSignal(CSignalBase *signal) { mExitSignal=signal; }
public: // Event handlers
virtual int OnInit() { return(InitResult()); }
virtual void OnTick();
virtual void OnTimer() { return; }
virtual double OnTester() { return(0.0); }
virtual void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {};
#ifdef __MQL5__
virtual void OnTrade() { return; }
virtual void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{ return; }
virtual void OnTesterInit() { return; }
virtual void OnTesterPass() { return; }
virtual void OnTesterDeinit() { return; }
virtual void OnBookEvent() { return; }
#endif
};
CExpertBase::~CExpertBase() {
}
int CExpertBase::Init(int magicNumber, string tradeComment) {
if (mInitResult!=INIT_SUCCEEDED) return(mInitResult);
mTradeComment = tradeComment;
SetMagic(magicNumber);
mLastBarTime = 0;
return(INIT_SUCCEEDED);
}
void CExpertBase::OnTick(void) {
if (!TradeAllowed()) return;
mBarTime = iTime(mSymbol, mTimeframe, 0);
bool firstTime = (mLastBarTime==0);
bool newBar = (mBarTime!=mLastBarTime);
if (LoopMain(newBar, firstTime)) {
mLastBarTime = mBarTime;
}
return;
}
bool CExpertBase::LoopMain(bool newBar,bool firstTime) {
//
// To start I will only trade on a new bar
// and not on the first bar after start
//
if (!newBar) return(true);
if (firstTime) return(true);
//
// Update the signals
//
if (mEntrySignal!=NULL) mEntrySignal.UpdateSignal();
if (mEntrySignal!=mExitSignal) {
if (mExitSignal!=NULL) mExitSignal.UpdateSignal();
}
//
// Should any trades be closed
//
if (mExitSignal!=NULL) {
if (mExitSignal.ExitSignal()==OFX_SIGNAL_BOTH) {
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY);
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL);
} else
if (mExitSignal.ExitSignal()==OFX_SIGNAL_BUY) {
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY);
} else
if (mExitSignal.ExitSignal()==OFX_SIGNAL_SELL) {
Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL);
}
}
//
// Should a trade be opened
//
if (mEntrySignal!=NULL) {
if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BOTH) {
Trade.Buy(mVolume, mSymbol);
Trade.Sell(mVolume, mSymbol);
} else
if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BUY) {
Trade.Buy(mVolume, mSymbol);
} else
if (mEntrySignal.EntrySignal()==OFX_SIGNAL_SELL) {
Trade.Sell(mVolume, mSymbol);
}
}
return(true);
}
@@ -0,0 +1,19 @@
/*
Framework_1.00.mqh
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#ifndef _FRAMEWORK_VERSION_
#define _FRAMEWORK_VERSION_ "1.00"
#include "CommonBase.mqh"
#include "Indicators/AllIndicators.mqh"
#include "Signals/AllSignals.mqh"
#include "ExpertBase.mqh"
#endif
@@ -0,0 +1,15 @@
/*
AllSignals.mqh
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#include "SignalBase.mqh"
//
// Other signals go here
//
#include "Crossover/SignalCrossover.mqh"
@@ -0,0 +1,78 @@
/*
SignalCrossover.mqh
For framework version 1.0
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#include "../SignalBase.mqh"
class CSignalCrossover : public CSignalBase {
private:
protected: // member variables
int mIndex1;
int mIndex2;
public: // constructors
CSignalCrossover(string symbol, ENUM_TIMEFRAMES timeframe,
int index1=1, int index2=2)
: CSignalBase(symbol, timeframe)
{ Init(index1, index2); }
CSignalCrossover(int index1=1, int index2=2)
: CSignalBase()
{ Init(index1, index2); }
~CSignalCrossover() { }
int Init(int index1, int index2);
public:
virtual void UpdateSignal();
};
int CSignalCrossover::Init(int index1, int index2) {
if (InitResult()!=INIT_SUCCEEDED) return(InitResult());
mIndex1 = index1;
mIndex2 = index2;
return(INIT_SUCCEEDED);
}
void CSignalCrossover::UpdateSignal() {
double fast1 = GetIndicatorData(0, mIndex1);
double fast2 = GetIndicatorData(0, mIndex2);
double slow1 = GetIndicatorData(1, mIndex1);
double slow2 = GetIndicatorData(1, mIndex2);
// There is a less common condition where the fast
// indicator touches the slow indicator and then
// reverses. With the conditions below this would
// appear like a cross.
if ( (fast1>slow1) && !(fast2>slow2) ) { // Crossed up
mEntrySignal = OFX_SIGNAL_BUY;
mExitSignal = OFX_SIGNAL_SELL;
} else
if ( (fast1<slow1) && !(fast2<slow2) ) { // Crossed down
mEntrySignal = OFX_SIGNAL_SELL;
mExitSignal = OFX_SIGNAL_BUY;
} else {
mEntrySignal = OFX_SIGNAL_NONE;
mExitSignal = OFX_SIGNAL_NONE;
}
return;
}
@@ -0,0 +1,85 @@
/*
SignalBase.mqh
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#include "../CommonBase.mqh"
#include "../Indicators/IndicatorBase.mqh"
struct SIndicatorItem {
CIndicatorBase *indicator;
int bufferNum;
};
enum ENUM_OFX_SIGNAL_DIRECTION {
OFX_SIGNAL_NONE = 0,
OFX_SIGNAL_BUY = 1,
OFX_SIGNAL_SELL = 2,
OFX_SIGNAL_BOTH = 3
};
class CSignalBase : public CCommonBase {
private:
protected: // member variables
ENUM_OFX_SIGNAL_DIRECTION mEntrySignal;
ENUM_OFX_SIGNAL_DIRECTION mExitSignal;
SIndicatorItem mIndicatorList[];
public: // constructors
CSignalBase() : CCommonBase()
{ Init(); }
CSignalBase(string symbol, ENUM_TIMEFRAMES timeframe) : CCommonBase(symbol, timeframe)
{ Init(); }
~CSignalBase() { }
int Init();
public:
virtual void UpdateSignal() { return; }
virtual ENUM_OFX_SIGNAL_DIRECTION EntrySignal() { return(mEntrySignal); }
virtual ENUM_OFX_SIGNAL_DIRECTION ExitSignal() { return(mExitSignal); }
virtual void AddIndicator(CIndicatorBase *indicator, int bufferNum);
virtual double GetIndicatorData(int indicatorNum, int index);
};
int CSignalBase::Init() {
if (InitResult()!=INIT_SUCCEEDED) return(InitResult());
mEntrySignal = OFX_SIGNAL_NONE;
mExitSignal = OFX_SIGNAL_NONE;
return(INIT_SUCCEEDED);
}
void CSignalBase::AddIndicator(CIndicatorBase *indicator, int bufferNum) {
SIndicatorItem indicatorItem = {NULL, 0};
indicatorItem.indicator = indicator;
indicatorItem.bufferNum = bufferNum;
int cnt = ArraySize(mIndicatorList);
ArrayResize(mIndicatorList, cnt+1);
mIndicatorList[cnt] = indicatorItem;
return;
}
double CSignalBase::GetIndicatorData(int indicatorNum,int index) {
return(mIndicatorList[indicatorNum].indicator.GetData(mIndicatorList[indicatorNum].bufferNum, index));
}
@@ -0,0 +1,14 @@
/*
Trade.mqh
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#ifdef __MQL4__
#include "Trade_mql4.mqh"
#endif
#ifdef __MQL5__
#include "Trade_mql5.mqh"
#endif
@@ -0,0 +1,83 @@
/*
Trade.mqh
(For MQL4)
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#include "../CommonBase.mqh"
enum ENUM_POSITION_TYPE {
POSITION_TYPE_BUY = ORDER_TYPE_BUY,
POSITION_TYPE_SELL = ORDER_TYPE_SELL
};
class CTradeCustom : public CCommonBase {
private:
protected: // member variables
int mMagic; // expert magic number
public: // constructors
CTradeCustom();
~CTradeCustom();
public:
ulong RequestMagic() { return(mMagic); }
void SetExpertMagicNumber(const int magic) { mMagic=magic; }
double BuyPrice(string symbol) { return(SymbolInfoDouble(symbol, SYMBOL_ASK)); }
double SellPrice(string symbol) { return(SymbolInfoDouble(symbol, SYMBOL_BID)); }
bool Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="");
bool Sell(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="");
bool PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType,const int deviation=ULONG_MAX);
};
CTradeCustom::CTradeCustom() {
mMagic = 0;
}
CTradeCustom::~CTradeCustom() {
}
bool CTradeCustom::Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="") {
if (price==0.0) price = BuyPrice(symbol);
int ticket = OrderSend(symbol, ORDER_TYPE_BUY, volume, price, 0, sl, tp, comment, mMagic);
return(ticket>0);
}
bool CTradeCustom::Sell(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="") {
if (price==0.0) price = SellPrice(symbol);
int ticket = OrderSend(symbol, ORDER_TYPE_SELL, volume, price, 0, sl, tp, comment, mMagic);
return(ticket>0);
}
bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const int deviation=ULONG_MAX) {
int slippage = (deviation==ULONG_MAX) ? 0 : deviation;
bool result = true;
int cnt = OrdersTotal();
for (int i = cnt-1; i>=0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==symbol && OrderMagicNumber()==mMagic && OrderType()==positionType) {
result &= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage);
}
}
}
return(result);
}
@@ -0,0 +1,44 @@
/*
Trade.mqh
(For MQL5)
Copyright 2013-2020, Orchard Forex
https://www.orchardforex.com
*/
#include <Trade/Trade.mqh>
class CTradeCustom : public CTrade {
private:
protected: // member variables
public: // constructors
public:
bool PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType,const ulong deviation=ULONG_MAX);
};
bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const ulong deviation=ULONG_MAX) {
bool result = true;
int cnt = PositionsTotal();
for (int i = cnt-1; i>=0; i--) {
ulong ticket = PositionGetTicket(i);
if (PositionSelectByTicket(ticket)) {
if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==positionType && PositionGetInteger(POSITION_MAGIC)==m_magic) {
result &= PositionClose(ticket, deviation);
}
} else {
m_result.retcode=TRADE_RETCODE_REJECT;
result = false;
}
}
return(result);
}