792 lines
19 KiB
Plaintext
792 lines
19 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XSCXSRBRStrategy
|
|
// 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.xstrategy.class.mq5"
|
|
|
|
//
|
|
string XSRBRStartegyToken = "XSRBR";
|
|
|
|
//
|
|
class XSCXSRBRStrategy : public XSCBaseStrategy
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Constructor(s) ...
|
|
void XSCXSRBRStrategy(
|
|
//
|
|
// Base ...
|
|
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 //
|
|
) : XSCBaseStrategy(_symbol,
|
|
_period,
|
|
_volume,
|
|
_r2r,
|
|
_slippage,
|
|
_magicNumber,
|
|
_allowLong,
|
|
_allowShort,
|
|
_maxAllowedLongs,
|
|
_maxAllowedShorts //
|
|
)
|
|
{
|
|
//
|
|
mThreshold = 5;
|
|
mVerificationsStep = 21;
|
|
mConditionsValidationAge = 20;
|
|
|
|
//
|
|
SetAlertPrefix(XSRBRStartegyToken);
|
|
}
|
|
|
|
//
|
|
// Getter / Setter (s) ...
|
|
|
|
//
|
|
double Treshold()
|
|
{
|
|
return mThreshold;
|
|
}
|
|
|
|
//
|
|
void Treshold(double value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mThreshold = value;
|
|
}
|
|
|
|
//
|
|
int VerificationsStep()
|
|
{
|
|
return mVerificationsStep;
|
|
}
|
|
|
|
//
|
|
void VerificationsStep(int value)
|
|
{
|
|
//
|
|
if (value < 5)
|
|
{
|
|
value = 5;
|
|
}
|
|
|
|
//
|
|
mVerificationsStep = value;
|
|
}
|
|
|
|
//
|
|
int ConditionsValidationAge()
|
|
{
|
|
return mConditionsValidationAge;
|
|
}
|
|
|
|
//
|
|
void ConditionsValidationAge(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mConditionsValidationAge = value;
|
|
}
|
|
|
|
//
|
|
bool DarwSupportAndResistances()
|
|
{
|
|
return mDarwSupportAndResistances;
|
|
}
|
|
|
|
//
|
|
void DarwSupportAndResistances(bool value)
|
|
{
|
|
//
|
|
mDarwSupportAndResistances = value;
|
|
|
|
//
|
|
if (!value)
|
|
{
|
|
//
|
|
supportPivot.Remove();
|
|
resistancePivot.Remove();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Overrides ...
|
|
|
|
//
|
|
// Customize Strategy Identifier ...
|
|
string GetTag() override
|
|
{
|
|
return XSRBRStartegyToken;
|
|
}
|
|
|
|
//
|
|
// Check Conditions For Signal ...
|
|
bool HasSignal(
|
|
XSignal &signal //
|
|
) override
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Try to Detect Trend ...
|
|
result = trendDetector.HasTrend();
|
|
if (!result)
|
|
{
|
|
//
|
|
result = trendDetector.FindTrend(
|
|
mSymbol,
|
|
mPeriod //
|
|
);
|
|
|
|
//
|
|
if (!result ||
|
|
(!trendDetector.isUpTrend && !trendDetector.isDownTrend))
|
|
{
|
|
//
|
|
trendDetector.Clean();
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Resistance Exists or not ...
|
|
// if Not, Try to Find One ...
|
|
if (!resistancePivot.isResistance)
|
|
{
|
|
//
|
|
result = resistancePivot.FindLastResistance(
|
|
mSymbol,
|
|
mPeriod //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
//
|
|
resistancePivot.Clean();
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
if (DarwSupportAndResistances())
|
|
{
|
|
resistancePivot.Draw(ChartID());
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Support Exists or not ...
|
|
// if Not, try to Find One ...
|
|
if (!supportPivot.isSupport)
|
|
{
|
|
//
|
|
result = supportPivot.FindLastSupport(
|
|
mSymbol,
|
|
mPeriod //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
//
|
|
supportPivot.Clean();
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
if (DarwSupportAndResistances())
|
|
{
|
|
supportPivot.Draw(ChartID());
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Retrieve Bar 1 ...
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
1 //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
CheckConditionLife();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
signal.Clean();
|
|
|
|
//
|
|
double sl = 0;
|
|
double tp = 0;
|
|
double risk = 0;
|
|
double entry = 0;
|
|
double reward = 0;
|
|
double r2r = R2R();
|
|
ENUM_POSITION_TYPE type;
|
|
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
|
|
|
//
|
|
bool isSupportBreaked = supportPivot.IsBreaked();
|
|
bool isSupportRejected = supportPivot.IsRejected();
|
|
|
|
//
|
|
bool isResistancetBreaked = resistancePivot.IsBreaked();
|
|
bool isResistancetRejected = resistancePivot.IsRejected();
|
|
|
|
//
|
|
bool isBarBullishPattern =
|
|
//
|
|
cBar.IsBullish() &&
|
|
cBar.HasStrongBody() &&
|
|
(cBar.IsHammer() ||
|
|
cBar.IsBullishEngulf())
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBarBearishPattern =
|
|
//
|
|
cBar.IsBearish() &&
|
|
cBar.HasStrongBody() &&
|
|
(cBar.IsShootingStar() ||
|
|
cBar.IsBearishEngulf())
|
|
//
|
|
;
|
|
|
|
//
|
|
// Up Trend ...
|
|
if (trendDetector.isUpTrend)
|
|
{
|
|
//
|
|
// During Up Trend ...
|
|
// Supports Must Rejected ...
|
|
// Resistance Must Breaked ...
|
|
|
|
//
|
|
// Check Trend Trading ...
|
|
// Check Based Support ...
|
|
bool hasSupportLong =
|
|
//
|
|
isSupportRejected &&
|
|
isBarBullishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Trading ...
|
|
// Check Based On Resistance ...
|
|
bool hasResistanceLong =
|
|
//
|
|
isResistancetBreaked &&
|
|
isBarBullishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Reversal Trading ...
|
|
// Check Based Support ...
|
|
bool hasSupportShort =
|
|
//
|
|
isSupportBreaked &&
|
|
isBarBearishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Reversal Trading ...
|
|
// Check Based On Resistance ...
|
|
bool hasResistanceShort =
|
|
//
|
|
isResistancetRejected &&
|
|
isBarBearishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Trading ...
|
|
bool hasLong =
|
|
//
|
|
hasSupportLong ||
|
|
hasResistanceLong
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Reversal Trading ...
|
|
bool hasShort =
|
|
//
|
|
hasSupportShort ||
|
|
hasResistanceShort
|
|
//
|
|
;
|
|
|
|
//
|
|
// Filling Signal ...
|
|
if (hasLong)
|
|
{
|
|
//
|
|
type = POSITION_TYPE_BUY;
|
|
entry = GetEntry(
|
|
_Symbol,
|
|
type //
|
|
);
|
|
|
|
//
|
|
if (hasSupportLong)
|
|
{
|
|
//
|
|
sl = supportPivot.price;
|
|
if (supportPivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
|
sl -= threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
else if (hasResistanceLong)
|
|
{
|
|
//
|
|
sl = resistancePivot.price;
|
|
if (resistancePivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
|
sl -= threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
|
|
//
|
|
result = signal.Prepare(
|
|
_Symbol,
|
|
"XSUPRES",
|
|
_Period,
|
|
type,
|
|
mode,
|
|
entry,
|
|
mVolume,
|
|
sl,
|
|
tp //
|
|
);
|
|
}
|
|
else if (hasShort)
|
|
{
|
|
//
|
|
type = POSITION_TYPE_SELL;
|
|
entry = GetEntry(
|
|
_Symbol,
|
|
type //
|
|
);
|
|
|
|
//
|
|
if (hasSupportShort)
|
|
{
|
|
//
|
|
sl = supportPivot.price;
|
|
if (supportPivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
|
sl += threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
else if (hasResistanceShort)
|
|
{
|
|
//
|
|
sl = resistancePivot.price;
|
|
if (resistancePivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
|
sl += threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
|
|
//
|
|
result = signal.Prepare(
|
|
_Symbol,
|
|
"XSUPRES",
|
|
_Period,
|
|
type,
|
|
mode,
|
|
entry,
|
|
mVolume,
|
|
sl,
|
|
tp //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
result = false;
|
|
}
|
|
}
|
|
//
|
|
// Down Trend ...
|
|
else if (trendDetector.isDownTrend)
|
|
{
|
|
//
|
|
// During Down Trend ...
|
|
// Supports Must Breaked ...
|
|
// Resistance Must Rejected ...
|
|
|
|
//
|
|
// Check Trend Reversal Trading ...
|
|
// Check Based Support ...
|
|
bool hasSupportLong =
|
|
//
|
|
isSupportRejected &&
|
|
isBarBullishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Reversal Trading ...
|
|
// Check Based On Resistance ...
|
|
bool hasResistanceLong =
|
|
//
|
|
isResistancetBreaked &&
|
|
isBarBullishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Trading ...
|
|
// Check Based Support ...
|
|
bool hasSupportShort =
|
|
//
|
|
isSupportBreaked &&
|
|
isBarBearishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Trading ...
|
|
// Check Based On Resistance ...
|
|
bool hasResistanceShort =
|
|
//
|
|
isResistancetRejected &&
|
|
isBarBearishPattern
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Reversal Trading ...
|
|
bool hasLong =
|
|
//
|
|
hasSupportLong ||
|
|
hasResistanceLong
|
|
//
|
|
;
|
|
|
|
//
|
|
// Check Trend Trading ...
|
|
bool hasShort =
|
|
//
|
|
hasSupportShort ||
|
|
hasResistanceShort
|
|
//
|
|
;
|
|
|
|
//
|
|
// Filling Signal ...
|
|
if (hasLong)
|
|
{
|
|
//
|
|
type = POSITION_TYPE_BUY;
|
|
entry = GetEntry(
|
|
_Symbol,
|
|
type //
|
|
);
|
|
|
|
//
|
|
if (hasSupportLong)
|
|
{
|
|
//
|
|
sl = supportPivot.price;
|
|
if (supportPivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
|
sl -= threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
else if (hasResistanceLong)
|
|
{
|
|
//
|
|
sl = resistancePivot.price;
|
|
if (resistancePivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
|
sl -= threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
|
|
//
|
|
result = signal.Prepare(
|
|
_Symbol,
|
|
"XSUPRES",
|
|
_Period,
|
|
type,
|
|
mode,
|
|
entry,
|
|
mVolume,
|
|
sl,
|
|
tp //
|
|
);
|
|
}
|
|
else if (hasShort)
|
|
{
|
|
//
|
|
type = POSITION_TYPE_SELL;
|
|
entry = GetEntry(
|
|
_Symbol,
|
|
type //
|
|
);
|
|
|
|
//
|
|
if (hasSupportShort)
|
|
{
|
|
//
|
|
sl = supportPivot.price;
|
|
if (supportPivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * supportPivot._threshold;
|
|
sl += threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
else if (hasResistanceShort)
|
|
{
|
|
//
|
|
sl = resistancePivot.price;
|
|
if (resistancePivot._threshold > 0)
|
|
{
|
|
//
|
|
double threshold = GetPoints(_Symbol) * resistancePivot._threshold;
|
|
sl += threshold;
|
|
}
|
|
|
|
//
|
|
CalculateTPSLBtPrice(
|
|
sl,
|
|
tp,
|
|
type,
|
|
entry,
|
|
r2r //
|
|
);
|
|
}
|
|
|
|
//
|
|
result = signal.Prepare(
|
|
_Symbol,
|
|
"XSUPRES",
|
|
_Period,
|
|
type,
|
|
mode,
|
|
entry,
|
|
mVolume,
|
|
sl,
|
|
tp //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
result = false;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
CheckConditionLife();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Notify Signal Execution ...
|
|
void OnSignalExecuted(XSignal &signal) override
|
|
{
|
|
ResetConditions();
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Pivots Detecting ...
|
|
double mThreshold; // Pivots Edge's Threshold ...
|
|
int mVerificationsStep; // Pivots Verification Steps ...
|
|
int mConditionsValidationAge; // How Many Bars a Support or Resistance is Valid ...
|
|
|
|
//
|
|
XPivot supportPivot;
|
|
XPivot resistancePivot;
|
|
|
|
//
|
|
bool mDarwSupportAndResistances; // Draw Last Found Support and Resistance
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Check Conditions Time Life ...
|
|
void CheckConditionLife()
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
datetime lTime =
|
|
//
|
|
supportPivot.time < resistancePivot.time
|
|
? supportPivot.time
|
|
: resistancePivot.time
|
|
//
|
|
;
|
|
|
|
//
|
|
bool canReset =
|
|
//
|
|
(
|
|
//
|
|
(((int)cTime - (int)lTime) / PeriodSeconds(mPeriod)) > mConditionsValidationAge
|
|
//
|
|
)
|
|
//
|
|
;
|
|
if (canReset)
|
|
{
|
|
ResetConditions();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Reset Conditions ...
|
|
void ResetConditions()
|
|
{
|
|
//
|
|
trendDetector.Clean();
|
|
|
|
//
|
|
supportPivot.Remove();
|
|
supportPivot.Clean();
|
|
|
|
//
|
|
resistancePivot.Remove();
|
|
resistancePivot.Clean();
|
|
}
|
|
};
|
|
|
|
// |