1188 lines
25 KiB
Plaintext
1188 lines
25 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
|
// -------------------------------------------------
|
|
// Name:
|
|
// 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 "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
struct X121SMCStrategyXPVSUPDEMSignalConditions
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
double sl;
|
|
ENUM_X_DIRECTION dir;
|
|
ENUM_X_POSITION_TYPES type;
|
|
|
|
//
|
|
// Setup Props ...
|
|
|
|
//
|
|
datetime setupTime;
|
|
datetime triggerTime;
|
|
|
|
//
|
|
XCTicksZone *ticksZone;
|
|
XCSupplyZone *supplyZones[];
|
|
XCDemandZone *demandZones[];
|
|
datetime activeZoneFoundedAt;
|
|
XCSupplyZone *activeSupplyZone;
|
|
XCDemandZone *activeDemandZone;
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCStrategyXPVSUPDEMSignalConditions()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleaning Up ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
sl = 0;
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
type = X_POSITION_TYPE_NONE;
|
|
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
setupTime = NULL;
|
|
triggerTime = NULL;
|
|
|
|
//
|
|
ExtensionClean();
|
|
}
|
|
|
|
/**
|
|
* 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()
|
|
{
|
|
//
|
|
ticksZone = NULL;
|
|
activeSupplyZone = NULL;
|
|
activeDemandZone = NULL;
|
|
activeZoneFoundedAt = NULL;
|
|
|
|
//
|
|
Clean(supplyZones);
|
|
Clean(demandZones);
|
|
}
|
|
|
|
/**
|
|
* Count Supply Zones ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountSupplyZones()
|
|
{
|
|
return ArraySize(supplyZones);
|
|
}
|
|
|
|
/**
|
|
* Count Demand Zones ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountDemandZones()
|
|
{
|
|
return ArraySize(demandZones);
|
|
}
|
|
|
|
/**
|
|
* Check Has Supply Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasSupplyZones()
|
|
{
|
|
return IsValidSize(CountSupplyZones());
|
|
}
|
|
|
|
/**
|
|
* Check Has Demand Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasDemandZones()
|
|
{
|
|
return IsValidSize(CountDemandZones());
|
|
}
|
|
|
|
/**
|
|
* Check Has Active Supply or Demand Zone ...
|
|
*
|
|
* @param _dir: ENUM_X_DIRECTION member Reference for Specify Active Zone ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasActiveZone(ENUM_X_DIRECTION &_dir)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
_dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Check Supplies ...
|
|
bool hasActiveSupplyZone = activeSupplyZone != NULL &&
|
|
activeSupplyZone.IsValid();
|
|
|
|
//
|
|
// Check Demnds ...
|
|
bool hasActiveDemandZone = activeDemandZone != NULL &&
|
|
activeDemandZone.IsValid();
|
|
|
|
//
|
|
result = hasActiveSupplyZone ||
|
|
hasActiveDemandZone;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
_dir = hasActiveDemandZone
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Active Zone Reference if Exists ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetActiveZone(XCBarZone *&activeZone)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
activeZone = NULL;
|
|
|
|
//
|
|
ENUM_X_DIRECTION activeZoneDir;
|
|
result = HasActiveZone(activeZoneDir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (IsBullish(activeZoneDir))
|
|
{
|
|
//
|
|
activeDemandZone.To(TimeCurrent());
|
|
activeZone = activeDemandZone;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
activeSupplyZone.To(TimeCurrent());
|
|
activeZone = activeSupplyZone;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Ticks Zone is Initialized or not ...
|
|
* @return ( bool )
|
|
*/
|
|
bool HasTicksZone()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
ticksZone != NULL &&
|
|
ticksZone.IsValid() &&
|
|
IsValidSize(ticksZone.Count())
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Extension Functions ...
|
|
|
|
//
|
|
// Detect Setup Conditions ...
|
|
bool DetectX121SMCXPVSUPDEMSiganlSetup(
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period,
|
|
//
|
|
X121SMCStrategyXPVSUPDEMSignalConditions &conditions,
|
|
//
|
|
XC121SMCCycleHelper *triggerCycleHelper,
|
|
XC121SMCCycleHelper *decisionCycleHelper,
|
|
XC121SMCCycleHelper *analyseCycleHelper,
|
|
XC121SMCCycleHelper *verificationCycleHelper,
|
|
XC121SMCCycleHelper *consolidationCycleHelper,
|
|
XC121SMCCycleHelper *visionCycleHelper
|
|
//
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
int loopback = 10;
|
|
|
|
//
|
|
string symbol = _symbol;
|
|
ENUM_TIMEFRAMES period = _period;
|
|
|
|
//
|
|
conditions.symbol = symbol;
|
|
conditions.period = period;
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double ask = GetAsk(symbol);
|
|
double bid = GetBid(symbol);
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
double ll = cBar.FindLowest(9, MODE_LOW);
|
|
double hh = cBar.FindHighest(9, MODE_HIGH);
|
|
|
|
//
|
|
int zoneValidationDivider = 10;
|
|
int validPivotRepetition = triggerCycleHelper.mX121Helper
|
|
.GetDonChainLength();
|
|
|
|
//
|
|
double selectedSL = 0;
|
|
|
|
//
|
|
// Cycles Conditions ...
|
|
|
|
//
|
|
// Trigger ...
|
|
ENUM_XPOI_EVENTS triggerPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS triggerCycleEvents[];
|
|
X121SMCCycleConditions triggerConditions;
|
|
result = triggerCycleHelper.GetConditions(
|
|
triggerCycleEvents,
|
|
triggerPoiEvents,
|
|
triggerConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Decision ...
|
|
ENUM_XPOI_EVENTS decisionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
|
|
X121SMCCycleConditions decisionConditions;
|
|
result = decisionCycleHelper.GetConditions(
|
|
decisionCycleEvents,
|
|
decisionPoiEvents,
|
|
decisionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Analyse ...
|
|
ENUM_XPOI_EVENTS analysePoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
|
|
X121SMCCycleConditions analyseConditions;
|
|
result = analyseCycleHelper.GetConditions(
|
|
analyseCycleEvents,
|
|
analysePoiEvents,
|
|
analyseConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Verification ...
|
|
ENUM_XPOI_EVENTS verificationPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS verificationCycleEvents[];
|
|
X121SMCCycleConditions verificationConditions;
|
|
result = verificationCycleHelper.GetConditions(
|
|
verificationCycleEvents,
|
|
verificationPoiEvents,
|
|
verificationConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Consolidation ...
|
|
ENUM_XPOI_EVENTS consolidationPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
|
|
X121SMCCycleConditions consolidationConditions;
|
|
result = consolidationCycleHelper.GetConditions(
|
|
consolidationCycleEvents,
|
|
consolidationPoiEvents,
|
|
consolidationConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Vision ...
|
|
ENUM_XPOI_EVENTS visionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
|
|
X121SMCCycleConditions visionConditions;
|
|
result = visionCycleHelper.GetConditions(
|
|
visionCycleEvents,
|
|
visionPoiEvents,
|
|
visionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cycles POI States ...
|
|
XPOIState triggerState = triggerConditions.state;
|
|
XPOIState decisionState = decisionConditions.state;
|
|
XPOIState analyseState = analyseConditions.state;
|
|
XPOIState verificationState = verificationConditions.state;
|
|
XPOIState consolidationState = consolidationConditions.state;
|
|
XPOIState visionState = visionConditions.state;
|
|
|
|
//
|
|
// Setup Conditions ...
|
|
|
|
//
|
|
// Select Source State ...
|
|
XPOIState state = consolidationState;
|
|
|
|
//
|
|
// Detect Supply and Demand Zones ...
|
|
|
|
//
|
|
// Supply ...
|
|
bool hasSupplyZones = conditions.HasSupplyZones();
|
|
if (!hasSupplyZones)
|
|
{
|
|
//
|
|
int count = state.CountSupplyZones();
|
|
for (int i = count - 1; i >= 0; i--)
|
|
{
|
|
//
|
|
XCSupplyZone *iZone = state.supplyZones[i];
|
|
|
|
//
|
|
bool isValid =
|
|
//
|
|
ask < iZone.Lower() &&
|
|
bid < iZone.Lower() &&
|
|
cBar.high < iZone.Lower()
|
|
//
|
|
;
|
|
if (isValid)
|
|
{
|
|
//
|
|
Add(
|
|
iZone,
|
|
conditions.supplyZones //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
hasSupplyZones = conditions.HasSupplyZones();
|
|
result = hasSupplyZones;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand ...
|
|
bool hasDemandZones = conditions.HasDemandZones();
|
|
if (!hasDemandZones)
|
|
{
|
|
//
|
|
int count = state.CountDemandZones();
|
|
for (int i = count - 1; i >= 0; i--)
|
|
{
|
|
//
|
|
XCDemandZone *iZone = state.demandZones[i];
|
|
|
|
//
|
|
bool isValid =
|
|
//
|
|
ask > iZone.Upper() &&
|
|
bid > iZone.Upper() &&
|
|
cBar.low > iZone.Upper()
|
|
//
|
|
;
|
|
if (isValid)
|
|
{
|
|
//
|
|
Add(
|
|
iZone,
|
|
conditions.demandZones //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
hasDemandZones = conditions.HasDemandZones();
|
|
result = hasDemandZones;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Waits For Price to Go Inside a Zone ...
|
|
ENUM_X_DIRECTION activeZoneDir = X_DIRECTION_NONE;
|
|
bool hasActiveZone = conditions.HasActiveZone(activeZoneDir);
|
|
if (!hasActiveZone)
|
|
{
|
|
//
|
|
// Looking Up For Active Zone ...
|
|
|
|
//
|
|
// Supply ...
|
|
if (hasSupplyZones)
|
|
{
|
|
//
|
|
int count = conditions.CountSupplyZones();
|
|
for (int i = count - 1; i >= 0; i--)
|
|
{
|
|
//
|
|
XCSupplyZone *iZone = conditions.supplyZones[i];
|
|
|
|
//
|
|
bool isValid =
|
|
//
|
|
ask <= iZone.Upper() &&
|
|
bid <= iZone.Upper() &&
|
|
ask >= iZone.Lower() &&
|
|
bid >= iZone.Lower() &&
|
|
cBar.high <= iZone.Upper() &&
|
|
cBar.low >= iZone.Lower()
|
|
//
|
|
;
|
|
if (isValid)
|
|
{
|
|
//
|
|
conditions.activeSupplyZone = iZone;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
hasActiveZone = conditions.HasActiveZone(activeZoneDir);
|
|
if (!hasActiveZone)
|
|
{
|
|
//
|
|
// Demand ...
|
|
if (hasDemandZones)
|
|
{
|
|
//
|
|
int count = conditions.CountDemandZones();
|
|
for (int i = count - 1; i >= 0; i--)
|
|
{
|
|
//
|
|
XCDemandZone *iZone = conditions.demandZones[i];
|
|
|
|
//
|
|
bool isValid =
|
|
//
|
|
ask <= iZone.Upper() &&
|
|
bid <= iZone.Upper() &&
|
|
ask >= iZone.Lower() &&
|
|
bid >= iZone.Lower() &&
|
|
cBar.high <= iZone.Upper() &&
|
|
cBar.low >= iZone.Lower()
|
|
//
|
|
;
|
|
if (isValid)
|
|
{
|
|
//
|
|
conditions.activeDemandZone = iZone;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
hasActiveZone = conditions.HasActiveZone(activeZoneDir);
|
|
result = hasActiveZone;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
conditions.activeZoneFoundedAt = cTime;
|
|
}
|
|
|
|
//
|
|
// Now we Have to Calculate Active Zones Ticks ...
|
|
|
|
//
|
|
// Select Active Zone ...
|
|
XCBarZone *activeZone = NULL;
|
|
result = conditions.GetActiveZone(activeZone);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Active Zone Start Bar ...
|
|
XOHCL fromBar;
|
|
datetime fromTime = activeZone.BarTime();
|
|
result = triggerCycleHelper.GetBar(
|
|
fromBar,
|
|
fromTime //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool hasTicksZone = conditions.HasTicksZone();
|
|
if (!hasTicksZone)
|
|
{
|
|
//
|
|
// Istantiate Ticks Zone ...
|
|
conditions.ticksZone = new XCTicksZone();
|
|
conditions.ticksZone.Levels(40);
|
|
}
|
|
|
|
//
|
|
// Update Ticks Zone ...
|
|
result = conditions.ticksZone.Init(
|
|
fromBar,
|
|
cBar //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Regenrate Conditions ...
|
|
hasTicksZone = conditions.HasTicksZone();
|
|
result = hasTicksZone;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Make Sure we Have a Direction for Setup ...
|
|
isBullish = IsBullish(activeZoneDir);
|
|
isBearish = IsBearish(activeZoneDir);
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check New Peaks or Vales Happens inside Zero Tick or Volume Percent Zone and
|
|
// also Active Zone ...
|
|
double peak = triggerConditions.x121Conditions.peaksBuffer[1];
|
|
double vale = triggerConditions.x121Conditions.valesBuffer[1];
|
|
bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast;
|
|
bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast;
|
|
|
|
//
|
|
bool isPeakInsideActiveZone =
|
|
//
|
|
peak <= activeZone.Upper() &&
|
|
peak >= activeZone.Lower()
|
|
//
|
|
;
|
|
bool isValeInsideActiveZone =
|
|
//
|
|
vale <= activeZone.Upper() &&
|
|
vale >= activeZone.Lower()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isPeakInsideZeroZone = false;
|
|
bool isValeInsideZeroZone = false;
|
|
int tzCount = conditions.ticksZone.Count();
|
|
if (IsValidSize(tzCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < tzCount; i++)
|
|
{
|
|
//
|
|
XCTickZone *iTZ = conditions.ticksZone.GetZone(i);
|
|
|
|
//
|
|
if (isBearish &&
|
|
!isPeakInsideZeroZone)
|
|
{
|
|
//
|
|
isPeakInsideZeroZone =
|
|
//
|
|
peak <= iTZ.high &&
|
|
peak >= iTZ.low &&
|
|
(iTZ.percent == 0 ||
|
|
iTZ.volumePercent == 0)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
if (isBullish &&
|
|
!isValeInsideZeroZone)
|
|
{
|
|
//
|
|
isValeInsideZeroZone =
|
|
//
|
|
vale <= iTZ.high &&
|
|
vale >= iTZ.low &&
|
|
(iTZ.percent == 0 ||
|
|
iTZ.volumePercent == 0)
|
|
//
|
|
;
|
|
}
|
|
|
|
//
|
|
if (isPeakInsideZeroZone ||
|
|
isValeInsideZeroZone)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
isBullish &&
|
|
isNewValeUnderLast &&
|
|
isValeInsideZeroZone &&
|
|
isValeInsideActiveZone
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
isBearish &&
|
|
isNewPeakOverLast &&
|
|
isPeakInsideZeroZone &&
|
|
isPeakInsideActiveZone
|
|
//
|
|
;
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
//
|
|
// Clean Conditions for Regenerate ...
|
|
int activeZoneAge = (int)(cTime - conditions.activeZoneFoundedAt) / PeriodSeconds(conditions.period);
|
|
if (activeZoneAge >= 200)
|
|
{
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
conditions.setupTime = cTime;
|
|
conditions.dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Conditions ...
|
|
bool DetectX121SMCXPVSUPDEMSiganlTrigger(
|
|
//
|
|
X121SMCStrategyXPVSUPDEMSignalConditions &conditions,
|
|
//
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period,
|
|
//
|
|
XC121SMCCycleHelper *triggerCycleHelper,
|
|
XC121SMCCycleHelper *decisionCycleHelper,
|
|
XC121SMCCycleHelper *analyseCycleHelper,
|
|
XC121SMCCycleHelper *verificationCycleHelper,
|
|
XC121SMCCycleHelper *consolidationCycleHelper,
|
|
XC121SMCCycleHelper *visionCycleHelper,
|
|
//
|
|
int maxAllowedSetupAge = 60 //
|
|
//
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = conditions.IsSetuped();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
datetime setupTime = conditions.setupTime;
|
|
ENUM_X_DIRECTION setupDir = conditions.dir;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
int loopback = 10;
|
|
|
|
//
|
|
string symbol = _symbol;
|
|
ENUM_TIMEFRAMES period = _period;
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double ask = GetAsk(symbol);
|
|
double bid = GetBid(symbol);
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
double ll = cBar.FindLowest(9, MODE_LOW);
|
|
double hh = cBar.FindHighest(9, MODE_HIGH);
|
|
|
|
//
|
|
int zoneValidationDivider = 10;
|
|
int validPivotRepetition = triggerCycleHelper.mX121Helper
|
|
.GetDonChainLength();
|
|
|
|
//
|
|
double selectedSL = 0;
|
|
|
|
//
|
|
// Cycles Conditions ...
|
|
|
|
//
|
|
// Trigger ...
|
|
ENUM_XPOI_EVENTS triggerPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS triggerCycleEvents[];
|
|
X121SMCCycleConditions triggerConditions;
|
|
result = triggerCycleHelper.GetConditions(
|
|
triggerCycleEvents,
|
|
triggerPoiEvents,
|
|
triggerConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Decision ...
|
|
ENUM_XPOI_EVENTS decisionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
|
|
X121SMCCycleConditions decisionConditions;
|
|
result = decisionCycleHelper.GetConditions(
|
|
decisionCycleEvents,
|
|
decisionPoiEvents,
|
|
decisionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Analyse ...
|
|
ENUM_XPOI_EVENTS analysePoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
|
|
X121SMCCycleConditions analyseConditions;
|
|
result = analyseCycleHelper.GetConditions(
|
|
analyseCycleEvents,
|
|
analysePoiEvents,
|
|
analyseConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Verification ...
|
|
ENUM_XPOI_EVENTS verificationPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS verificationCycleEvents[];
|
|
X121SMCCycleConditions verificationConditions;
|
|
result = verificationCycleHelper.GetConditions(
|
|
verificationCycleEvents,
|
|
verificationPoiEvents,
|
|
verificationConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Consolidation ...
|
|
ENUM_XPOI_EVENTS consolidationPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
|
|
X121SMCCycleConditions consolidationConditions;
|
|
result = consolidationCycleHelper.GetConditions(
|
|
consolidationCycleEvents,
|
|
consolidationPoiEvents,
|
|
consolidationConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Vision ...
|
|
ENUM_XPOI_EVENTS visionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
|
|
X121SMCCycleConditions visionConditions;
|
|
result = visionCycleHelper.GetConditions(
|
|
visionCycleEvents,
|
|
visionPoiEvents,
|
|
visionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cycles POI States ...
|
|
XPOIState triggerState = triggerConditions.state;
|
|
XPOIState decisionState = decisionConditions.state;
|
|
XPOIState analyseState = analyseConditions.state;
|
|
XPOIState verificationState = verificationConditions.state;
|
|
XPOIState consolidationState = consolidationConditions.state;
|
|
XPOIState visionState = visionConditions.state;
|
|
|
|
//
|
|
// Trigger Conditions ...
|
|
|
|
//
|
|
// Select Active Zone Class ...
|
|
XCBarZone *activeZone = NULL;
|
|
result = conditions.GetActiveZone(activeZone);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Last Valid Peak or Last Valid Vales Breaks ...
|
|
// Beak Of Structure ...
|
|
|
|
//
|
|
// Peak ...
|
|
double peak = triggerConditions.x121Conditions.peaksBuffer[1];
|
|
XPVPivotPoint lastPeakPivot;
|
|
bool hasLastPeakPivot = triggerCycleHelper
|
|
.GetLastPeakPivotPoint(lastPeakPivot);
|
|
bool isLastPeakPivotBreaked =
|
|
//
|
|
lastPeakPivot.IsPeak() &&
|
|
lastPeakPivot.IsValid() &&
|
|
peak > lastPeakPivot.value
|
|
//
|
|
;
|
|
|
|
//
|
|
// Vale ...
|
|
double vale = triggerConditions.x121Conditions.valesBuffer[1];
|
|
XPVPivotPoint lastValePivot;
|
|
bool hasLastValePivot = triggerCycleHelper
|
|
.GetLastValePivotPoint(lastValePivot);
|
|
bool isLastValePivotBreaked =
|
|
//
|
|
lastValePivot.IsVale() &&
|
|
lastValePivot.IsValid() &&
|
|
vale < lastValePivot.value
|
|
//
|
|
;
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
IsBullish(setupDir) &&
|
|
isLastValePivotBreaked
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
IsBearish(setupDir) &&
|
|
isLastPeakPivotBreaked
|
|
//
|
|
;
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
//
|
|
// Cleanup Setup Conditions ...
|
|
int setupAge = conditions.GetSetupAge();
|
|
if (IsValidSize(setupAge) &&
|
|
IsValidSize(maxAllowedSetupAge) &&
|
|
setupAge >= maxAllowedSetupAge)
|
|
{
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
conditions.triggerTime = cTime;
|
|
conditions.sl = isBullish
|
|
? activeZone.Lower()
|
|
: activeZone.Upper();
|
|
conditions.type = isBullish
|
|
? X_POSITION_TYPE_LONG
|
|
: X_POSITION_TYPE_SHORT;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
// |