512 lines
9.1 KiB
Plaintext
512 lines
9.1 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XSCBaseStrategy
|
|
// Description: provides all based classes for use ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
/// Imports ...
|
|
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
|
#include "../Classes/x-saherelm.xalert.class.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
enum ENUM_X_SIGNALLING_DIRECTION
|
|
{
|
|
X_SIGNALLING_NONE = 0,
|
|
X_SIGNALLING_BOTH_DIRECTIONS = 1,
|
|
X_SIGNALLING_TREND_DIRECTION = 2,
|
|
X_SIGNALIING_TREND_REVERSAL_DIRECTION = 3
|
|
};
|
|
|
|
//
|
|
class XSCBaseStrategy : public XSCBaseAlert
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Constructors ...
|
|
void XSCBaseStrategy(
|
|
string _symbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES _period, // Trading TimeFrame
|
|
double _volume, // Voluem
|
|
double _r2r, // Risk/Reward Ratio
|
|
int _slippage, // Trader Slippage
|
|
long _magicNumber, // Trader Magic Number
|
|
bool _allowLong = true,
|
|
bool _allowShort = true,
|
|
int _maxAllowedLongs = 0,
|
|
int _maxAllowedShorts = 0 //
|
|
)
|
|
{
|
|
//
|
|
// Fill Properties ...
|
|
mR2R = _r2r;
|
|
mVolume = _volume;
|
|
mSymbol = _symbol;
|
|
mPeriod = _period;
|
|
mSlippage = _slippage;
|
|
mAllowLong = _allowLong;
|
|
mAllowShort = _allowShort;
|
|
mMagicNumber = _magicNumber;
|
|
mMaxAllowedLongs = _maxAllowedLongs;
|
|
mMaxAllowedShorts = _maxAllowedShorts;
|
|
|
|
//
|
|
mForceDisabled = false;
|
|
|
|
//
|
|
// Initial Trader Class Instance ...
|
|
trader = new XSCTrade(
|
|
mSlippage,
|
|
mMagicNumber //
|
|
);
|
|
|
|
//
|
|
// Initial Time Tracker ...
|
|
barTracker.Init(
|
|
mSymbol,
|
|
mPeriod //
|
|
);
|
|
|
|
//
|
|
SetAlertPrefix(GetTag());
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XSCBaseStrategy()
|
|
{
|
|
//
|
|
delete trader;
|
|
|
|
//
|
|
Reset();
|
|
}
|
|
|
|
//
|
|
// Getter and Setter (s) ...
|
|
|
|
//
|
|
int Slippage()
|
|
{
|
|
return mSlippage;
|
|
}
|
|
|
|
//
|
|
long MagicNumber()
|
|
{
|
|
return mMagicNumber;
|
|
}
|
|
|
|
//
|
|
string Symbol()
|
|
{
|
|
return mSymbol;
|
|
}
|
|
|
|
//
|
|
ENUM_TIMEFRAMES Period()
|
|
{
|
|
return mPeriod;
|
|
}
|
|
|
|
//
|
|
bool IsDisabled()
|
|
{
|
|
return mForceDisabled;
|
|
}
|
|
|
|
//
|
|
void Disable()
|
|
{
|
|
mForceDisabled = true;
|
|
}
|
|
|
|
//
|
|
void Enable()
|
|
{
|
|
mForceDisabled = false;
|
|
}
|
|
|
|
//
|
|
double Volume()
|
|
{
|
|
return mVolume;
|
|
}
|
|
|
|
//
|
|
void Volume(double value)
|
|
{
|
|
//
|
|
if (value < 0.01)
|
|
{
|
|
value = 0.01;
|
|
}
|
|
|
|
//
|
|
mVolume = value;
|
|
}
|
|
|
|
//
|
|
double R2R()
|
|
{
|
|
return mR2R;
|
|
}
|
|
|
|
//
|
|
bool AllowLong()
|
|
{
|
|
return mAllowLong;
|
|
}
|
|
|
|
//
|
|
void AllowLong(bool value)
|
|
{
|
|
mAllowLong = value;
|
|
}
|
|
|
|
//
|
|
bool AllowShort()
|
|
{
|
|
return mAllowShort;
|
|
}
|
|
|
|
//
|
|
void AllowShort(bool value)
|
|
{
|
|
mAllowShort = value;
|
|
}
|
|
|
|
//
|
|
int MaxAllowedLongs()
|
|
{
|
|
return mMaxAllowedLongs;
|
|
}
|
|
|
|
//
|
|
void MaxAllowedLongs(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMaxAllowedLongs = value;
|
|
}
|
|
|
|
//
|
|
int MaxAllowedShorts()
|
|
{
|
|
return mMaxAllowedShorts;
|
|
}
|
|
|
|
//
|
|
void MaxAllowedShorts(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMaxAllowedShorts = value;
|
|
}
|
|
|
|
//
|
|
int RequiredPivots()
|
|
{
|
|
return mRequiredPivots;
|
|
}
|
|
|
|
//
|
|
void RequiredPivots(int value)
|
|
{
|
|
//
|
|
if (value < 3)
|
|
{
|
|
value = 3;
|
|
}
|
|
|
|
//
|
|
mRequiredPivots = value;
|
|
}
|
|
|
|
//
|
|
int RequiredShoulders()
|
|
{
|
|
return mRequiredShoulders;
|
|
}
|
|
|
|
//
|
|
void RequiredShoulders(int value)
|
|
{
|
|
//
|
|
if (value < 5)
|
|
{
|
|
value = 5;
|
|
}
|
|
|
|
//
|
|
mRequiredShoulders = value;
|
|
}
|
|
|
|
//
|
|
// Virtual Methods ...
|
|
|
|
//
|
|
// Tag ...
|
|
virtual string GetTag()
|
|
{
|
|
return "XBaseStrategy";
|
|
}
|
|
|
|
//
|
|
// Check Conditions for Signal ...
|
|
// this must be Override based on each Strategy ...
|
|
virtual bool HasSignal(
|
|
XSignal &signal //
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Check Conditions For Signal and Execute Signal ...
|
|
virtual void HandleTick()
|
|
{
|
|
//
|
|
if (IsDisabled())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (!AllowLong() && !AllowShort())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (!barTracker.CanProcessBar())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
MqlTick cTick;
|
|
bool hasTick = GetTick(
|
|
mSymbol,
|
|
cTick //
|
|
);
|
|
bool isSameAsLast = cTick.time == lastTick.time;
|
|
if (isSameAsLast)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
lastTick = cTick;
|
|
|
|
//
|
|
XSignal signal;
|
|
bool hasSignal = HasSignal(signal);
|
|
if (!hasSignal)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
barTracker.Waits();
|
|
|
|
//
|
|
Execute(signal);
|
|
}
|
|
|
|
//
|
|
// Handle Signal Execution ...
|
|
virtual bool Execute(XSignal &signal)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = !IsDisabled();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = signal.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isLong = IsLong(signal.type);
|
|
|
|
//
|
|
result =
|
|
//
|
|
isLong
|
|
? AllowLong()
|
|
: AllowShort()
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Max Allowed Trades Limitation ...
|
|
if (
|
|
(isLong && MaxAllowedLongs() > 0) ||
|
|
(!isLong && MaxAllowedShorts() > 0))
|
|
{
|
|
//
|
|
// Here We Have to Count Positions ...
|
|
|
|
//
|
|
// Get and Count Positions ...
|
|
XPosition positions[];
|
|
int positionsCount = trader.GetPositions(
|
|
positions //
|
|
);
|
|
|
|
//
|
|
// Get and Count Lng and Short Positions ...
|
|
XPosition longs[];
|
|
XPosition shorts[];
|
|
ExtractPositions(
|
|
positions,
|
|
longs,
|
|
shorts //
|
|
);
|
|
int longsCount = ArraySize(longs);
|
|
int shortsCount = ArraySize(shorts);
|
|
|
|
//
|
|
result =
|
|
//
|
|
isLong
|
|
? longsCount < MaxAllowedLongs()
|
|
: shortsCount < MaxAllowedShorts()
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
ENUM_X_SIGNAL_EXECUTION_RESULT state;
|
|
result = trader.ExecuteSignal(
|
|
signal,
|
|
state //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
string message = "Execute " + (isLong ? "Long" : "Short") + " " + signal.symbol + "/" + ToString(signal.period) + " ...";
|
|
Alert(message);
|
|
|
|
//
|
|
OnSignalExecuted(signal);
|
|
}
|
|
else
|
|
{
|
|
OnSignalExecutionFailed(signal, state);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calls When a Signal Executed Successfully ...
|
|
virtual void OnSignalExecuted(XSignal &signal)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Calls When a Signal Execution Failed ...
|
|
virtual void OnSignalExecutionFailed(
|
|
XSignal &signal,
|
|
ENUM_X_SIGNAL_EXECUTION_RESULT result //
|
|
)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
int mSlippage; // Trader Slippage
|
|
long mMagicNumber; // Trader Magic Number
|
|
bool mForceDisabled; // Force Disabled
|
|
bool mAllowLong; // Allow Long Signals
|
|
bool mAllowShort; // Allow Short Signals
|
|
int mMaxAllowedLongs; // Max Allowed Longs
|
|
int mMaxAllowedShorts; // Max Allowed Shorts
|
|
|
|
//
|
|
string mSymbol; // Trading Symbol ...
|
|
ENUM_TIMEFRAMES mPeriod; // Trading TimeFrame ...
|
|
|
|
//
|
|
double mR2R; // Risk/Rewar Ratio ...
|
|
double mVolume; // Static Volume Per Trades ...
|
|
|
|
//
|
|
XBarTracker barTracker; // Strategy Time Tracker ...
|
|
|
|
//
|
|
// Trend Detecting ...
|
|
int mRequiredPivots; // Required Pivots For Trend Detecting ...
|
|
int mRequiredShoulders; // Required Pivots Shoulders ...
|
|
|
|
//
|
|
XSCTrade *trader;
|
|
|
|
//
|
|
MqlTick lastTick;
|
|
|
|
//
|
|
void Reset()
|
|
{
|
|
barTracker.Clean();
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
};
|
|
|
|
// |