last ...
This commit is contained in:
@@ -265,7 +265,7 @@ void OnTick()
|
||||
// Handle On Trade Event ...
|
||||
void OnTrade()
|
||||
{
|
||||
eaExpert.HandleOnTrade();
|
||||
eaExpert.HandleOnTrade();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -7528,6 +7528,86 @@ bool IsBelowBox(
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a Box is Used or not ...
|
||||
*
|
||||
* @param box: XBoxZone instance Reference ...
|
||||
* @param fromIndex: int ...
|
||||
* @param toIndex: int
|
||||
* @param forPeriod: Specified Period ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsBoxUsed(
|
||||
XBoxZone &box,
|
||||
int fromIndex,
|
||||
int toIndex = 0,
|
||||
ENUM_TIMEFRAMES forPeriod = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (toIndex < 0)
|
||||
{
|
||||
toIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
box.IsValid()
|
||||
fromIndex > 0 &&
|
||||
fromIndex > toIndex
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
if (!IsValid(forPeriod))
|
||||
{
|
||||
forPeriod = box.period;
|
||||
}
|
||||
|
||||
//
|
||||
EUM_X_DIRECT forDir = box.dir;
|
||||
bool isBllish = IsBullish(forDir);
|
||||
|
||||
//
|
||||
for (int i = fromIndex; i >= toIndex; i--)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
bool isInited = iBar.Init(
|
||||
box.symbol,
|
||||
forPeriod,
|
||||
i //
|
||||
);
|
||||
|
||||
//
|
||||
bool isTouched =
|
||||
isBullish
|
||||
? iBar.high > box.lower
|
||||
: iBar.low < box.upper;
|
||||
if (!isTouched)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool IsRejectBox(
|
||||
ENUM_X_DIRECTION &forDir,
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
const string X121SMCStrategyToken = "X121SMC";
|
||||
|
||||
//
|
||||
const string X121SMCXWZToken = "X121XWZ";
|
||||
const string X121SMCXSupDemOBSToken = "X121XSupDemOBS";
|
||||
|
||||
//
|
||||
@@ -43,6 +44,7 @@ enum ENUM_X_121_SMC_PROVIDERS
|
||||
{
|
||||
//
|
||||
X_121_SMC_PROVIDER_NONE,
|
||||
X_121_SMC_PROVIDER_XWZ,
|
||||
X_121_SMC_PROVIDER_XSUPDEMOBS,
|
||||
};
|
||||
|
||||
@@ -693,6 +695,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value)
|
||||
switch (value)
|
||||
{
|
||||
//
|
||||
case X_121_SMC_PROVIDER_XWZ:
|
||||
result = X121SMCXWZToken;
|
||||
break;
|
||||
|
||||
//
|
||||
case X_121_SMC_PROVIDER_XSUPDEMOBS:
|
||||
result = X121SMCXSupDemOBSToken;
|
||||
break;
|
||||
@@ -721,7 +728,11 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
|
||||
}
|
||||
|
||||
//
|
||||
if (Contains(X121SMCXSupDemOBSToken, value))
|
||||
if (Contains(X121SMCXWZToken, value))
|
||||
{
|
||||
result = X_121_SMC_PROVIDER_XWZ;
|
||||
}
|
||||
else if (Contains(X121SMCXSupDemOBSToken, value))
|
||||
{
|
||||
result = X_121_SMC_PROVIDER_XSUPDEMOBS;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,824 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
||||
// -------------------------------------------------
|
||||
// Name: XWZ
|
||||
// Description: provide all Signalling functions ...
|
||||
//
|
||||
//
|
||||
// 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-trade.lib"
|
||||
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
||||
#include "../Libraries/x-121.smc.guard.lib.mq5"
|
||||
#include "../Libraries/x-121.smc.lib.mq5"
|
||||
|
||||
//
|
||||
enum ENUM_X121SMC_XWZ_PRIORITY
|
||||
{
|
||||
X121SMC_XWZ_PRIORITY_NONE,
|
||||
X121SMC_XWZ_PRIORITY_WEAK,
|
||||
X121SMC_XWZ_PRIORITY_LOW,
|
||||
X121SMC_XWZ_PRIORITY_REGULAR,
|
||||
X121SMC_XWZ_PRIORITY_HIGH,
|
||||
};
|
||||
|
||||
//
|
||||
struct X121SMCXWZWorkingZone
|
||||
{
|
||||
//
|
||||
string symbol;
|
||||
ENUM_TIMEFRAMES period;
|
||||
|
||||
//
|
||||
double upper;
|
||||
double lower;
|
||||
|
||||
//
|
||||
double zoneUpper;
|
||||
double zoneLower;
|
||||
|
||||
//
|
||||
double quarter1;
|
||||
double quarter2;
|
||||
double quarter3;
|
||||
|
||||
//
|
||||
datetime from;
|
||||
|
||||
//
|
||||
X121SMCXWZWorkingZone()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
upper = 0;
|
||||
lower = 0;
|
||||
quarter1 = 0;
|
||||
quarter2 = 0;
|
||||
quarter3 = 0;
|
||||
zoneLower = 0;
|
||||
zoneUpper = 0;
|
||||
|
||||
//
|
||||
from = NULL;
|
||||
symbol = NULL;
|
||||
period = NULL;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
//
|
||||
bool IsValid()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
lower > 0 &&
|
||||
upper > 0 &&
|
||||
quarter1 > 0 &&
|
||||
quarter2 > 0 &&
|
||||
quarter3 > 0 &&
|
||||
upper > lower &&
|
||||
zoneLower > 0 &&
|
||||
zoneUpper > 0 &&
|
||||
IsValid(from) &&
|
||||
IsValid(symbol) &&
|
||||
IsValid(period) &&
|
||||
zoneUpper > upper &&
|
||||
zoneLower < lower;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool DetectOveralTrend(
|
||||
XOHCL &touchedBar,
|
||||
ENUM_X_DIRECTION &trendDir,
|
||||
int barIndex = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (barIndex < 0)
|
||||
{
|
||||
barIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
trendDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int fromBarIndex = iBarShift(
|
||||
symbol,
|
||||
period,
|
||||
from //
|
||||
);
|
||||
result = IsValidIndex(fromBarIndex);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL nearestUpperTouchedBar;
|
||||
XOHCL nearestLowerTouchedBar;
|
||||
bool hasNearestUpperTouchedBar = false;
|
||||
bool hasNearestLowerTouchedBar = false;
|
||||
for (int i = barIndex; i < fromBarIndex; i++)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
bool isInited = iBar.Init(
|
||||
symbol,
|
||||
period,
|
||||
i //
|
||||
);
|
||||
|
||||
//
|
||||
hasNearestUpperTouchedBar = nearestUpperTouchedBar.IsValid();
|
||||
if (!hasNearestUpperTouchedBar)
|
||||
{
|
||||
//
|
||||
bool isBarTouchedUpper = iBar.high > upper;
|
||||
if (isBarTouchedUpper)
|
||||
{
|
||||
//
|
||||
nearestUpperTouchedBar = iBar;
|
||||
hasNearestUpperTouchedBar = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
hasNearestLowerTouchedBar = nearestLowerTouchedBar.IsValid();
|
||||
if (!hasNearestLowerTouchedBar)
|
||||
{
|
||||
//
|
||||
bool isBarTouchedLower = iBar.low < lower;
|
||||
if (isBarTouchedLower)
|
||||
{
|
||||
//
|
||||
nearestLowerTouchedBar = iBar;
|
||||
hasNearestLowerTouchedBar = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (hasNearestUpperTouchedBar &&
|
||||
hasNearestLowerTouchedBar)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = hasNearestUpperTouchedBar ||
|
||||
hasNearestLowerTouchedBar;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (hasNearestUpperTouchedBar &&
|
||||
!hasNearestLowerTouchedBar)
|
||||
{
|
||||
//
|
||||
trendDir = X_DIRECTION_BEARISH;
|
||||
touchedBar = nearestUpperTouchedBar;
|
||||
}
|
||||
else if (!hasNearestUpperTouchedBar &&
|
||||
hasNearestLowerTouchedBar)
|
||||
{
|
||||
//
|
||||
trendDir = X_DIRECTION_BULLISH;
|
||||
touchedBar = nearestLowerTouchedBar;
|
||||
}
|
||||
else if (hasNearestUpperTouchedBar &&
|
||||
hasNearestLowerTouchedBar)
|
||||
{
|
||||
//
|
||||
trendDir =
|
||||
nearestUpperTouchedBar.time < nearestLowerTouchedBar.time
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
if (IsBullish(trendDir))
|
||||
{
|
||||
touchedBar = nearestLowerTouchedBar;
|
||||
}
|
||||
else
|
||||
{
|
||||
touchedBar = nearestUpperTouchedBar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool IsDestroyed(
|
||||
ENUM_X_DIRECTION &destroyedDir,
|
||||
int barIndex = 0,
|
||||
ENUM_TIMEFRAMES forPeriod = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (barIndex < 0)
|
||||
{
|
||||
barIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
if (!IsValid(forPeriod))
|
||||
{
|
||||
forPeriod = period;
|
||||
}
|
||||
|
||||
//
|
||||
destroyedDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
result = IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL bar;
|
||||
result = bar.Init(
|
||||
symbol,
|
||||
forPeriod,
|
||||
barIndex //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isUpperBreaked =
|
||||
bar.high > zoneUpper &&
|
||||
bar.close > zoneUpper;
|
||||
|
||||
//
|
||||
bool isLowerBreaked =
|
||||
bar.low < zoneLower &&
|
||||
bar.close < zoneLower;
|
||||
|
||||
//
|
||||
result = isUpperBreaked ||
|
||||
isLowerBreaked;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
destroyedDir =
|
||||
isUpperBreaked
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
struct X121SMCStrategyXWZSignalConditions
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
string symbol;
|
||||
ENUM_TIMEFRAMES period;
|
||||
|
||||
//
|
||||
double sl;
|
||||
double target;
|
||||
double reward;
|
||||
double amountPercent;
|
||||
ENUM_X_DIRECTION dir;
|
||||
ENUM_X_POSITION_TYPES type;
|
||||
|
||||
//
|
||||
// Setup Props ...
|
||||
|
||||
//
|
||||
datetime setupTime;
|
||||
datetime triggerTime;
|
||||
|
||||
//
|
||||
double pivot;
|
||||
double point;
|
||||
|
||||
//
|
||||
ENUM_X121SMC_XWZ_PRIORITY priority;
|
||||
|
||||
//
|
||||
// Working Zone ...
|
||||
|
||||
//
|
||||
XCFVG *fairValueGap;
|
||||
XCOrderBlock *orderBlock;
|
||||
XCSupplyZone *supplyZone;
|
||||
XCDemandZone *demandZone;
|
||||
X121SMCXWZWorkingZone workingZone;
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
X121SMCStrategyXWZSignalConditions()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
/**
|
||||
* Cleaning Up ...
|
||||
*/
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
sl = 0;
|
||||
target = 0;
|
||||
|
||||
//
|
||||
dir = X_DIRECTION_NONE;
|
||||
type = X_POSITION_TYPE_NONE;
|
||||
|
||||
//
|
||||
symbol = NULL;
|
||||
period = NULL;
|
||||
setupTime = NULL;
|
||||
triggerTime = NULL;
|
||||
|
||||
//
|
||||
ExtensionClean();
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Condition is Setting Up ...
|
||||
*
|
||||
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsSetuped()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = IsValid(setupTime) &&
|
||||
HasDirection(dir);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Setup Age ...
|
||||
*
|
||||
* @return ( int )
|
||||
*/
|
||||
int GetSetupAge()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
if (!IsSetuped())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect How we Can Trigger Signal ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool CanTrigger()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
sl > 0 &&
|
||||
IsValid(symbol) &&
|
||||
IsValid(period) &&
|
||||
IsValid(triggerTime) &&
|
||||
type != X_POSITION_TYPE_ALL &&
|
||||
type != X_POSITION_TYPE_NONE
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extensions ...
|
||||
|
||||
/**
|
||||
* Clean Additional Properties ...
|
||||
*/
|
||||
void ExtensionClean()
|
||||
{
|
||||
//
|
||||
pivot = 0;
|
||||
point = 0;
|
||||
|
||||
//
|
||||
target = 0;
|
||||
reward = 0;
|
||||
amountPercent = 0;
|
||||
|
||||
//
|
||||
delete supplyZone;
|
||||
ZeroMemory(supplyZone);
|
||||
|
||||
//
|
||||
delete demandZone;
|
||||
ZeroMemory(demandZone);
|
||||
|
||||
//
|
||||
workingZone.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
bool HasWorkingZone()
|
||||
{
|
||||
return workingZone.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
// Working Zone is an Area which
|
||||
// we decide to trade inside it ...
|
||||
bool ExtractWorkingZone(
|
||||
XPOIState &state //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = !HasWorkingZone();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = state.IsValid() &&
|
||||
state.HasChild() &&
|
||||
state.HasSupplyZones() &&
|
||||
state.HasDemandZones();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve Highest Supply Zone ...
|
||||
int hSupplyIDX = GetHighest(state.supplyZones);
|
||||
int lDemandIDX = GetLowest(state.demandZones);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
IsValidIndex(hSupplyIDX) &&
|
||||
IsValidIndex(lDemandIDX)
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
supplyZone = state.supplyZones[hSupplyIDX];
|
||||
demandZone = state.demandZones[lDemandIDX];
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
supplyZone != NULL &&
|
||||
demandZone != NULL &&
|
||||
supplyZone.IsValid() &&
|
||||
demandZone.IsValid()
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
Clean();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
workingZone.symbol = symbol;
|
||||
workingZone.period = period;
|
||||
|
||||
//
|
||||
workingZone.upper = supplyZone.Lower();
|
||||
workingZone.zoneUpper = supplyZone.Upper();
|
||||
|
||||
//
|
||||
workingZone.lower = demandZone.Upper();
|
||||
workingZone.zoneLower = demandZone.Lower();
|
||||
|
||||
//
|
||||
workingZone.from = MathMax(supplyZone.From(), demandZone.From());
|
||||
|
||||
//
|
||||
double upper = workingZone.upper;
|
||||
double range =
|
||||
workingZone.upper - workingZone.lower;
|
||||
double ranegPercent = range / 100;
|
||||
double quarterValue = ranegPercent * 25;
|
||||
|
||||
//
|
||||
workingZone.quarter1 = upper - (quarterValue * 1);
|
||||
workingZone.quarter2 = upper - (quarterValue * 2);
|
||||
workingZone.quarter3 = upper - (quarterValue * 3);
|
||||
|
||||
//
|
||||
result = workingZone.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool IsWorkingZoneDestroyed(
|
||||
ENUM_X_DIRECTION &destroyedDir,
|
||||
int barIndex = 0,
|
||||
ENUM_TIMEFRAMES forPeriod = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (barIndex < 0)
|
||||
{
|
||||
barIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
if (!IsValid(forPeriod))
|
||||
{
|
||||
forPeriod = period;
|
||||
}
|
||||
|
||||
//
|
||||
destroyedDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
result = workingZone.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = workingZone.IsDestroyed(
|
||||
destroyedDir,
|
||||
barIndex,
|
||||
forPeriod //
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool DetectTrend(
|
||||
ENUM_X_DIRECTION &trend,
|
||||
int barIndex = 0,
|
||||
ENUM_TIMEFRAMES forPeriod = NULL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (barIndex < 0)
|
||||
{
|
||||
barIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
if (forPeriod == NULL)
|
||||
{
|
||||
forPeriod = period;
|
||||
}
|
||||
|
||||
//
|
||||
trend = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
result = HasWorkingZone();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int FromIndex = iBarShift(
|
||||
symbol,
|
||||
forPeriod,
|
||||
workingZone.from //
|
||||
);
|
||||
|
||||
//
|
||||
datetime supplyTouch = NULL;
|
||||
datetime demandTouch = NULL;
|
||||
for (int i = barIndex; i < FromIndex; i++)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
bool isInited = iBar.Init(
|
||||
symbol,
|
||||
forPeriod,
|
||||
i //
|
||||
);
|
||||
if (!isInited)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isTouchSupplyZone =
|
||||
//
|
||||
iBar.low < supplyZone.Lower() &&
|
||||
iBar.GetUp() > supplyZone.Lower()
|
||||
//
|
||||
;
|
||||
if (isTouchSupplyZone &&
|
||||
!IsValid(supplyTouch))
|
||||
{
|
||||
supplyTouch = iBar.time;
|
||||
}
|
||||
|
||||
//
|
||||
bool isTouchDemandZone =
|
||||
//
|
||||
iBar.high > demandZone.Upper() &&
|
||||
iBar.GetDown() < demandZone.Upper()
|
||||
//
|
||||
;
|
||||
if (isTouchDemandZone &&
|
||||
!IsValid(demandTouch))
|
||||
{
|
||||
demandTouch = iBar.time;
|
||||
}
|
||||
|
||||
//
|
||||
bool canBreak =
|
||||
IsValid(supplyTouch) &&
|
||||
IsValid(demandTouch);
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
if (canBreak)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
IsValid(supplyTouch) &&
|
||||
IsValid(demandTouch)
|
||||
//
|
||||
;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
trend =
|
||||
//
|
||||
supplyTouch > demandTouch
|
||||
? X_DIRECTION_BEARISH
|
||||
: X_DIRECTION_BULLISH
|
||||
//
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool HasOrderBlock()
|
||||
{
|
||||
return orderBlock != NULL &&
|
||||
orderBlock.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
bool HasFairValueGap()
|
||||
{
|
||||
return fairValueGap != NULL &&
|
||||
fairValueGap.IsValid();
|
||||
}
|
||||
|
||||
//
|
||||
void UpdateTo(datetime value = NULL)
|
||||
{
|
||||
//
|
||||
value = NormalizeTime(value);
|
||||
|
||||
//
|
||||
if (supplyZone != NULL)
|
||||
{
|
||||
supplyZone.To(value);
|
||||
}
|
||||
|
||||
//
|
||||
if (demandZone != NULL)
|
||||
{
|
||||
demandZone.To(value);
|
||||
}
|
||||
|
||||
//
|
||||
if (orderBlock != NULL)
|
||||
{
|
||||
orderBlock.To(value);
|
||||
}
|
||||
|
||||
//
|
||||
if (fairValueGap != NULL)
|
||||
{
|
||||
fairValueGap.To(value);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
};
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
//
|
||||
#include "../Signals/x-121.smc.xsupdemobs.signal.class.mq5"
|
||||
#include "../Signals/x-121.smc.xwz.signal.class.mq5"
|
||||
|
||||
//
|
||||
// Definitions ...
|
||||
@@ -41,8 +42,10 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
public:
|
||||
//
|
||||
// Props ...
|
||||
bool useXWZSignal;
|
||||
bool useXSupDemOBSSignal;
|
||||
XCX121SMCXSupDemOBSSignalDetector *mXSupDemONSSignalDetector;
|
||||
XCX121SMCXWZSignalDetector *mXWZSignalDetector;
|
||||
XCX121SMCXSupDemOBSSignalDetector *mXSupDemOBSSignalDetector;
|
||||
|
||||
//
|
||||
// Constructor(s) ...
|
||||
@@ -56,7 +59,10 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
{
|
||||
//
|
||||
InitialHelpers();
|
||||
mXSupDemONSSignalDetector = new XCX121SMCXSupDemOBSSignalDetector();
|
||||
|
||||
//
|
||||
mXWZSignalDetector = new XCX121SMCXWZSignalDetector();
|
||||
mXSupDemOBSSignalDetector = new XCX121SMCXSupDemOBSSignalDetector();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -104,12 +110,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
*/
|
||||
void Destroy() override
|
||||
{
|
||||
//
|
||||
ZeroMemory(mDecisionCycleHelper);
|
||||
ZeroMemory(mAnalyseCycleHelper);
|
||||
ZeroMemory(mConsolidationCycleHelper);
|
||||
ZeroMemory(mVisionCycleHelper);
|
||||
|
||||
//
|
||||
delete mDecisionCycleHelper;
|
||||
delete mAnalyseCycleHelper;
|
||||
@@ -117,8 +117,18 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
delete mVisionCycleHelper;
|
||||
|
||||
//
|
||||
ZeroMemory(mXSupDemONSSignalDetector);
|
||||
delete mXSupDemONSSignalDetector;
|
||||
ZeroMemory(mDecisionCycleHelper);
|
||||
ZeroMemory(mAnalyseCycleHelper);
|
||||
ZeroMemory(mConsolidationCycleHelper);
|
||||
ZeroMemory(mVisionCycleHelper);
|
||||
|
||||
//
|
||||
delete mXWZSignalDetector;
|
||||
ZeroMemory(mXWZSignalDetector);
|
||||
|
||||
//
|
||||
delete mXSupDemOBSSignalDetector;
|
||||
ZeroMemory(mXSupDemOBSSignalDetector);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,8 +207,22 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
bool hasSignal = false;
|
||||
|
||||
//
|
||||
bool hasXWZSignal = false;
|
||||
bool hasXSupDemOBSSignal = false;
|
||||
|
||||
//
|
||||
// XSupDemOBS Signal ...
|
||||
X121SMCStrategyXWZSignalConditions mXWZConditions;
|
||||
if (useXWZSignal && !hasSignal)
|
||||
{
|
||||
//
|
||||
hasXWZSignal = DetectXWZSignal(
|
||||
conditions,
|
||||
mXWZConditions //
|
||||
);
|
||||
hasSignal = hasXWZSignal;
|
||||
}
|
||||
|
||||
//
|
||||
// XSupDemOBS Signal ...
|
||||
X121SMCStrategyXSupDemOBSSignalConditions mXSupDemOBSConditions;
|
||||
@@ -376,6 +400,20 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
signal.trailSL = true;
|
||||
signal.trailSLStartOnReachTPLevel = 3;
|
||||
signal.fullTPLevel = signal.GetRiskRewardRatio();
|
||||
|
||||
// //
|
||||
// mXSupDemOBSSignalDetector.RemoveDraws();
|
||||
// mXSupDemOBSSignalDetector.DrawConditions(
|
||||
// mXSupDemOBSConditions,
|
||||
// mVisionCycleHelper.mPOIDrawer //
|
||||
// );
|
||||
|
||||
// //
|
||||
// mXSupDemOBSSignalDetector.RemoveWorkingZoneDraws();
|
||||
// mXSupDemOBSSignalDetector.DrawWorkingZone(
|
||||
// mXSupDemOBSConditions,
|
||||
// mVisionCycleHelper.mPOIDrawer //
|
||||
// );
|
||||
}
|
||||
|
||||
//
|
||||
@@ -430,6 +468,72 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
//
|
||||
Clean(guards);
|
||||
|
||||
//
|
||||
int count = ArraySize(positions);
|
||||
result = IsValidSize(count);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XWZ Guard Detection ...
|
||||
if (useXWZSignal)
|
||||
{
|
||||
//
|
||||
X121SMCGuard xwzGuards[];
|
||||
bool hasGuard = mXWZSignalDetector.DetectGuards(
|
||||
xwzGuards,
|
||||
positions,
|
||||
mDecisionCycleHelper,
|
||||
mAnalyseCycleHelper,
|
||||
mConsolidationCycleHelper,
|
||||
mVisionCycleHelper //
|
||||
);
|
||||
|
||||
//
|
||||
if (hasGuard)
|
||||
{
|
||||
//
|
||||
Copy(
|
||||
xwzGuards,
|
||||
guards,
|
||||
false //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// XSupDemOBS Guard Detection ...
|
||||
if (useXSupDemOBSSignal)
|
||||
{
|
||||
//
|
||||
X121SMCGuard xsupDemOBSGuards[];
|
||||
bool hasGuard = mXSupDemOBSSignalDetector.DetectGuards(
|
||||
xsupDemOBSGuards,
|
||||
positions,
|
||||
mDecisionCycleHelper,
|
||||
mAnalyseCycleHelper,
|
||||
mConsolidationCycleHelper,
|
||||
mVisionCycleHelper //
|
||||
);
|
||||
|
||||
//
|
||||
if (hasGuard)
|
||||
{
|
||||
//
|
||||
Copy(
|
||||
xsupDemOBSGuards,
|
||||
guards,
|
||||
false //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
count = ArraySize(guards);
|
||||
result = IsValidSize(count);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -439,53 +543,9 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
*/
|
||||
void DoUnwaitedTicksWork() override
|
||||
{
|
||||
//
|
||||
// Update All Cycle Helpers ...
|
||||
int zIndex = 0;
|
||||
int loopback = 7;
|
||||
|
||||
//
|
||||
// Decision ...
|
||||
mDecisionCycleHelper.Update();
|
||||
|
||||
// //
|
||||
// // Analyse ...
|
||||
// ENUM_XPOI_EVENTS analysePoiEvents[];
|
||||
// ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
|
||||
// X121SMCCycleConditions analyseConditions;
|
||||
// mAnalyseCycleHelper.GetConditions(
|
||||
// analyseCycleEvents,
|
||||
// analysePoiEvents,
|
||||
// analyseConditions,
|
||||
// zIndex,
|
||||
// loopback //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Consolidation ...
|
||||
// ENUM_XPOI_EVENTS consolidationPoiEvents[];
|
||||
// ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
|
||||
// X121SMCCycleConditions consolidationConditions;
|
||||
// mConsolidationCycleHelper.GetConditions(
|
||||
// consolidationCycleEvents,
|
||||
// consolidationPoiEvents,
|
||||
// consolidationConditions,
|
||||
// zIndex,
|
||||
// loopback //
|
||||
// );
|
||||
|
||||
// //
|
||||
// // Vision ...
|
||||
// ENUM_XPOI_EVENTS visionPoiEvents[];
|
||||
// ENUM_X_CYCLE_EVENTS visionCycleEvents[];
|
||||
// X121SMCCycleConditions visionConditions;
|
||||
// mVisionCycleHelper.GetConditions(
|
||||
// visionCycleEvents,
|
||||
// visionPoiEvents,
|
||||
// visionConditions,
|
||||
// zIndex,
|
||||
// loopback //
|
||||
// );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,6 +579,240 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
//
|
||||
// Signalling Functions ...
|
||||
|
||||
//
|
||||
// XWZ Signal ...
|
||||
bool DetectXWZSignal(
|
||||
X121SMCStrategyConditions &conditions,
|
||||
X121SMCStrategyXWZSignalConditions &xSupDemOBSConditions //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Cycle Helpers ...
|
||||
result =
|
||||
//
|
||||
mVisionCycleHelper != NULL &&
|
||||
mAnalyseCycleHelper != NULL &&
|
||||
mDecisionCycleHelper != NULL &&
|
||||
mConsolidationCycleHelper != NULL
|
||||
//
|
||||
;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isBullish = false;
|
||||
bool isBearish = false;
|
||||
|
||||
//
|
||||
int zIndex = 0;
|
||||
int cIndex = zIndex + 1;
|
||||
int pIndex = cIndex + 1;
|
||||
int ppIndex = pIndex + 1;
|
||||
|
||||
//
|
||||
string symbol = GetSymbol();
|
||||
ENUM_TIMEFRAMES period = GetPeriod();
|
||||
|
||||
//
|
||||
XOHCL zBar;
|
||||
result = zBar.Init(
|
||||
symbol,
|
||||
period,
|
||||
zIndex //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL cBar;
|
||||
result = cBar.Init(
|
||||
symbol,
|
||||
period,
|
||||
cIndex //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL pBar;
|
||||
result = pBar.Init(
|
||||
symbol,
|
||||
period,
|
||||
pIndex //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double cLL = cBar.FindLowest(7, MODE_LOW);
|
||||
double cHH = cBar.FindHighest(7, MODE_HIGH);
|
||||
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
|
||||
//
|
||||
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XSUPDEMOBS;
|
||||
string providerStr = ToString(provider);
|
||||
|
||||
//
|
||||
// Detect Setup Conditions ...
|
||||
datetime setupTime = mXWZSignalDetector.mConditions.setupTime;
|
||||
bool isSetuped = mXWZSignalDetector.mConditions.IsSetuped();
|
||||
ENUM_X_DIRECTION setupDir = mXWZSignalDetector.mConditions.dir;
|
||||
if (!isSetuped)
|
||||
{
|
||||
//
|
||||
// Detect Signal Setup ...
|
||||
isSetuped = mXWZSignalDetector.DetectSignalSetup(
|
||||
symbol,
|
||||
period,
|
||||
mDecisionCycleHelper,
|
||||
mAnalyseCycleHelper,
|
||||
mConsolidationCycleHelper,
|
||||
mVisionCycleHelper //
|
||||
);
|
||||
|
||||
//
|
||||
setupDir = mXWZSignalDetector.mConditions.dir;
|
||||
setupTime = mXWZSignalDetector.mConditions.setupTime;
|
||||
|
||||
//
|
||||
if (isSetuped)
|
||||
{
|
||||
//
|
||||
int items = mXWZSignalDetector
|
||||
.AddConditionsIfNotExists();
|
||||
|
||||
//
|
||||
mXWZSignalDetector.mConditions.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
int conditionsCount = ArraySize(mXWZSignalDetector.mConditionsCollection);
|
||||
result = IsValidSize(conditionsCount);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Looking For Conditions ...
|
||||
int selectedIndex = 0;
|
||||
X121SMCStrategyXWZSignalConditions mTmpConditions[];
|
||||
Copy(
|
||||
mXWZSignalDetector.mConditionsCollection,
|
||||
mTmpConditions //
|
||||
);
|
||||
X121SMCStrategyXWZSignalConditions mConditions;
|
||||
for (int i = 0; i < conditionsCount; i++)
|
||||
{
|
||||
//
|
||||
// Check Triggers ...
|
||||
bool canTrigger = mTmpConditions[i].CanTrigger();
|
||||
datetime triggerTime = mTmpConditions[i].triggerTime;
|
||||
if (!canTrigger)
|
||||
{
|
||||
//
|
||||
// Detect Signal Trigger ...
|
||||
canTrigger = mXWZSignalDetector
|
||||
.DetectSignalTrigger(
|
||||
mTmpConditions[i],
|
||||
symbol,
|
||||
period,
|
||||
mDecisionCycleHelper,
|
||||
mAnalyseCycleHelper,
|
||||
mConsolidationCycleHelper,
|
||||
mVisionCycleHelper //
|
||||
);
|
||||
|
||||
//
|
||||
result = canTrigger;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
bool isISetuped = mTmpConditions[i].IsSetuped();
|
||||
if (!isISetuped)
|
||||
{
|
||||
//
|
||||
ArrayRemove(
|
||||
mXWZSignalDetector.mConditionsCollection,
|
||||
i,
|
||||
1 //
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
triggerTime = mTmpConditions[i].triggerTime;
|
||||
}
|
||||
|
||||
//
|
||||
if (canTrigger)
|
||||
{
|
||||
//
|
||||
selectedIndex = i;
|
||||
mConditions = mTmpConditions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = IsValid(mConditions.setupTime) &&
|
||||
HasDirection(mConditions.dir);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove Selected Index from Main Collection ...
|
||||
ArrayRemove(
|
||||
mXWZSignalDetector.mConditionsCollection,
|
||||
selectedIndex,
|
||||
1 //
|
||||
);
|
||||
|
||||
//
|
||||
// Check Signal Direction ...
|
||||
isBullish = IsBullish(mConditions.dir);
|
||||
isBearish = IsBearish(mConditions.dir);
|
||||
result = isBullish ||
|
||||
isBearish;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Issues Signal on Conditions ...
|
||||
conditions.sl = mConditions.sl;
|
||||
conditions.provider = providerStr;
|
||||
conditions.signalDir = mConditions.dir;
|
||||
conditions.target = mConditions.target;
|
||||
|
||||
//
|
||||
xSupDemOBSConditions = mConditions;
|
||||
|
||||
//
|
||||
mConditions.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XSupDemOBS Signal ...
|
||||
bool DetectXSupDemOBSSignal(
|
||||
@@ -607,14 +901,14 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
|
||||
//
|
||||
// Detect Setup Conditions ...
|
||||
datetime setupTime = mXSupDemONSSignalDetector.mConditions.setupTime;
|
||||
bool isSetuped = mXSupDemONSSignalDetector.mConditions.IsSetuped();
|
||||
ENUM_X_DIRECTION setupDir = mXSupDemONSSignalDetector.mConditions.dir;
|
||||
datetime setupTime = mXSupDemOBSSignalDetector.mConditions.setupTime;
|
||||
bool isSetuped = mXSupDemOBSSignalDetector.mConditions.IsSetuped();
|
||||
ENUM_X_DIRECTION setupDir = mXSupDemOBSSignalDetector.mConditions.dir;
|
||||
if (!isSetuped)
|
||||
{
|
||||
//
|
||||
// Detect Signal Setup ...
|
||||
isSetuped = mXSupDemONSSignalDetector.DetectSignalSetup(
|
||||
isSetuped = mXSupDemOBSSignalDetector.DetectSignalSetup(
|
||||
symbol,
|
||||
period,
|
||||
mDecisionCycleHelper,
|
||||
@@ -624,23 +918,23 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
);
|
||||
|
||||
//
|
||||
setupDir = mXSupDemONSSignalDetector.mConditions.dir;
|
||||
setupTime = mXSupDemONSSignalDetector.mConditions.setupTime;
|
||||
setupDir = mXSupDemOBSSignalDetector.mConditions.dir;
|
||||
setupTime = mXSupDemOBSSignalDetector.mConditions.setupTime;
|
||||
|
||||
//
|
||||
if (isSetuped)
|
||||
{
|
||||
//
|
||||
int items = mXSupDemONSSignalDetector
|
||||
int items = mXSupDemOBSSignalDetector
|
||||
.AddConditionsIfNotExists();
|
||||
|
||||
//
|
||||
mXSupDemONSSignalDetector.mConditions.Clean();
|
||||
mXSupDemOBSSignalDetector.mConditions.Clean();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
int conditionsCount = ArraySize(mXSupDemONSSignalDetector.mConditionsCollection);
|
||||
int conditionsCount = ArraySize(mXSupDemOBSSignalDetector.mConditionsCollection);
|
||||
result = IsValidSize(conditionsCount);
|
||||
if (!result)
|
||||
{
|
||||
@@ -652,7 +946,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
int selectedIndex = 0;
|
||||
X121SMCStrategyXSupDemOBSSignalConditions mTmpConditions[];
|
||||
Copy(
|
||||
mXSupDemONSSignalDetector.mConditionsCollection,
|
||||
mXSupDemOBSSignalDetector.mConditionsCollection,
|
||||
mTmpConditions //
|
||||
);
|
||||
X121SMCStrategyXSupDemOBSSignalConditions mConditions;
|
||||
@@ -666,7 +960,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
{
|
||||
//
|
||||
// Detect Signal Trigger ...
|
||||
canTrigger = mXSupDemONSSignalDetector
|
||||
canTrigger = mXSupDemOBSSignalDetector
|
||||
.DetectSignalTrigger(
|
||||
mTmpConditions[i],
|
||||
symbol,
|
||||
@@ -687,7 +981,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
{
|
||||
//
|
||||
ArrayRemove(
|
||||
mXSupDemONSSignalDetector.mConditionsCollection,
|
||||
mXSupDemOBSSignalDetector.mConditionsCollection,
|
||||
i,
|
||||
1 //
|
||||
);
|
||||
@@ -720,7 +1014,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
//
|
||||
// Remove Selected Index from Main Collection ...
|
||||
ArrayRemove(
|
||||
mXSupDemONSSignalDetector.mConditionsCollection,
|
||||
mXSupDemOBSSignalDetector.mConditionsCollection,
|
||||
selectedIndex,
|
||||
1 //
|
||||
);
|
||||
@@ -768,7 +1062,8 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy
|
||||
void InitialHelpers()
|
||||
{
|
||||
//
|
||||
useXSupDemOBSSignal = true;
|
||||
useXWZSignal = true;
|
||||
useXSupDemOBSSignal = false;
|
||||
|
||||
//
|
||||
string symbol = GetSymbol();
|
||||
|
||||
Reference in New Issue
Block a user