Files
MQL5Data/Classes/x-saherelm.xstrategy.class.mq5
T
2024-07-17 19:23:17 +03:30

655 lines
13 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 "../Libraries/x-saherelm.tools.lib.mq5"
#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 _useTPSLAsPoint = false, // Converts TP and SL by Provided Points
bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points
double _tpPoint = 0, // TP As Point
double _slPoint = 0, // SL As Point
bool _allowLong = true,
bool _allowShort = true,
int _maxAllowedLongs = 0,
int _maxAllowedShorts = 0 //
)
{
//
// Fill Properties ...
mR2R = _r2r;
mVolume = _volume;
mSymbol = _symbol;
mPeriod = _period;
mTPPoint = _tpPoint;
mSLPoint = _slPoint;
mSlippage = _slippage;
mAllowLong = _allowLong;
mAllowShort = _allowShort;
mMagicNumber = _magicNumber;
mUseTPSLAsPoint = _useTPSLAsPoint;
mMaxAllowedLongs = _maxAllowedLongs;
mMaxAllowedShorts = _maxAllowedShorts;
mForceMaxTPSLAsPoint = _forceMaxTPSLAsPoint;
//
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;
}
//
bool UseTPSLAsPoint()
{
return mUseTPSLAsPoint;
}
//
void UseTPSLAsPoint(bool value)
{
mUseTPSLAsPoint = value;
}
//
bool ForceMaxTPSLAsPoint()
{
return mForceMaxTPSLAsPoint;
}
//
void ForceMaxTPSLAsPoint(bool value)
{
mForceMaxTPSLAsPoint = value;
}
//
double TPPoint()
{
return mTPPoint;
}
//
void TPPoint(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mTPPoint = value;
}
//
double SLPoint()
{
return mSLPoint;
}
//
void SLPoint(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mSLPoint = 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;
}
}
//
// Check TP and SL ...
double points = GetPoints(signal.symbol);
if (mUseTPSLAsPoint)
{
//
double sl = 0;
double tp = 0;
bool isCalculated = !(mSLPoint > 0 || mTPPoint > 0)
? false
: CalculateTPSLByPoint(
sl,
tp,
signal.type,
signal.entry,
points,
mR2R,
mSLPoint,
mTPPoint //
);
if (isCalculated)
{
//
signal.sl = sl;
signal.tp = tp;
}
}
else if (mForceMaxTPSLAsPoint)
{
//
if (mSLPoint > 0)
{
//
double risk = signal.GetRisk();
double riskPoints = risk / points;
//
if (riskPoints > mSLPoint)
{
//
signal.sl =
isLong
? signal.entry - (mSLPoint * points)
: signal.entry + (mSLPoint * points);
}
}
//
if (mTPPoint > 0)
{
//
double reward = signal.GetReward();
double rewardPoints = reward / points;
//
if (rewardPoints > mTPPoint)
{
//
signal.tp =
isLong
? signal.entry + (mTPPoint * points)
: signal.entry - (mTPPoint * points);
}
}
}
//
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
//
bool mUseTPSLAsPoint; // Converts TP and SL by Provided Points
bool mForceMaxTPSLAsPoint; // Force Max TP and SL by Provided Points
double mTPPoint; // TP As Point
double mSLPoint; // SL As Point
//
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 ...
};
//