backup all works even x121 ...
This commit is contained in:
@@ -0,0 +1,763 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 _ignoreSignalExecution = false, // Ignore Signal Execution
|
||||
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 _ignoreTP = false, // TP set to 0
|
||||
bool _ignoreSL = false, // SL set to 0
|
||||
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;
|
||||
mIgnoreTP = _ignoreTP;
|
||||
mIgnoreSL = _ignoreSL;
|
||||
mSlippage = _slippage;
|
||||
mAllowLong = _allowLong;
|
||||
mAllowShort = _allowShort;
|
||||
mMagicNumber = _magicNumber;
|
||||
mUseTPSLAsPoint = _useTPSLAsPoint;
|
||||
mMaxAllowedLongs = _maxAllowedLongs;
|
||||
mMaxAllowedShorts = _maxAllowedShorts;
|
||||
mForceMaxTPSLAsPoint = _forceMaxTPSLAsPoint;
|
||||
mIgnoreSignalExecution = _ignoreSignalExecution;
|
||||
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
bool IgnoreTP()
|
||||
{
|
||||
return mIgnoreTP;
|
||||
}
|
||||
|
||||
//
|
||||
void IgnoreTP(bool value)
|
||||
{
|
||||
mIgnoreTP = value;
|
||||
}
|
||||
|
||||
//
|
||||
bool IgnoreSL()
|
||||
{
|
||||
return mIgnoreSL;
|
||||
}
|
||||
|
||||
//
|
||||
void IgnoreSL(bool value)
|
||||
{
|
||||
mIgnoreSL = value;
|
||||
}
|
||||
|
||||
//
|
||||
bool IgnoreSignalExecution()
|
||||
{
|
||||
return mIgnoreSignalExecution;
|
||||
}
|
||||
|
||||
//
|
||||
void IgnoreSignalExecution(bool value)
|
||||
{
|
||||
mIgnoreSignalExecution = value;
|
||||
}
|
||||
|
||||
//
|
||||
// On Signal Handlers ...
|
||||
void AddSignalEventHandler(TOnSignal handler)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
handler,
|
||||
mOnSignalEventHandlers //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (mIgnoreTP)
|
||||
{
|
||||
signal.tp = 0;
|
||||
}
|
||||
|
||||
//
|
||||
if (mIgnoreSL)
|
||||
{
|
||||
signal.sl = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Notify Signal Event Handler(s) ...
|
||||
NotifyOnSignalEventHandlers(signal);
|
||||
|
||||
//
|
||||
// Check Signal Execution Enabled or not ...
|
||||
result = !mIgnoreSignalExecution;
|
||||
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
|
||||
|
||||
//
|
||||
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
|
||||
bool mIgnoreTP; // TP set to 0
|
||||
bool mIgnoreSL; // SL set to 0
|
||||
bool mIgnoreSignalExecution; // Ignore Signal Execution
|
||||
|
||||
//
|
||||
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();
|
||||
}
|
||||
|
||||
//
|
||||
// Notified Signal Event Handler(s) ...
|
||||
void NotifyOnSignalEventHandlers(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (!signal.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int count = ArraySize(mOnSignalEventHandlers);
|
||||
if (!IsValidSize(count))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
mOnSignalEventHandlers[i](signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Private ...
|
||||
private:
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
// On Signal Recieved Event Handler(s) ...
|
||||
TOnSignal mOnSignalEventHandlers[];
|
||||
};
|
||||
|
||||
//
|
||||
Reference in New Issue
Block a user