1421 lines
30 KiB
Plaintext
1421 lines
30 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"
|
|
|
|
// //
|
|
// const string X121SMCXTWPV_Method_1_Token = "X121SMCXTWPV_1";
|
|
// const string X121SMCXTWPV_Method_2_Token = "X121SMCXTWPV_2";
|
|
// const string X121SMCXTWPV_Method_3_Token = "X121SMCXTWPV_3";
|
|
|
|
// //
|
|
// enum ENUM_X_X121SMC_XTWPV_METHODS
|
|
// {
|
|
// X_X121SMC_XTWPV_METHOD_UNKNOWN,
|
|
// X_X121SMC_XTWPV_METHOD_1,
|
|
// X_X121SMC_XTWPV_METHOD_2,
|
|
// X_X121SMC_XTWPV_METHOD_3,
|
|
// };
|
|
|
|
// //
|
|
// string ToString(ENUM_X_X121SMC_XTWPV_METHODS value)
|
|
// {
|
|
// //
|
|
// string result = NULL;
|
|
|
|
// //
|
|
// if (value == X_X121SMC_XTWPV_METHOD_UNKNOWN)
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// switch (value)
|
|
// {
|
|
// //
|
|
// case X_X121SMC_XTWPV_METHOD_1:
|
|
// result = "Method_1";
|
|
// break;
|
|
|
|
// //
|
|
// case X_X121SMC_XTWPV_METHOD_2:
|
|
// result = "Method_2";
|
|
// break;
|
|
// }
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// ENUM_X_X121SMC_XTWPV_METHODS ParseMethod(string value)
|
|
// {
|
|
// //
|
|
// ENUM_X_X121SMC_XTWPV_METHODS result = X_X121SMC_XTWPV_METHOD_UNKNOWN;
|
|
|
|
// //
|
|
// if (!IsValid(value))
|
|
// {
|
|
// return result;
|
|
// }
|
|
|
|
// //
|
|
// if (Contains(X121SMCXTWPV_Method_1_Token, value))
|
|
// {
|
|
// result = X_X121SMC_XTWPV_METHOD_1;
|
|
// }
|
|
// else if (Contains(X121SMCXTWPV_Method_2_Token, value))
|
|
// {
|
|
// result = X_X121SMC_XTWPV_METHOD_2;
|
|
// }
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
//
|
|
// Definitions ...
|
|
struct X121SMCStrategyXTWPVSignalConditions
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
double sl;
|
|
double target;
|
|
ENUM_X_DIRECTION dir;
|
|
ENUM_X_POSITION_TYPES type;
|
|
|
|
//
|
|
// Setup Props ...
|
|
|
|
//
|
|
datetime setupTime;
|
|
datetime triggerTime;
|
|
|
|
//
|
|
XMarketStructure consolidationMarketStructure;
|
|
XMarketStructure analyseMarketStructure;
|
|
|
|
//
|
|
datetime newPeakAboveAtrUpperAt;
|
|
datetime newValeBelowAtrLowerAt;
|
|
datetime sarSiwtchedToBullishAt;
|
|
datetime sarSiwtchedToBearishAt;
|
|
datetime rsiCrossedOverOverSoldAt;
|
|
datetime rsiCrossedUnderOverBoughtAt;
|
|
|
|
//
|
|
XPriceZones decisionZone;
|
|
XPriceZones peakPriceZone;
|
|
XPriceZones valePriceZone;
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCStrategyXTWPVSignalConditions()
|
|
{
|
|
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();
|
|
}
|
|
|
|
/**
|
|
* 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()
|
|
{
|
|
//
|
|
decisionZone.Clean();
|
|
peakPriceZone.Clean();
|
|
valePriceZone.Clean();
|
|
|
|
//
|
|
analyseMarketStructure.Clean();
|
|
consolidationMarketStructure.Clean();
|
|
|
|
//
|
|
newPeakAboveAtrUpperAt = NULL;
|
|
newValeBelowAtrLowerAt = NULL;
|
|
sarSiwtchedToBullishAt = NULL;
|
|
sarSiwtchedToBearishAt = NULL;
|
|
rsiCrossedOverOverSoldAt = NULL;
|
|
rsiCrossedUnderOverBoughtAt = NULL;
|
|
}
|
|
|
|
/**
|
|
* Check Required Market Strucutre Exists or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasMarketStrucutre()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
analyseMarketStructure.IsValid() &&
|
|
consolidationMarketStructure.IsValid()
|
|
//
|
|
&&
|
|
//
|
|
analyseMarketStructure.HasTrend() &&
|
|
consolidationMarketStructure.HasTrend()
|
|
//
|
|
&&
|
|
//
|
|
analyseMarketStructure.bias == consolidationMarketStructure.bias
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if Conditions Filled ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsFilled()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = HasMarketStrucutre();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish(analyseMarketStructure.bias);
|
|
|
|
//
|
|
result =
|
|
isBullish
|
|
? IsValid(newValeBelowAtrLowerAt) &&
|
|
IsValid(sarSiwtchedToBullishAt) &&
|
|
IsValid(rsiCrossedOverOverSoldAt)
|
|
: IsValid(newPeakAboveAtrUpperAt) &&
|
|
IsValid(sarSiwtchedToBearishAt) &&
|
|
IsValid(rsiCrossedUnderOverBoughtAt);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if Has Price Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasPriceZone()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = HasMarketStrucutre();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish(analyseMarketStructure.bias);
|
|
|
|
//
|
|
result =
|
|
isBullish
|
|
? valePriceZone.IsValid()
|
|
: peakPriceZone.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if Has Decision Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasDecisionZone()
|
|
{
|
|
return HasPriceZone() &&
|
|
decisionZone.IsValid();
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Extension Functions ...
|
|
|
|
//
|
|
// Detect Setup Conditions ...
|
|
bool DetectX121SMCXTWPVSiganlSetup(
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period,
|
|
//
|
|
X121SMCStrategyXTWPVSignalConditions &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;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
result = pBar.Init(
|
|
symbol,
|
|
period,
|
|
pIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double ask = GetAsk(symbol);
|
|
double bid = GetBid(symbol);
|
|
datetime cTime = TimeCurrent();
|
|
double points = GetPoints(symbol);
|
|
|
|
//
|
|
int swingLoopback = 9;
|
|
double ll = cBar.FindLowest(swingLoopback, MODE_LOW);
|
|
double hh = cBar.FindHighest(swingLoopback, MODE_HIGH);
|
|
double llDown = cBar.FindLowesttDown(swingLoopback);
|
|
double hhUp = cBar.FindHighestUp(swingLoopback);
|
|
|
|
//
|
|
// 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 ...
|
|
|
|
//
|
|
bool hasMarketStructure = conditions.HasMarketStrucutre();
|
|
if (!hasMarketStructure)
|
|
{
|
|
//
|
|
bool hasConsolidationMarketStructure =
|
|
consolidationCycleHelper
|
|
.DetectMarketStructure(conditions.consolidationMarketStructure);
|
|
|
|
//
|
|
bool hasAnalyseMarketStructure =
|
|
analyseCycleHelper
|
|
.DetectMarketStructure(conditions.analyseMarketStructure);
|
|
|
|
//
|
|
hasMarketStructure = conditions.HasMarketStrucutre();
|
|
result = hasMarketStructure;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We Are Sure we Have Direct Structure Bias ...
|
|
isBullish = IsBullish(conditions.analyseMarketStructure.bias);
|
|
isBearish = IsBearish(conditions.analyseMarketStructure.bias);
|
|
|
|
//
|
|
// RSI ...
|
|
double rsi = triggerConditions.x121Conditions.rsiBuffer[1];
|
|
|
|
//
|
|
bool isRSICrossedOverOverBought = triggerConditions.x121Conditions.isRSICrossedOverOverBought;
|
|
bool isRSICrossedUnderOverBought = triggerConditions.x121Conditions.isRSICrossedUnderOverBought;
|
|
|
|
//
|
|
bool isRSICrossedOverOverSold = triggerConditions.x121Conditions.isRSICrossedOverOverSold;
|
|
bool isRSICrossedUnderOverSold = triggerConditions.x121Conditions.isRSICrossedUnderOverSold;
|
|
|
|
//
|
|
// PV ...
|
|
double peak = triggerConditions.x121Conditions.peaksBuffer[1];
|
|
double vale = triggerConditions.x121Conditions.valesBuffer[1];
|
|
|
|
//
|
|
bool isNewPeak = triggerConditions.x121Conditions.isNewPeak;
|
|
bool isNewVale = triggerConditions.x121Conditions.isNewVale;
|
|
|
|
//
|
|
// ATR ...
|
|
double atr = triggerConditions.x121Conditions.atrBuffer[1];
|
|
double atrUpper = triggerConditions.x121Conditions.atrUpperBuffer[1];
|
|
double atrLower = triggerConditions.x121Conditions.atrLowerBuffer[1];
|
|
|
|
//
|
|
// SAR ...
|
|
double sar = triggerConditions.x121Conditions.sarBuffer[1];
|
|
|
|
//
|
|
bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish;
|
|
bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish;
|
|
|
|
//
|
|
// Complex Conditions ...
|
|
|
|
//
|
|
bool isNewPeakAboveAtrUpper =
|
|
isNewPeak &&
|
|
peak > atrUpper;
|
|
|
|
//
|
|
bool isNewValeBelowAtrLower =
|
|
isNewVale &&
|
|
vale < atrLower;
|
|
|
|
//
|
|
// Fill Conditions ...
|
|
bool isConditionsFilled = conditions.IsFilled();
|
|
if (!isConditionsFilled)
|
|
{
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
// Sar ...
|
|
|
|
//
|
|
// Bullish ...
|
|
if (isBullish &&
|
|
isSarSwitchedToBearish &&
|
|
IsValid(conditions.sarSiwtchedToBullishAt))
|
|
{
|
|
conditions.sarSiwtchedToBullishAt = NULL;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
if (isBearish &&
|
|
isSarSwitchedToBullish &&
|
|
IsValid(conditions.sarSiwtchedToBearishAt))
|
|
{
|
|
conditions.sarSiwtchedToBearishAt = NULL;
|
|
}
|
|
|
|
//
|
|
// Rsi ...
|
|
|
|
//
|
|
// Bullish ...
|
|
if (isBullish &&
|
|
isRSICrossedUnderOverSold &&
|
|
IsValid(conditions.rsiCrossedOverOverSoldAt))
|
|
{
|
|
conditions.rsiCrossedOverOverSoldAt = NULL;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
if (isBearish &&
|
|
isRSICrossedOverOverBought &&
|
|
IsValid(conditions.rsiCrossedUnderOverBoughtAt))
|
|
{
|
|
conditions.rsiCrossedUnderOverBoughtAt = NULL;
|
|
}
|
|
|
|
//
|
|
// Atr Change ...
|
|
|
|
//
|
|
// Bullish ...
|
|
if (isBullish &&
|
|
isNewPeak &&
|
|
IsValid(conditions.newValeBelowAtrLowerAt))
|
|
{
|
|
conditions.newValeBelowAtrLowerAt = NULL;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
if (isBearish &&
|
|
isNewVale &&
|
|
IsValid(conditions.newPeakAboveAtrUpperAt))
|
|
{
|
|
conditions.newPeakAboveAtrUpperAt = NULL;
|
|
}
|
|
|
|
//
|
|
// Filling Up ...
|
|
|
|
//
|
|
// Sar Change ...
|
|
|
|
//
|
|
// Bullish ...
|
|
if (isBullish &&
|
|
isSarSwitchedToBullish &&
|
|
!IsValid(conditions.sarSiwtchedToBullishAt))
|
|
{
|
|
conditions.sarSiwtchedToBullishAt = cTime;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
if (isBearish &&
|
|
isSarSwitchedToBearish &&
|
|
!IsValid(conditions.sarSiwtchedToBearishAt))
|
|
{
|
|
conditions.sarSiwtchedToBearishAt = cTime;
|
|
}
|
|
|
|
//
|
|
// Rsi Change ...
|
|
|
|
//
|
|
// Bullish ...
|
|
if (isBullish &&
|
|
isRSICrossedOverOverSold &&
|
|
!IsValid(conditions.rsiCrossedOverOverSoldAt))
|
|
{
|
|
conditions.rsiCrossedOverOverSoldAt = cTime;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
if (isBearish &&
|
|
isRSICrossedUnderOverBought &&
|
|
!IsValid(conditions.rsiCrossedUnderOverBoughtAt))
|
|
{
|
|
conditions.rsiCrossedUnderOverBoughtAt = cTime;
|
|
}
|
|
|
|
//
|
|
// Atr Change ...
|
|
// New Peaks and Vale ...
|
|
|
|
//
|
|
// Bullish ...
|
|
if (isBullish &&
|
|
isNewValeBelowAtrLower &&
|
|
!IsValid(conditions.newValeBelowAtrLowerAt))
|
|
{
|
|
conditions.newValeBelowAtrLowerAt = cTime;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
if (isBearish &&
|
|
isNewPeakAboveAtrUpper &&
|
|
!IsValid(conditions.newPeakAboveAtrUpperAt))
|
|
{
|
|
conditions.newPeakAboveAtrUpperAt = cTime;
|
|
}
|
|
|
|
//
|
|
isConditionsFilled = conditions.IsFilled();
|
|
result = isConditionsFilled;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fill Price Zones ...
|
|
bool hasPriceZone = conditions.HasPriceZone();
|
|
if (!hasPriceZone)
|
|
{
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
XPriceZones vPZone;
|
|
bool hasValeInsideZone = CalculatePriceInsideZones(
|
|
vPZone,
|
|
analyseState,
|
|
vale //
|
|
);
|
|
|
|
//
|
|
XPriceZones cbPZone;
|
|
bool hasPriceInsideZone = CalculatePriceInsideZones(
|
|
cbPZone,
|
|
analyseState,
|
|
cBar //
|
|
);
|
|
|
|
//
|
|
if (hasValeInsideZone &&
|
|
hasPriceInsideZone &&
|
|
vPZone.IsBullish() &&
|
|
cbPZone.IsBullish())
|
|
{
|
|
conditions.valePriceZone = cbPZone;
|
|
}
|
|
}
|
|
else if (isBearish)
|
|
{
|
|
//
|
|
XPriceZones pPZone;
|
|
bool hasPeakInsideZone = CalculatePriceInsideZones(
|
|
pPZone,
|
|
analyseState,
|
|
peak //
|
|
);
|
|
|
|
//
|
|
XPriceZones cbPZone;
|
|
bool hasPriceInsideZone = CalculatePriceInsideZones(
|
|
cbPZone,
|
|
analyseState,
|
|
cBar //
|
|
);
|
|
|
|
//
|
|
if (
|
|
hasPeakInsideZone &&
|
|
hasPriceInsideZone &&
|
|
pPZone.IsBearish() &&
|
|
cbPZone.IsBearish())
|
|
{
|
|
conditions.peakPriceZone = cbPZone;
|
|
}
|
|
}
|
|
|
|
//
|
|
hasPriceZone = conditions.HasPriceZone();
|
|
result = hasPriceZone;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check for Decision ...
|
|
bool hasDecision = conditions.HasDecisionZone();
|
|
if (!hasDecision)
|
|
{
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
XPriceZones pZone;
|
|
bool hasPZone = CalculatePriceInsideZones(
|
|
pZone,
|
|
decisionState,
|
|
vale //
|
|
);
|
|
|
|
//
|
|
if (hasPZone &&
|
|
pZone.IsBullish())
|
|
{
|
|
conditions.decisionZone = pZone;
|
|
}
|
|
}
|
|
else if (isBearish)
|
|
{
|
|
//
|
|
XPriceZones pZone;
|
|
bool hasPZone = CalculatePriceInsideZones(
|
|
pZone,
|
|
decisionState,
|
|
peak //
|
|
);
|
|
|
|
//
|
|
if (hasPZone &&
|
|
pZone.IsBearish())
|
|
{
|
|
conditions.decisionZone = pZone;
|
|
}
|
|
}
|
|
|
|
//
|
|
hasDecision = conditions.HasDecisionZone();
|
|
result = hasDecision;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
conditions.setupTime = cTime;
|
|
conditions.dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Conditions ...
|
|
bool DetectX121SMCXTWPVSiganlTrigger(
|
|
//
|
|
X121SMCStrategyXTWPVSignalConditions &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 = IsBullish(setupDir);
|
|
bool isBearish = IsBearish(setupDir);
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
result = pBar.Init(
|
|
symbol,
|
|
period,
|
|
pIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double ask = GetAsk(symbol);
|
|
double bid = GetBid(symbol);
|
|
datetime cTime = TimeCurrent();
|
|
double points = GetPoints(symbol);
|
|
|
|
//
|
|
int swingLoopback = 9;
|
|
double ll = cBar.FindLowest(swingLoopback, MODE_LOW);
|
|
double hh = cBar.FindHighest(swingLoopback, MODE_HIGH);
|
|
double llDown = cBar.FindLowesttDown(swingLoopback);
|
|
double hhUp = cBar.FindHighestUp(swingLoopback);
|
|
|
|
//
|
|
// 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 ...
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
//
|
|
// Cleanup Setup Conditions ...
|
|
int setupAge = conditions.GetSetupAge();
|
|
if (IsValidSize(setupAge) &&
|
|
IsValidSize(maxAllowedSetupAge) &&
|
|
setupAge >= maxAllowedSetupAge)
|
|
{
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Nearest Pivot Point ...
|
|
|
|
//
|
|
// Detect Target ...
|
|
double target = CalculateTarget(
|
|
cBar,
|
|
analyseState,
|
|
setupDir //
|
|
);
|
|
if (target == 0)
|
|
{
|
|
//
|
|
target = CalculateTarget(
|
|
cBar,
|
|
verificationState,
|
|
setupDir //
|
|
);
|
|
}
|
|
|
|
//
|
|
double oppositTarget = CalculateTarget(
|
|
cBar,
|
|
analyseState,
|
|
Opposit(setupDir) //
|
|
);
|
|
|
|
//
|
|
double entry = GetEntry(
|
|
conditions.symbol,
|
|
setupDir //
|
|
);
|
|
|
|
//
|
|
// Filling SL Candidates ...
|
|
|
|
//
|
|
double sls[];
|
|
|
|
//
|
|
double atr = triggerConditions.x121Conditions.atrBuffer[1];
|
|
double peak = triggerConditions.x121Conditions.peaksBuffer[1];
|
|
double vale = triggerConditions.x121Conditions.valesBuffer[1];
|
|
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
double lowerVale = triggerCycleHelper.mX121Helper.GetLowerVale(vale);
|
|
if (lowerVale > 0)
|
|
{
|
|
//
|
|
Add(
|
|
lowerVale,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
else if (isBearish)
|
|
{
|
|
//
|
|
double higherPeak = triggerCycleHelper.mX121Helper.GetHigherPeak(peak);
|
|
if (higherPeak > 0)
|
|
{
|
|
//
|
|
Add(
|
|
higherPeak,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (ArraySize(sls) == 0)
|
|
{
|
|
}
|
|
|
|
//
|
|
double slsMin = GetMin(sls);
|
|
double slsMax = GetMax(sls);
|
|
|
|
//
|
|
double sl = isBullish
|
|
? slsMin - atr
|
|
: slsMax + atr;
|
|
double risk = MathAbs(entry - sl);
|
|
double targetDelta = 2 * (risk / 3);
|
|
if (target == 0)
|
|
{
|
|
//
|
|
int minTargetPint = 50;
|
|
double minTargetPointValue = minTargetPint * points;
|
|
if (targetDelta < minTargetPointValue)
|
|
{
|
|
targetDelta = minTargetPointValue;
|
|
}
|
|
|
|
//
|
|
// Force Target On Half Risk ...
|
|
target =
|
|
isBullish
|
|
? entry + targetDelta
|
|
: entry - targetDelta;
|
|
|
|
//
|
|
target = 0;
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
conditions.sl = sl;
|
|
conditions.target = target;
|
|
conditions.triggerTime = cTime;
|
|
conditions.type = isBullish
|
|
? X_POSITION_TYPE_LONG
|
|
: X_POSITION_TYPE_SHORT;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Draw Signal ...
|
|
int DrawX121SMCXTWPVSiganl(
|
|
X121SMCStrategyXTWPVSignalConditions &conditions,
|
|
XCBaseObject *&drawnObjects[],
|
|
XCPOIDrawer *drawer //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(drawnObjects);
|
|
|
|
//
|
|
if (drawer == NULL)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isSetuped = conditions.IsSetuped();
|
|
if (!isSetuped)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish(conditions.dir);
|
|
|
|
//
|
|
XCBaseObject *priceZoneObjs[];
|
|
XCBaseObject *decisionZoneObjs[];
|
|
XCBaseObject *marketStructureObjs[];
|
|
|
|
//
|
|
bool hasMarketStructure = conditions.HasMarketStrucutre();
|
|
if (hasMarketStructure)
|
|
{
|
|
// //
|
|
// drawer.DrawMarketStructure(
|
|
// conditions.analyseMarketStructure,
|
|
// marketStructureObjs //
|
|
// );
|
|
}
|
|
|
|
//
|
|
bool hasPriceZone = conditions.HasPriceZone();
|
|
if (hasPriceZone)
|
|
{
|
|
//
|
|
XPriceZones pZone;
|
|
if (isBullish)
|
|
{
|
|
pZone = conditions.valePriceZone;
|
|
}
|
|
else
|
|
{
|
|
pZone = conditions.peakPriceZone;
|
|
}
|
|
|
|
//
|
|
drawer.DrawPriceZone(
|
|
pZone,
|
|
priceZoneObjs,
|
|
conditions.dir //
|
|
);
|
|
}
|
|
|
|
//
|
|
bool hasDecisionZone = conditions.HasDecisionZone();
|
|
if (hasDecisionZone)
|
|
{
|
|
//
|
|
drawer.DrawPriceZone(
|
|
conditions.decisionZone,
|
|
decisionZoneObjs
|
|
// ,
|
|
// conditions.dir //
|
|
);
|
|
}
|
|
|
|
//
|
|
Copy(
|
|
priceZoneObjs,
|
|
drawnObjects,
|
|
false //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
decisionZoneObjs,
|
|
drawnObjects,
|
|
false //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
marketStructureObjs,
|
|
drawnObjects,
|
|
false //
|
|
);
|
|
|
|
//
|
|
result = ArraySize(drawnObjects);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|