1693 lines
41 KiB
Plaintext
1693 lines
41 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
|
// -------------------------------------------------
|
|
// Name: XSTRPV
|
|
// 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 X121SMCStrategyXSTRPVSignalConditions
|
|
{
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
double pivot;
|
|
double point;
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCStrategyXSTRPVSignalConditions()
|
|
{
|
|
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()
|
|
{
|
|
//
|
|
pivot = 0;
|
|
point = 0;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Signaller Data Sources ...
|
|
X121SMCStrategyXSTRPVSignalConditions mXSTRPVConditions;
|
|
X121SMCStrategyXSTRPVSignalConditions mXSTRPVConditionsCollection[];
|
|
|
|
//
|
|
// Extension Functions ...
|
|
|
|
//
|
|
// Detect Setup Conditions ...
|
|
bool DetectX121SMCXSTRPVSiganlSetup(
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period,
|
|
//
|
|
X121SMCStrategyXSTRPVSignalConditions &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 = 3;
|
|
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 ...
|
|
|
|
//
|
|
// Waits for new Peak or Vale ...
|
|
|
|
//
|
|
// Reading Previous Conditions ...
|
|
ENUM_XPOI_EVENTS consolidationPoiEventsPrev[];
|
|
ENUM_X_CYCLE_EVENTS consolidationCycleEventsPrev[];
|
|
X121SMCCycleConditions consolidationConditionsPrev;
|
|
result = consolidationCycleHelper.GetConditions(
|
|
consolidationCycleEventsPrev,
|
|
consolidationPoiEventsPrev,
|
|
consolidationConditionsPrev,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Setup Conditions ...
|
|
|
|
//
|
|
// Detect Trend ...
|
|
|
|
//
|
|
ENUM_X_DIRECTION marketDir;
|
|
bool hasMarketDir = decisionCycleHelper.DetectMarketStructure(marketDir);
|
|
|
|
//
|
|
bool hasBullishTrend =
|
|
hasMarketDir &&
|
|
IsBullish(marketDir);
|
|
|
|
//
|
|
bool hasBearishTrend =
|
|
hasMarketDir &&
|
|
IsBearish(marketDir);
|
|
|
|
//
|
|
// Reading Bar State ...
|
|
|
|
//
|
|
// Engulf ...
|
|
ENUM_X_DIRECTION cBarEngulfDir;
|
|
bool isCBarEngulfed = decisionCycleHelper
|
|
.mBarAnalyser
|
|
.IsEngulfBar(
|
|
cBar,
|
|
cBarEngulfDir,
|
|
0 // Extended ...
|
|
);
|
|
bool isCBarBullishEngulfed =
|
|
isCBarEngulfed &&
|
|
IsBullish(cBarEngulfDir);
|
|
bool isCBarBearishEngulfed =
|
|
isCBarEngulfed &&
|
|
IsBearish(cBarEngulfDir);
|
|
|
|
//
|
|
// Momentum ...
|
|
ENUM_X_DIRECTION cBarMomentumDir;
|
|
bool isCBarMomentum = decisionCycleHelper
|
|
.mBarAnalyser
|
|
.IsMomentumBar(
|
|
cBar,
|
|
cBarMomentumDir,
|
|
0 // Extended ...
|
|
);
|
|
bool isCBarBullishMomentum =
|
|
isCBarMomentum &&
|
|
IsBullish(cBarMomentumDir);
|
|
bool isCBarBearishMomentum =
|
|
isCBarMomentum &&
|
|
IsBearish(cBarMomentumDir);
|
|
|
|
//
|
|
// Reject ...
|
|
ENUM_X_DIRECTION cBarRejectDir;
|
|
bool isCBarRejected = decisionCycleHelper
|
|
.mBarAnalyser
|
|
.IsRejectionBar(
|
|
cBar,
|
|
cBarRejectDir,
|
|
0 // Extended ...
|
|
);
|
|
bool isCBarBullishRejected =
|
|
isCBarRejected &&
|
|
IsBullish(cBarRejectDir);
|
|
bool isCBarBearishRejected =
|
|
isCBarRejected &&
|
|
IsBearish(cBarRejectDir);
|
|
|
|
//
|
|
// HH/LL Break ...
|
|
|
|
//
|
|
bool isCBarBreaksUpHH = IsBarBreak(
|
|
hh,
|
|
X_DIRECTION_BULLISH,
|
|
cBar //
|
|
);
|
|
|
|
//
|
|
bool isCBarBreaksDownLL = IsBarBreak(
|
|
hh,
|
|
X_DIRECTION_BEARISH,
|
|
cBar //
|
|
);
|
|
|
|
//
|
|
// Bar Checking Summary ...
|
|
|
|
//
|
|
// Bullish ...
|
|
bool isCBarBullishFormed =
|
|
//
|
|
isCBarBreaksUpHH ||
|
|
isCBarBullishEngulfed ||
|
|
isCBarBullishMomentum ||
|
|
isCBarBullishRejected
|
|
//
|
|
;
|
|
|
|
//
|
|
// Bearish ...
|
|
bool isCBarBearishFormed =
|
|
//
|
|
isCBarBreaksDownLL ||
|
|
isCBarBearishEngulfed ||
|
|
isCBarBearishMomentum ||
|
|
isCBarBearishRejected
|
|
//
|
|
;
|
|
|
|
//
|
|
// Read Slopes ...
|
|
double rsiSlope = decisionConditions.x121Conditions.rsiSlope;
|
|
double strSlope = decisionConditions.x121Conditions.strSlope;
|
|
double atrUpperSlope = decisionConditions.x121Conditions.atrUpperSlope;
|
|
double atrLowerSlope = decisionConditions.x121Conditions.atrLowerSlope;
|
|
double vwapFastSlope = decisionConditions.x121Conditions.vwapFastSlope;
|
|
double vwapMidSlope = decisionConditions.x121Conditions.vwapMidSlope;
|
|
double vwapSlowSlope = decisionConditions.x121Conditions.vwapSlowSlope;
|
|
|
|
//
|
|
bool isRsiSlopeBullish = decisionConditions.x121Conditions.isRsiSlopeBullish;
|
|
bool isStrSlopeBullish = decisionConditions.x121Conditions.isStrSlopeBullish;
|
|
bool isAtrUpperSlopeBullish = decisionConditions.x121Conditions.isAtrUpperSlopeBullish;
|
|
bool isAtrLowerSlopeBullish = decisionConditions.x121Conditions.isAtrLowerSlopeBullish;
|
|
bool isVwapFastSlopeBullish = decisionConditions.x121Conditions.isVwapFastSlopeBullish;
|
|
bool isVwapMidSlopeBullish = decisionConditions.x121Conditions.isVwapMidSlopeBullish;
|
|
bool isVwapSlowSlopeBullish = decisionConditions.x121Conditions.isVwapSlowSlopeBullish;
|
|
|
|
//
|
|
bool isRsiSlopeBearish = decisionConditions.x121Conditions.isRsiSlopeBearish;
|
|
bool isStrSlopeBearish = decisionConditions.x121Conditions.isStrSlopeBearish;
|
|
bool isAtrUpperSlopeBearish = decisionConditions.x121Conditions.isAtrUpperSlopeBearish;
|
|
bool isAtrLowerSlopeBearish = decisionConditions.x121Conditions.isAtrLowerSlopeBearish;
|
|
bool isVwapFastSlopeBearish = decisionConditions.x121Conditions.isVwapFastSlopeBearish;
|
|
bool isVwapMidSlopeBearish = decisionConditions.x121Conditions.isVwapMidSlopeBearish;
|
|
bool isVwapSlowSlopeBearish = decisionConditions.x121Conditions.isVwapSlowSlopeBearish;
|
|
|
|
//
|
|
bool isSlopesBullish =
|
|
isRsiSlopeBullish &&
|
|
isVwapMidSlopeBullish &&
|
|
isAtrUpperSlopeBullish &&
|
|
isAtrLowerSlopeBullish &&
|
|
isVwapFastSlopeBullish &&
|
|
isVwapSlowSlopeBullish;
|
|
|
|
//
|
|
bool isSlopesBearish =
|
|
isRsiSlopeBearish &&
|
|
isVwapMidSlopeBearish &&
|
|
isAtrUpperSlopeBearish &&
|
|
isAtrLowerSlopeBearish &&
|
|
isVwapFastSlopeBearish &&
|
|
isVwapSlowSlopeBearish;
|
|
|
|
//
|
|
// RSI ...
|
|
|
|
//
|
|
double rsiMult1 = 2;
|
|
double rsiMult2 = 2;
|
|
|
|
//
|
|
double rsi = decisionConditions.x121Conditions.rsiBuffer[1];
|
|
|
|
//
|
|
bool isRsiOverSold = decisionConditions.x121Conditions.isRsiOverSold;
|
|
bool isRsiOverBought = decisionConditions.x121Conditions.isRsiOverBought;
|
|
|
|
//
|
|
bool isRsiCrossedOverOverSold = decisionConditions.x121Conditions.isRsiCrossedOverOverSold;
|
|
bool isRsiCrossedUnderOverBought = decisionConditions.x121Conditions.isRsiCrossedUnderOverBought;
|
|
|
|
//
|
|
bool isRsiBullishFormed =
|
|
//
|
|
(rsiSlope > rsiMult2)
|
|
//
|
|
||
|
|
//
|
|
(rsiSlope > rsiMult1 &&
|
|
isRsiCrossedOverOverSold)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isRsiBearishFormed =
|
|
//
|
|
(rsiSlope < (-1 * rsiMult2))
|
|
//
|
|
||
|
|
//
|
|
(rsiSlope < (-1 * rsiMult1) &&
|
|
isRsiCrossedUnderOverBought)
|
|
//
|
|
;
|
|
|
|
//
|
|
// SAR ...
|
|
|
|
//
|
|
double sar = decisionConditions.x121Conditions.sarBuffer[1];
|
|
double sarPrev = decisionConditions.x121Conditions.sarBuffer[2];
|
|
|
|
//
|
|
bool isSarBullish = decisionConditions.x121Conditions.isSarBullish;
|
|
bool isSarBearish = decisionConditions.x121Conditions.isSarBearish;
|
|
|
|
//
|
|
bool isSarSwitchedToBullish = decisionConditions.x121Conditions.isSarSwitchedToBullish;
|
|
bool isSarSwitchedToBearish = decisionConditions.x121Conditions.isSarSwitchedToBearish;
|
|
|
|
//
|
|
bool isPrevSarBreakedUp = IsBarBreak(
|
|
sarPrev,
|
|
X_DIRECTION_BULLISH,
|
|
cBar //
|
|
);
|
|
bool isPrevSarBreakedDown = IsBarBreak(
|
|
sarPrev,
|
|
X_DIRECTION_BEARISH,
|
|
cBar //
|
|
);
|
|
|
|
//
|
|
// ATR ...
|
|
|
|
//
|
|
double atr = decisionConditions.x121Conditions.atrBuffer[1];
|
|
double atrUpper = decisionConditions.x121Conditions.atrUpperBuffer[1];
|
|
double atrLower = decisionConditions.x121Conditions.atrLowerBuffer[1];
|
|
|
|
//
|
|
bool isAtrUpperBullishSlope = atrUpperSlope > 0;
|
|
bool isAtrLowerBullishSlope = atrLowerSlope > 0;
|
|
|
|
//
|
|
bool isAtrUpperBearishSlope = atrUpperSlope < 0;
|
|
bool isAtrLowerBearishSlope = atrLowerSlope < 0;
|
|
|
|
//
|
|
bool isAtrBullishSlope = isAtrUpperBullishSlope &&
|
|
isAtrLowerBullishSlope;
|
|
bool isAtrBearishSlope = isAtrUpperBearishSlope &&
|
|
isAtrLowerBearishSlope;
|
|
|
|
//
|
|
// STR ...
|
|
|
|
//
|
|
double str = decisionConditions.x121Conditions.strBuffer[1];
|
|
|
|
//
|
|
bool isStrBullish = decisionConditions.x121Conditions.isStrBullish;
|
|
bool isStrBearish = decisionConditions.x121Conditions.isStrBearish;
|
|
|
|
//
|
|
bool isStrSwitchedToBullish = decisionConditions.x121Conditions.isStrSwitchedToBullish;
|
|
bool isStrSwitchedToBearish = decisionConditions.x121Conditions.isStrSwitchedToBearish;
|
|
|
|
//
|
|
// PV ...
|
|
|
|
//
|
|
double peak = decisionConditions.x121Conditions.peaksBuffer[1];
|
|
double vale = decisionConditions.x121Conditions.valesBuffer[1];
|
|
|
|
//
|
|
bool isPeakIncreasing = IsIncreasing(decisionConditions.x121Conditions.peaksBuffer);
|
|
bool isPeakDecreasing = IsDecreasing(decisionConditions.x121Conditions.peaksBuffer);
|
|
|
|
//
|
|
bool isValeIncreasing = IsIncreasing(decisionConditions.x121Conditions.valesBuffer);
|
|
bool isValeDecreasing = IsDecreasing(decisionConditions.x121Conditions.valesBuffer);
|
|
|
|
//
|
|
bool isPVIncreasing = (isPeakIncreasing &&
|
|
isValeIncreasing) &&
|
|
!(isPeakDecreasing &&
|
|
isValeDecreasing);
|
|
bool isPVDecreasing = (isPeakDecreasing &&
|
|
isValeDecreasing) &&
|
|
!(isPeakIncreasing &&
|
|
isValeIncreasing);
|
|
|
|
//
|
|
bool isNewPeak = decisionConditions.x121Conditions.isNewPeak;
|
|
bool isNewPeakOverLast = decisionConditions.x121Conditions.isNewPeakOverLast;
|
|
bool isNewPeakUnderLast = decisionConditions.x121Conditions.isNewPeakUnderLast;
|
|
|
|
//
|
|
bool isNewVale = decisionConditions.x121Conditions.isNewVale;
|
|
bool isNewValeOverLast = decisionConditions.x121Conditions.isNewValeOverLast;
|
|
bool isNewValeUnderLast = decisionConditions.x121Conditions.isNewValeUnderLast;
|
|
|
|
//
|
|
bool isPVBullishFormed =
|
|
isPVIncreasing ||
|
|
isNewPeakOverLast ||
|
|
isNewValeOverLast;
|
|
|
|
//
|
|
bool isPVBearishFormed =
|
|
isPVDecreasing ||
|
|
isNewPeakUnderLast ||
|
|
isNewValeUnderLast;
|
|
|
|
//
|
|
// VWAP ...
|
|
|
|
//
|
|
bool isVWapFastOverMid = decisionConditions.x121Conditions.isVWapFastOverMid;
|
|
bool isVWapFastUnderMid = decisionConditions.x121Conditions.isVWapFastUnderMid;
|
|
|
|
//
|
|
bool isVWapBullishState = decisionConditions.x121Conditions.isVWapBullishState;
|
|
bool isVWapBearishState = decisionConditions.x121Conditions.isVWapBearishState;
|
|
|
|
//
|
|
bool isVWapSwitchedToBullishState = decisionConditions.x121Conditions.isVWapSwitchedToBullishState;
|
|
bool isVWapSwitchedToBearishState = decisionConditions.x121Conditions.isVWapSwitchedToBearishState;
|
|
|
|
//
|
|
bool isVWapBullishOrdered = decisionConditions.x121Conditions.isVWapBullishOrdered;
|
|
bool isVWapBearishOrdered = decisionConditions.x121Conditions.isVWapBearishOrdered;
|
|
|
|
//
|
|
bool isVWapSwitchedToBullishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBullishOrdered;
|
|
bool isVWapSwitchedToBearishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBearishOrdered;
|
|
|
|
//
|
|
bool isVWapMinBreakedUp = decisionConditions.x121Conditions.isVWapMinBreakedUp;
|
|
bool isVWapMaxBreakedUp = decisionConditions.x121Conditions.isVWapMaxBreakedUp;
|
|
|
|
//
|
|
bool isVWapMinBreakedDown = decisionConditions.x121Conditions.isVWapMinBreakedDown;
|
|
bool isVWapMaxBreakedDown = decisionConditions.x121Conditions.isVWapMaxBreakedDown;
|
|
|
|
//
|
|
bool isVWapFastCrossedOverMid = decisionConditions.x121Conditions.isVWapFastCrossedOverMid;
|
|
bool isVWapFastCrossedUnderMid = decisionConditions.x121Conditions.isVWapFastCrossedUnderMid;
|
|
|
|
//
|
|
bool isVWapFastCrossedOverSlow = decisionConditions.x121Conditions.isVWapFastCrossedOverSlow;
|
|
bool isVWapFastCrossedUnderSlow = decisionConditions.x121Conditions.isVWapFastCrossedUnderSlow;
|
|
|
|
//
|
|
bool isClosedOverVWapMin = decisionConditions.x121Conditions.isClosedOverVWapMin;
|
|
bool isClosedUnderVWapMin = decisionConditions.x121Conditions.isClosedUnderVWapMin;
|
|
|
|
//
|
|
bool isClosedOverVWapMax = decisionConditions.x121Conditions.isClosedOverVWapMax;
|
|
bool isClosedUnderVWapMax = decisionConditions.x121Conditions.isClosedUnderVWapMax;
|
|
|
|
//
|
|
bool isVWapBullishSlope =
|
|
vwapFastSlope > 0 &&
|
|
vwapMidSlope > 0 &&
|
|
vwapSlowSlope > 0;
|
|
|
|
//
|
|
bool isVWapBearishSlope =
|
|
vwapFastSlope < 0 &&
|
|
vwapMidSlope < 0 &&
|
|
vwapSlowSlope < 0;
|
|
|
|
//
|
|
bool isVWapBullishFormed =
|
|
//
|
|
isVWapBullishSlope
|
|
//
|
|
&&
|
|
//
|
|
(
|
|
//
|
|
(isVWapBullishOrdered &&
|
|
isVWapSwitchedToBullishState)
|
|
//
|
|
||
|
|
//
|
|
(isVWapBullishState &&
|
|
isVWapSwitchedToBullishOrdered)
|
|
//
|
|
||
|
|
//
|
|
((isVWapMaxBreakedUp ||
|
|
isClosedOverVWapMax) &&
|
|
(isVWapFastCrossedOverMid ||
|
|
isVWapFastCrossedOverSlow))
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isVWapBearishFormed =
|
|
//
|
|
isVWapBearishSlope
|
|
//
|
|
&&
|
|
//
|
|
(
|
|
//
|
|
(isVWapBearishOrdered &&
|
|
isVWapSwitchedToBearishState)
|
|
//
|
|
||
|
|
//
|
|
(isVWapBearishState &&
|
|
isVWapSwitchedToBearishOrdered)
|
|
//
|
|
||
|
|
//
|
|
((isVWapMinBreakedDown ||
|
|
isClosedUnderVWapMin) &&
|
|
(isVWapFastCrossedUnderMid ||
|
|
isVWapFastCrossedUnderSlow))
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
// Complext ...
|
|
|
|
//
|
|
bool isSarIncreased = decisionConditions.x121Conditions.isSarIncreased;
|
|
bool isSarDecreased = decisionConditions.x121Conditions.isSarDecreased;
|
|
bool isSarEqualsToPeak = decisionConditions.x121Conditions.isSarEqualsToPeak;
|
|
bool isSarEqualsToVale = decisionConditions.x121Conditions.isSarEqualsToVale;
|
|
bool isStrEqualsToPeak = decisionConditions.x121Conditions.isStrEqualsToPeak;
|
|
bool isStrEqualsToVale = decisionConditions.x121Conditions.isStrEqualsToVale;
|
|
bool isStrUpperOverPeak = decisionConditions.x121Conditions.isStrUpperOverPeak;
|
|
bool isPeakOverAtrUpper = decisionConditions.x121Conditions.isPeakOverAtrUpper;
|
|
bool isStrLowerOverVale = decisionConditions.x121Conditions.isStrLowerOverVale;
|
|
bool isBreakedUpPrevSar = decisionConditions.x121Conditions.isBreakedUpPrevSar;
|
|
bool isBreakedUpPrevStr = decisionConditions.x121Conditions.isBreakedUpPrevStr;
|
|
bool isStrLowerUnderVale = decisionConditions.x121Conditions.isStrLowerUnderVale;
|
|
bool isStrUpperUnderPeak = decisionConditions.x121Conditions.isStrUpperUnderPeak;
|
|
bool isValeUnderAtrLower = decisionConditions.x121Conditions.isValeUnderAtrLower;
|
|
bool isSarCrossedOverVale = decisionConditions.x121Conditions.isSarCrossedOverVale;
|
|
bool isStrCrossedOverVale = decisionConditions.x121Conditions.isStrCrossedOverVale;
|
|
bool isBreakedDownPrevStr = decisionConditions.x121Conditions.isBreakedDownPrevStr;
|
|
bool isBreakedDownPrevSar = decisionConditions.x121Conditions.isBreakedDownPrevSar;
|
|
bool isSarCrossedUnderPeak = decisionConditions.x121Conditions.isSarCrossedUnderPeak;
|
|
bool isStrCrossedUnderPeak = decisionConditions.x121Conditions.isStrCrossedUnderPeak;
|
|
bool isNewPeakOverAtrUpper = decisionConditions.x121Conditions.isNewPeakOverAtrUpper;
|
|
bool isNewValeUnderAtrLower = decisionConditions.x121Conditions.isNewValeUnderAtrLower;
|
|
bool isStrUpperOverAtrUpper = decisionConditions.x121Conditions.isStrUpperOverAtrUpper;
|
|
bool isStrLowerOverAtrLower = decisionConditions.x121Conditions.isStrLowerOverAtrLower;
|
|
bool isStrUpperUnderAtrUpper = decisionConditions.x121Conditions.isStrUpperUnderAtrUpper;
|
|
bool isStrLowerUnderAtrLower = decisionConditions.x121Conditions.isStrLowerUnderAtrLower;
|
|
bool isBreakedUpPrevAtrUpper = decisionConditions.x121Conditions.isBreakedUpPrevAtrUpper;
|
|
bool isBreakedUpPrevAtrLower = decisionConditions.x121Conditions.isBreakedUpPrevAtrLower;
|
|
bool isBreakedDownPrevAtrUpper = decisionConditions.x121Conditions.isBreakedDownPrevAtrUpper;
|
|
bool isBreakedDownPrevAtrLower = decisionConditions.x121Conditions.isBreakedDownPrevAtrLower;
|
|
bool isDonLowLowerEqualsToVale = decisionConditions.x121Conditions.isDonLowLowerEqualsToVale;
|
|
bool isStrUpperCrossedOverPeak = decisionConditions.x121Conditions.isStrUpperCrossedOverPeak;
|
|
bool isStrLowerCrossedOverVale = decisionConditions.x121Conditions.isStrLowerCrossedOverVale;
|
|
bool isStrLowerOverDonLowLower = decisionConditions.x121Conditions.isStrLowerOverDonLowLower;
|
|
bool isStrUpperOverDonHighUpper = decisionConditions.x121Conditions.isStrUpperOverDonHighUpper;
|
|
bool isStrLowerUnderDonLowLower = decisionConditions.x121Conditions.isStrLowerUnderDonLowLower;
|
|
bool isDonHighUpperEqualsToPeak = decisionConditions.x121Conditions.isDonHighUpperEqualsToPeak;
|
|
bool isStrUpperCrossedUnderPeak = decisionConditions.x121Conditions.isStrUpperCrossedUnderPeak;
|
|
bool isStrLowerCrossedUnderVale = decisionConditions.x121Conditions.isStrLowerCrossedUnderVale;
|
|
bool isStrUpperUnderDonHighUpper = decisionConditions.x121Conditions.isStrUpperUnderDonHighUpper;
|
|
bool isStrLowerCrossedOverAtrLower = decisionConditions.x121Conditions.isStrLowerCrossedOverAtrLower;
|
|
bool isStrUpperCrossedOverAtrUpper = decisionConditions.x121Conditions.isStrUpperCrossedOverAtrUpper;
|
|
bool isStrUpperCrossedUnderAtrUpper = decisionConditions.x121Conditions.isStrUpperCrossedUnderAtrUpper;
|
|
bool isStrLowerCrossedUnderAtrLower = decisionConditions.x121Conditions.isStrLowerCrossedUnderAtrLower;
|
|
bool isStrLowerCrossedOverDonLowLower = decisionConditions.x121Conditions.isStrLowerCrossedOverDonLowLower;
|
|
bool isStrUpperCrossedOverDonHighUpper = decisionConditions.x121Conditions.isStrUpperCrossedOverDonHighUpper;
|
|
bool isStrLowerCrossedUnderDonLowLower = decisionConditions.x121Conditions.isStrLowerCrossedUnderDonLowLower;
|
|
bool isStrUpperCrossedUnderDonHighUpper = decisionConditions.x121Conditions.isStrUpperCrossedUnderDonHighUpper;
|
|
|
|
//
|
|
XPriceZones priceZones;
|
|
bool hasPriceZones = CalculatePriceInsideZones(
|
|
priceZones,
|
|
analyseState,
|
|
cBar //
|
|
);
|
|
double priceZonesUpper = 0;
|
|
double priceZonesLower = 0;
|
|
bool isPriceZoneValidForPeak = false;
|
|
bool isPriceZoneValidForVale = false;
|
|
if (hasPriceZones)
|
|
{
|
|
//
|
|
bool hasBoundary = priceZones.GetBoundary(
|
|
X_DIRECTION_ALL,
|
|
priceZonesUpper,
|
|
priceZonesLower //
|
|
);
|
|
|
|
//
|
|
isPriceZoneValidForPeak =
|
|
hasBoundary &&
|
|
peak <= priceZonesUpper &&
|
|
peak >= priceZonesLower;
|
|
|
|
//
|
|
isPriceZoneValidForVale =
|
|
hasBoundary &&
|
|
vale <= priceZonesUpper &&
|
|
vale >= priceZonesLower;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Method 1 ...
|
|
// VWap Switch Start ...
|
|
|
|
//
|
|
bool bullishMethod1 =
|
|
//
|
|
isSarBullish &&
|
|
isStrBullish &&
|
|
isSlopesBullish &&
|
|
hasBullishTrend &&
|
|
cBar.IsBullish() &&
|
|
isAtrBullishSlope &&
|
|
isPVBullishFormed &&
|
|
isRsiBullishFormed &&
|
|
isVWapBullishFormed
|
|
//
|
|
;
|
|
|
|
//
|
|
bool bearishMethod1 =
|
|
//
|
|
isSarBearish &&
|
|
isStrBearish &&
|
|
isSlopesBearish &&
|
|
hasBearishTrend &&
|
|
cBar.IsBearish() &&
|
|
isAtrBearishSlope &&
|
|
isPVBearishFormed &&
|
|
isRsiBearishFormed &&
|
|
isVWapBearishFormed
|
|
//
|
|
;
|
|
|
|
//
|
|
// Method 2 ...
|
|
// PV Start ...
|
|
|
|
//
|
|
bool bullishMethod2 =
|
|
//
|
|
false
|
|
// isStrCrossedOverVale
|
|
//
|
|
;
|
|
|
|
//
|
|
bool bearishMethod2 =
|
|
//
|
|
!isNewVale &&
|
|
(
|
|
//
|
|
isStrCrossedUnderPeak
|
|
//
|
|
||
|
|
//
|
|
(isPrevSarBreakedDown &&
|
|
isStrSwitchedToBearish)
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
|
|
//
|
|
// Summarize Conditions ...
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
// bullishMethod1
|
|
// //
|
|
// ||
|
|
//
|
|
bullishMethod2
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
// bearishMethod1
|
|
// //
|
|
// ||
|
|
//
|
|
bearishMethod2
|
|
//
|
|
;
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
conditions.point =
|
|
isBullish
|
|
? vale
|
|
: peak;
|
|
conditions.setupTime = cTime;
|
|
conditions.dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
double point = GetEntry(
|
|
conditions.symbol,
|
|
conditions.dir //
|
|
);
|
|
conditions.point = point;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Conditions ...
|
|
bool DetectX121SMCXSTRPVSiganlTrigger(
|
|
//
|
|
X121SMCStrategyXSTRPVSignalConditions &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 ...
|
|
|
|
//
|
|
// SAR ...
|
|
double sar = decisionConditions.x121Conditions.sarBuffer[1];
|
|
|
|
//
|
|
// STR ...
|
|
double str = decisionConditions.x121Conditions.strBuffer[1];
|
|
|
|
//
|
|
// ATR ...
|
|
double atrUpper = decisionConditions.x121Conditions.atrUpperBuffer[1];
|
|
double atrLower = decisionConditions.x121Conditions.atrLowerBuffer[1];
|
|
|
|
//
|
|
// PV ...
|
|
double peak = decisionConditions.x121Conditions.peaksBuffer[1];
|
|
double vale = decisionConditions.x121Conditions.valesBuffer[1];
|
|
|
|
//
|
|
int higherPeakIDX = -1;
|
|
double higherPeak = decisionCycleHelper
|
|
.mX121Helper
|
|
.xpvHelper.GetHigherPeak(
|
|
higherPeakIDX,
|
|
peak //
|
|
);
|
|
|
|
//
|
|
int lowerValeIDX = -1;
|
|
double lowerVale = decisionCycleHelper
|
|
.mX121Helper
|
|
.xpvHelper.GetLowerVale(
|
|
lowerValeIDX,
|
|
vale //
|
|
);
|
|
|
|
//
|
|
double point = conditions.point;
|
|
bool isPointBreak = IsBarBreak(
|
|
point,
|
|
setupDir,
|
|
cBar //
|
|
);
|
|
|
|
//
|
|
// Detect Bullish Conditions ...
|
|
isBullish =
|
|
//
|
|
isBullish &&
|
|
isPointBreak &&
|
|
cBar.IsBullish()
|
|
//
|
|
// &&
|
|
// //
|
|
// false
|
|
//
|
|
;
|
|
|
|
//
|
|
// Detect Bearish Conditions ...
|
|
isBearish =
|
|
//
|
|
isBearish &&
|
|
isPointBreak &&
|
|
cBar.IsBearish()
|
|
//
|
|
// &&
|
|
// //
|
|
// false
|
|
//
|
|
;
|
|
|
|
//
|
|
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,
|
|
decisionState,
|
|
setupDir //
|
|
);
|
|
if (target == 0)
|
|
{
|
|
//
|
|
target = CalculateTarget(
|
|
cBar,
|
|
analyseState,
|
|
setupDir //
|
|
);
|
|
|
|
//
|
|
if (target == 0)
|
|
{
|
|
//
|
|
target = CalculateTarget(
|
|
cBar,
|
|
verificationState,
|
|
setupDir //
|
|
);
|
|
}
|
|
}
|
|
target = 0;
|
|
|
|
//
|
|
double entry = GetEntry(
|
|
conditions.symbol,
|
|
setupDir //
|
|
);
|
|
|
|
//
|
|
// Filling SL Candidates ...
|
|
double momentumBarPointsDif = 30 * points;
|
|
|
|
//
|
|
// Bullish Momentum Bar Selection ...
|
|
XOHCL bullishMomentumBar;
|
|
int bullishMomentumBarsCount = decisionState.CountBullishMomentumBars();
|
|
if (IsValidSize(bullishMomentumBarsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishMomentumBarsCount; i++)
|
|
{
|
|
//
|
|
XCMomentumBar *iMomentum = decisionState.bullishMomentumBars[i];
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool isFilled = iMomentum.FillBar(iBar);
|
|
if (!isFilled)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool isValidDistane = (MathAbs(iBar.low) - entry) >= momentumBarPointsDif;
|
|
if (!isValidDistane)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool isIndexPassed = iBar.Index() <= 5;
|
|
if (!isIndexPassed)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool canSet =
|
|
!bullishMomentumBar.IsValid() ||
|
|
(bullishMomentumBar.IsValid() &&
|
|
bullishMomentumBar.low < entry &&
|
|
bullishMomentumBar.Index() > iBar.Index());
|
|
if (canSet)
|
|
{
|
|
bullishMomentumBar = iBar;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Momentum Bar Selection ...
|
|
XOHCL bearishMomentumBar;
|
|
int bearishMomentumBarsCount = decisionState.CountBearishMomentumBars();
|
|
if (IsValidSize(bearishMomentumBarsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishMomentumBarsCount; i++)
|
|
{
|
|
//
|
|
XCMomentumBar *iMomentum = decisionState.bearishMomentumBars[i];
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool isFilled = iMomentum.FillBar(iBar);
|
|
if (!isFilled)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool isValidDistane = (MathAbs(iBar.high) - entry) >= momentumBarPointsDif;
|
|
if (!isValidDistane)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool isIndexPassed = iBar.Index() <= 5;
|
|
if (!isIndexPassed)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool canSet =
|
|
!bearishMomentumBar.IsValid() ||
|
|
(bearishMomentumBar.IsValid() &&
|
|
bearishMomentumBar.high > entry &&
|
|
bearishMomentumBar.Index() > iBar.Index());
|
|
if (canSet)
|
|
{
|
|
bearishMomentumBar = iBar;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
double sls[];
|
|
Add(
|
|
sar,
|
|
sls //
|
|
);
|
|
Add(
|
|
str,
|
|
sls //
|
|
);
|
|
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
Add(
|
|
atrLower,
|
|
sls //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
vale,
|
|
sls //
|
|
);
|
|
|
|
//
|
|
if (bullishMomentumBar.IsValid())
|
|
{
|
|
//
|
|
Add(
|
|
bullishMomentumBar.low,
|
|
sls //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (IsValidIndex(lowerValeIDX))
|
|
{
|
|
//
|
|
Add(
|
|
lowerVale,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
Add(
|
|
atrUpper,
|
|
sls //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
peak,
|
|
sls //
|
|
);
|
|
|
|
//
|
|
if (bearishMomentumBar.IsValid())
|
|
{
|
|
//
|
|
Add(
|
|
bearishMomentumBar.high,
|
|
sls //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (IsValidIndex(higherPeakIDX))
|
|
{
|
|
//
|
|
Add(
|
|
higherPeak,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
double iAtr = decisionConditions.x121Conditions.atrBuffer[1];
|
|
|
|
//
|
|
double slsMin = GetMin(sls);
|
|
double slsMax = GetMax(sls);
|
|
|
|
//
|
|
double sl = isBullish
|
|
? slsMin - iAtr
|
|
: slsMax + iAtr;
|
|
double risk = MathAbs(entry - sl);
|
|
double riskInPoints = risk / points;
|
|
if (riskInPoints >= 150)
|
|
{
|
|
//
|
|
target =
|
|
isBullish
|
|
? entry + (points * 200)
|
|
: entry - (points * 200);
|
|
|
|
//
|
|
target = 0;
|
|
}
|
|
|
|
//
|
|
// Filling Conditions Props ...
|
|
conditions.sl = sl;
|
|
conditions.target = target;
|
|
conditions.triggerTime = cTime;
|
|
conditions.type = isBullish
|
|
? X_POSITION_TYPE_LONG
|
|
: X_POSITION_TYPE_SHORT;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int AddX121SMCXSTRPVConditionsIfNotExists(
|
|
X121SMCStrategyXSTRPVSignalConditions &item,
|
|
X121SMCStrategyXSTRPVSignalConditions &items[],
|
|
int maxAllowed = 10 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool isSetuped = IsValid(item.setupTime) &&
|
|
HasDirection(item.dir);
|
|
if (!isSetuped)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
// Copy Original Items ...
|
|
X121SMCStrategyXSTRPVSignalConditions tmpItems[];
|
|
Copy(
|
|
items,
|
|
tmpItems //
|
|
);
|
|
|
|
//
|
|
// Prese Item Data ...
|
|
bool isBullish = IsBullish(item.dir);
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
X121SMCStrategyXSTRPVSignalConditions iItem = tmpItems[i];
|
|
|
|
//
|
|
bool canRemove = item.dir == iItem.dir &&
|
|
item.pivot == iItem.pivot;
|
|
if (canRemove)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
items,
|
|
i,
|
|
1 //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
Clean(tmpItems);
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
item,
|
|
items //
|
|
);
|
|
|
|
//
|
|
// Remove Olds ...
|
|
CleanupArray(
|
|
items,
|
|
maxAllowed //
|
|
);
|
|
|
|
//
|
|
result = ArraySize(items);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|