From 9ba70d733aba136d709eeb00ff47f94744df9411 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 28 Nov 2024 07:16:23 +0330 Subject: [PATCH] Last Works ... --- Documents/BKP/x-121.smc.FULL.lib.mq5 | 1798 +++++++++++ .../x-121.smc.test.strategy.FULL.class.mq5 | 2830 +++++++++++++++++ .../Classes/x-121.smc.base.strategy.class.mq5 | 119 +- .../x-121.smc.market.cycle.helper.class.mq5 | 468 +++ X121SMCEA/Libraries/x-121.smc.lib.mq5 | 643 +++- .../x-121.smc.test.strategy.class.mq5 | 1405 +++----- 6 files changed, 6196 insertions(+), 1067 deletions(-) create mode 100644 Documents/BKP/x-121.smc.FULL.lib.mq5 create mode 100644 Documents/BKP/x-121.smc.test.strategy.FULL.class.mq5 create mode 100644 X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 diff --git a/Documents/BKP/x-121.smc.FULL.lib.mq5 b/Documents/BKP/x-121.smc.FULL.lib.mq5 new file mode 100644 index 00000000..e88a3ac2 --- /dev/null +++ b/Documents/BKP/x-121.smc.FULL.lib.mq5 @@ -0,0 +1,1798 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: X121SMCLib +// Description: provide all commonly used 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-saherelm.base.class.mq5" +#include "../../Helpers/x-saherelm.x3ma.helper.mq5" +#include "../../Helpers/x-saherelm.x3vwap.helper.mq5" +#include "../../Helpers/x-saherelm.xchsar.helper.mq5" +#include "../../Helpers/x-saherelm.xpv.helper.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" +#include "../../Libraries/x-saherelm.x-poi.lib.mq5" +#include "../../Libraries/x-saherelm.x-trade.lib.mq5" + +// +// Definitions ... + +const string X121SMCStrategyToken = "X121SMC"; + +const string X121SMCPVToken = "X121SMCPV"; +const string X121SMCBOSToken = "X121SMCBOS"; +const string X121SMCSARToken = "X121SMCSAR"; +const string X121SMCCHOCHToken = "X121SMCCHOCH"; +const string X121SMCPULLBKToken = "X121SMCPULLBK"; + +enum ENUM_X_121_SMC_PROVIDERS +{ + // + X_121_SMC_PROVIDER_NONE, + X_121_SMC_PROVIDER_PV, + X_121_SMC_PROVIDER_BOS, + X_121_SMC_PROVIDER_SAR, + X_121_SMC_PROVIDER_CHOCH, + X_121_SMC_PROVIDER_PULLBK, +}; + +enum ENUM_XPV_PIVOTS +{ + XPV_NONE, + XPV_PEAK, + XPV_VALE, +}; + +struct XPVPivot +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + datetime from; + datetime to; + + // + int repetition; + + // + ENUM_XPV_PIVOTS type; + + // + // Combined all States ... + XPOIState state; + + // + XPVPivot() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + + // + to = NULL; + from = NULL; + symbol = NULL; + period = NULL; + + // + repetition = 0; + + // + type = XPV_NONE; + + // + state.Clean(); + } + + /** + * Validation ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(to) && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + repetition > 0 && + type != XPV_NONE && + (upper > 0 || lower > 0) + // + ; + + // + return result; + } + + /** + * Check Pivot is Peak ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check Pivot is Vale ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + /** + * Calculate Lower for Peaks ... + * + * @return ( double ) + */ + double CalculateLower() + { + // + double result = 0; + + // + if (!IsValid() || + !IsPeak()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int llIDX = iLowest( + symbol, + period, + MODE_LOW, + count, + toIndex // + ); + + // + result = + iLow( + symbol, + period, + llIDX // + ); + + // + return result; + } + + /** + * Calculate Upper for Vales ... + * + * @return ( double ) + */ + double CalculateUpper() + { + // + double result = 0; + + // + if (!IsValid() || + !IsVale()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int hhIDX = iHighest( + symbol, + period, + MODE_HIGH, + count, + toIndex // + ); + + // + result = + iHigh( + symbol, + period, + hhIDX // + ); + + // + return result; + } + + /** + * Calculate Range of Pivot ... + * + * @return ( double ) + */ + double CalculateRange() + { + // + double result = 0; + + // + if (!IsValid() || + upper <= 0 || + lower <= 0) + { + return result; + } + + // + result = upper - lower; + + // + return result; + } + + /** + * Calculate Middle of Pivot ... + * Used for + * @return ( double ) + */ + double CalculateMid() + { + // + double result = 0; + + // + double range = CalculateRange(); + if (range <= 0) + { + return result; + } + + // + result = lower + (range / 2); + + // + return result; + } + + /** + * Calculate Liquidity Percent for Specified Direction ... + * + * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... + * @param price: Double, Specified Price ... + * + * @return ( double ) + */ + double CalculateLiquidityPercent( + ENUM_X_DIRECTION forDirection, + double price = 0 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = state + .CalculateLiquidityPercent( + forDirection, + price // + ); + + // + return result; + } + + // + + /** + * Get Unique Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = symbol + "_" + + ToString(period) + "_" + + ToString(upper) + "," + + ToString(lower) + "_" + + ToString(from) + "," + + ToString(to); + hash = ToMD5(hash); + + // + string typeStr = + type == XPV_PEAK + ? "Peak" + : "Vale"; + + // + result = + // + "XPV_" + + typeStr + "_" + + symbol + "_" + + ToString(period) + + "_" + hash + // + ; + + // + return result; + } + + // +}; + +// +// Model Signalling Conditions ... +struct X121SMCStrategyConditions +{ + // + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + XPVConditions xpvConditions; + X3MAConditions x3maConditions; + X3VWAPConditions x3vwapConditions; + XCHSARConditions xchsarConditions; + + // + void X121SMCStrategyConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + time = NULL; + + // + xpvConditions.Clean(); + x3maConditions.Clean(); + x3vwapConditions.Clean(); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(time); + + // + return result; + } + + // + // Reporter Functions ... + + /** + * Generate Provided Scores ... + * + * @param bullishScore: Integer, reference ... + * @param bearishScore: Integer, referenceF ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + if (!IsValid()) + { + return; + } + + // + double bullScore = 0; + double bearScore = 0; + + // // + // // XPV ... + // pvConditions.GenerateScore( + // bullScore, + // bearScore // + // ); + // bullishScore += bullScore; + // bearishScore += bearScore; + } + + /** + * Generate Summary ... + * + * @param onlyCommons: Boolean ... + * @param onlyConditions: Boolean ... + * @param includeScores: Boolean ... + * @param ignoreFalseConditions: Boolean ... + * @param separator: String ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores, + true // + ); + + // // + // // XPV ... + // string pvStr = pvConditions.GenerateSummary( + // false, + // true, + // false, + // ignoreFalseConditions // + // ); + + // + string conditionsStr = + // + // pvStr + separator + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + "----------" + separator + + (onlyConditions + ? "" + : commonStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Get Unique Identifier ... + * + * @param forObject: Boolean ... + * + * @return ( string ) + */ + string GetTag( + bool forObject = false // + ) + { + // + string result = NULL; + + // + if (!forObject) + { + result = X121SMCStrategyToken; + } + else + { + // + result = X121SMCStrategyToken + "_" + + symbol + "_" + ToString(period) + "_" + + ToMD5(time); + } + + // + return result; + } + + // +}; + +typedef void (*TOnX121SMCSignal)( + XSignal &signal, + X121SMCStrategyConditions &conditions // +); + +// +// Time Frames Tools ... + +/** + * Calculate Analyse Period ... + * + * @param value: ENUM_TIMEFRAMES member, Specified Trigger Period ... + * + * @return ( ENUM_TIMEFRAMES ) + */ +ENUM_TIMEFRAMES GetAnalysePeriod(ENUM_TIMEFRAMES value) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + value = NormalizePeriod(value); + + // + switch (value) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + default: + result = NULL; + } + + // + return result; +} +bool HasValidAnalysePeriod( + ENUM_TIMEFRAMES value, + ENUM_TIMEFRAMES &period // +) +{ + // + bool result = false; + + period = GetAnalysePeriod(value); + result = IsValid(period); + + // + return result; +} + +/** + * Calculate Vision Period ... + * + * @param value: ENUM_TIMEFRAMES member, Specified Trigger Period ... + * + * @return ( ENUM_TIMEFRAMES ) + */ +ENUM_TIMEFRAMES GetVisionPeriod(ENUM_TIMEFRAMES value) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + value = NormalizePeriod(value); + + // + switch (value) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_H1; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H6; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_D1; + break; + + // + default: + result = NULL; + } + + // + return result; +} +bool HasValidVisionPeriod( + ENUM_TIMEFRAMES value, + ENUM_TIMEFRAMES &period // +) +{ + // + bool result = false; + + period = GetVisionPeriod(value); + result = IsValid(period); + + // + return result; +} + +// +// Extentions ... + +/** + * Find Oldest Pivot Index ... + * + * @param pivots: XPVPivot instance ... + * @return ( int ) + */ +int FindOldestPivotIndex( + XPVPivot &pivots[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(pivots); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + bool isOldest = true; + for (int j = 0; j < count; j++) + { + // + XPVPivot jPivot = pivots[j]; + + // + isOldest = iPivot.from <= jPivot.from; + if (!isOldest) + { + break; + } + } + + // + if (isOldest) + { + // + result = i; + break; + } + } + + // + return result; +} + +/** + * Sort Pivots Based On From Date ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void SortPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1); + } + else + { + // + int idx = FindOldestPivotIndex(tmp); + if (IsValidIndex(idx)) + { + // + AddRef( + tmp[idx], + pivots // + ); + + // + ArrayRemove( + tmp, + idx, + 1 // + ); + } + } + } + + // + Clean(tmp); +} + +bool IsPivotBreaked( + XPVPivot &pivot, + XPVPivot &pivots[] // +) +{ + // + bool result = false; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + int count = ArraySize(pivots); + result = IsValidSize(pivots); + if (!result) + { + return result; + } + + // + // For Peaks Highs Must not Broked ... + // For Vales Lows Must not Broked ... + bool isPeak = pivot.IsPeak(); + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + result = isPeak + ? iPivot.upper > pivot.upper + : iPivot.lower < pivot.lower; + if (result) + { + break; + } + } + + // + return result; +} + +/** + * Filter Broken Pivots for Detect Order Flow ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void FilterBrokenPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + } + else + { + // + XPVPivot pivot = tmp[0]; + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + + // + bool isBreaked = IsPivotBreaked( + pivot, + tmp // + ); + if (!isBreaked) + { + // + AddRef( + pivot, + pivots // + ); + } + } + } + + // + Clean(tmp); +} + +/** + * Calculate Order Flow Direction ... + * + * @param orderFlow: XPVPivot instance Collection reference ... + * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... + * + * @return ( bool ) + */ +bool DetectPivotDirection( + XPVPivot &orderFlow[], + ENUM_X_DIRECTION &dir // +) +{ + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + int count = ArraySize(orderFlow); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... + bool isBullish = false; + bool canLookupForBullish = true; + + // + // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... + bool isBearish = false; + bool canLookupForBearish = true; + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = orderFlow[i]; + + // + XPVPivot tmp[]; + Copy( + orderFlow, + tmp // + ); + ArrayRemove( + tmp, + 0, + i + 1 // + ); + + // + int tmpCount = ArraySize(tmp); + if (IsValidSize(tmpCount)) + { + // + for (int j = 0; j < tmpCount; j++) + { + // + XPVPivot jPivot = tmp[j]; + + // + // Check Bullish Direction ... + isBullish = + canLookupForBullish && + jPivot.lower >= iPivot.lower; + if (!isBullish) + { + canLookupForBullish = false; + } + + // + // Check Bearish Direction ... + isBearish = + canLookupForBearish && + jPivot.upper <= iPivot.upper; + if (!isBearish) + { + canLookupForBearish = false; + } + + // + if (!canLookupForBullish && + !canLookupForBearish) + { + break; + } + } + } + Clean(tmp); + } + + // + if (isBullish && + !isBearish) + { + dir = X_DIRECTION_BULLISH; + } + else if (isBearish && + !isBullish) + { + dir = X_DIRECTION_BEARISH; + } + + // + result = dir != X_DIRECTION_NONE; + + // + return result; +} + +/** + * Detect all POIs which inside a Pivot ... + * + * @param pivot: XPVPivot instance, Specified Pivot ... + * @param source: XPOIState instance, Reference to Source State ... + * @param state: XPOIState instance, Reference to Detected Pivots ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + */ +void DetectPivotPOIs( + XPVPivot &pivot, + XPOIState &source, + XPOIState &state, + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // +) +{ + // + state.Clean(); + + // + if (!pivot.IsValid()) + { + return; + } + + // + int count = 0; + + // + state.symbol = pivot.symbol; + state.period = pivot.period; + state.time = TimeCurrent(); + + // + // Swings ... + + // + // Swing High ... + if (lookupSwingHighs) + { + // + count = ArraySize(source.swingHighs); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper; + if (isInside) + { + // + Add( + iSwing, + state.swingHighs // + ); + } + } + } + } + + // + // Swing Low ... + if (lookupSwingLows) + { + // + count = ArraySize(source.swingLows); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iSwing, + state.swingLows // + ); + } + } + } + } + + // + // Support and Resistance Zones ... + + // + // Support Zones ... + if (lookupSupportZones) + { + // + count = ArraySize(source.supportZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.supportZones // + ); + } + } + } + } + + // + // Resistance Zones ... + if (lookupResistanceZones) + { + // + count = ArraySize(source.resistanceZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.resistanceZones // + ); + } + } + } + } + + // + // Supply and Demand Zones ... + + // + // Supply Zones ... + if (lookupSupplyZones) + { + // + count = ArraySize(source.supplyZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.supplyZones // + ); + } + } + } + } + + // + // Demand Zones ... + if (lookupDemandZones) + { + // + count = ArraySize(source.demandZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.demandZones // + ); + } + } + } + } + + // + // Order Blocks ... + + // + // Bullish Order Blocks ... + if (lookupBullishOrderBlocks) + { + // + count = ArraySize(source.bullishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bullishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bullishOrderBlocks // + ); + } + } + } + } + + // + // Bearish Order Blocks ... + if (lookupBearishOrderBlocks) + { + // + count = ArraySize(source.bearishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bearishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bearishOrderBlocks // + ); + } + } + } + } + + // + // Fair Value Gaps ... + + // + // Bullish Fair Value Gaps ... + if (lookupBullishFairValueGaps) + { + // + count = ArraySize(source.bullishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bullishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bullishFairValueGaps // + ); + } + } + } + } + + // + // Bearish Fair Value Gaps ... + if (lookupBearishFairValueGaps) + { + // + count = ArraySize(source.bearishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bearishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bearishFairValueGaps // + ); + } + } + } + } + + // + // Rejection Bars ... + + // + // Bullish Rejection Bars ... + if (lookupBullishRejectionBars) + { + // + count = ArraySize(source.bullishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iRejection, + state.bullishRejectionBars // + ); + } + } + } + } + + // + // Bearish Rejection Bars ... + if (lookupBearishRejectionBars) + { + // + count = ArraySize(source.bearishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + Add( + iRejection, + state.bearishRejectionBars // + ); + } + } + } + } + + // + // Momentum Bars ... + + // + // Bullish Momentum Bars ... + if (lookupBullishMomentumBars) + { + // + count = ArraySize(source.bullishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iMomentum, + state.bullishMomentumBars // + ); + } + } + } + } + + // + // Bearish Momenum Bars ... + if (lookupBearishMomentumBars) + { + // + count = ArraySize(source.bearishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + Add( + iMomentum, + state.bearishMomentumBars // + ); + } + } + } + } +} + +// +// Provider Extensions ... + +/** + * Validate a Signal Provider ... + * + * @param value: ENUM_X_121_SMC_PROVIDERS member ... + * + * @return ( bool ) + */ +bool IsValid(ENUM_X_121_SMC_PROVIDERS value) +{ + // + bool result = false; + + // + result = value != X_121_SMC_PROVIDER_NONE; + + // + return result; +} + +/** + * Converts a Signal Provider to String ... + * + * @param value: ENUM_X_121_SMC_PROVIDERS member ... + * + * @return ( string ) + */ +string ToString(ENUM_X_121_SMC_PROVIDERS value) +{ + // + string result = NULL; + + // + if (!IsValid(value)) + { + return result; + } + + // + switch (value) + { + // + case X_121_SMC_PROVIDER_PV: + result = X121SMCPVToken; + break; + + // + case X_121_SMC_PROVIDER_BOS: + result = X121SMCBOSToken; + break; + + // + case X_121_SMC_PROVIDER_SAR: + result = X121SMCSARToken; + break; + + // + case X_121_SMC_PROVIDER_CHOCH: + result = X121SMCCHOCHToken; + break; + + // + case X_121_SMC_PROVIDER_PULLBK: + result = X121SMCPULLBKToken; + break; + } + + // + return result; +} + +/** + * Parse Specified String as a Signal Provider ... + * + * @param value: String ... + * + * @return ( ENUM_X_121_SMC_PROVIDERS ) + */ +ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) +{ + // + ENUM_X_121_SMC_PROVIDERS result = X_121_SMC_PROVIDER_NONE; + + // + if (!IsValid(value)) + { + return result; + } + + // + if (Contains(X121SMCPVToken, value)) + { + result = X_121_SMC_PROVIDER_PV; + } + else if (Contains(X121SMCBOSToken, value)) + { + result = X_121_SMC_PROVIDER_BOS; + } + else if (Contains(X121SMCSARToken, value)) + { + result = X_121_SMC_PROVIDER_SAR; + } + else if (Contains(X121SMCCHOCHToken, value)) + { + result = X_121_SMC_PROVIDER_CHOCH; + } + else if (Contains(X121SMCPULLBKToken, value)) + { + result = X_121_SMC_PROVIDER_PULLBK; + } + + // + return result; +} + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.test.strategy.FULL.class.mq5 b/Documents/BKP/x-121.smc.test.strategy.FULL.class.mq5 new file mode 100644 index 00000000..365ab16f --- /dev/null +++ b/Documents/BKP/x-121.smc.test.strategy.FULL.class.mq5 @@ -0,0 +1,2830 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XCX121SMCTestStrategy +// Description: provides all based classes for use ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... + +// +#include "../../Helpers/x-saherelm.x3ma.helper.mq5" +#include "../../Helpers/x-saherelm.x3vwap.helper.mq5" +#include "../../Helpers/x-saherelm.xchsar.helper.mq5" +#include "../../Helpers/x-saherelm.xpv.helper.mq5" +#include "../Classes/x-121.smc.base.strategy.class.mq5" + +// +// Definitions ... + +// +// XStrategy Class Implementation(s) ... +class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy +{ + // + // Public ... + public: + // + + // + // Constructor(s) ... + void XCX121SMCTestStrategy( + // + // Base ... + string _symbol, // Trading Symbol + ENUM_TIMEFRAMES _period // Trading TimeFrame + ) + : XCX121SMCBaseStrategy(_symbol, _period) + { + InitialHelpers(); + } + + // + // Deconstructur ... + void ~XCX121SMCTestStrategy() + { + } + + // + // Overrides Actions ... + + /** + * Destroy All Class Implementations ... + */ + void Destroy() override + { + // + delete xpvHelper; + delete x3maHelper; + delete xchsarHelper; + delete x3vwapHelper; + } + + /** + * Check Conditions For Signal ... + */ + bool HasSignal( + XSignal &signal, + X121SMCStrategyConditions &conditions // + ) override + { + // + bool result = false; + + // + signal.Clean(); + conditions.Clean(); + + // + int pushers = 0; + + // + double sl = 0; + double tp = 0; + double risk = 0; + double entry = 0; + double reward = 0; + double r2r = R2R(); + string provider = ""; + double volume = Volume(); + ENUM_POSITION_TYPE type = POSITION_TYPE_BUY; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + + // + bool hasLong = false; + bool hasShort = false; + + // + double selectedSL = 0; + + // + // Start Calculations ... + + // + string _symbol = GetSymbol(); + ENUM_TIMEFRAMES _period = GetPeriod(); + + // + double points = GetPoints(_symbol); + double pip = GetPipPrice(_symbol); + double pip2 = 2 * pip; + + // + datetime cTime = TimeCurrent(); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Retrieve Bars ... + + // + // Zero Bar ... + XOHCL zBar; + result = zBar.Init( + _symbol, + _period, + zIndex // + ); + if (!result) + { + return result; + } + + // + // Last Bar ... + XOHCL cBar; + result = cBar.Init( + _symbol, + _period, + cIndex // + ); + if (!result) + { + return result; + } + + // + // Previous Bar ... + XOHCL pBar; + result = pBar.Init( + _symbol, + _period, + pIndex // + ); + if (!result) + { + return result; + } + + // + // Prepare Areas ... + double bid = GetBid(_symbol); + + // + // Check Momentum Bar ... + ENUM_X_DIRECTION momentumCBarDir; + bool isCMomentumBar = mBarAnalyser.IsMomentumBar( + cBar, + momentumCBarDir // + ); + bool isCBullishMomentumBar = + isCMomentumBar && + IsBullish(momentumCBarDir); + bool isCBearishMomentumBar = + isCMomentumBar && + IsBearish(momentumCBarDir); + + // + // Check Momentum Bar ... + ENUM_X_DIRECTION momentumPBarDir; + bool isPMomentumBar = mBarAnalyser.IsMomentumBar( + pBar, + momentumPBarDir // + ); + bool isPBullishMomentumBar = + isPMomentumBar && + IsBullish(momentumPBarDir); + bool isPBearishMomentumBar = + isPMomentumBar && + IsBearish(momentumPBarDir); + + // + // Check Rejection Bar ... + ENUM_X_DIRECTION rejectionCBarDir; + bool isCRejectionBar = mBarAnalyser.IsRejectionBar( + cBar, + rejectionCBarDir // + ); + bool isCBullishRejectionBar = + isCRejectionBar && + IsBullish(rejectionCBarDir); + bool isCBearishRejectionBar = + isCRejectionBar && + IsBearish(rejectionCBarDir); + + // + // Check Rejection Bar ... + ENUM_X_DIRECTION rejectionPBarDir; + bool isPRejectionBar = mBarAnalyser.IsRejectionBar( + pBar, + rejectionPBarDir // + ); + bool isPBullishRejectionBar = + isPRejectionBar && + IsBullish(rejectionPBarDir); + bool isPBearishRejectionBar = + isPRejectionBar && + IsBearish(rejectionPBarDir); + + // + // Check Engulfing ... + ENUM_X_DIRECTION engulfCBarDir; + bool isCEngulfed = mBarAnalyser.IsEngulfBar( + cBar, + engulfCBarDir // + ); + bool isCBullishEngulfed = + isCEngulfed && + IsBullish(engulfCBarDir); + bool isCBearishEngulfed = + isCEngulfed && + IsBearish(engulfCBarDir); + + // + // Check Engulfing ... + ENUM_X_DIRECTION engulfPBarDir; + bool isPEngulfed = mBarAnalyser.IsEngulfBar( + pBar, + engulfPBarDir // + ); + bool isPBullishEngulfed = + isPEngulfed && + IsBullish(engulfPBarDir); + bool isPBearishEngulfed = + isPEngulfed && + IsBearish(engulfPBarDir); + + // + bool isCRMEBullish = + // + isCBullishEngulfed + // + || + // + isCBullishMomentumBar + // + || + // + isCBullishRejectionBar + // + ; + + // + bool isPRMEBullish = + // + isPBullishEngulfed + // + || + // + isPBullishMomentumBar + // + || + // + isPBullishRejectionBar + // + ; + + // + bool isCRMEBearish = + // + isCBearishEngulfed + // + || + // + isCBearishMomentumBar + // + || + // + isCBearishRejectionBar + // + ; + + // + bool isPRMEBearish = + // + isPBearishEngulfed + // + || + // + isPBearishMomentumBar + // + || + // + isPBearishRejectionBar + // + ; + + // + bool isSpreadPassed = IsSpreadPass(); + result = isSpreadPassed; + if (!result) + { + return result; + } + + // + // Try to Implement SMC Based Conditions ... + result = DetectConditions(conditions); + if (!result) + { + return result; + } + + // + // Validate Order Flow ... + bool isValidOrderFlow = HasValidOrderFlow(); + result = isValidOrderFlow; + if (!result) + { + return result; + } + + // + XPVPivot lastPivot; + result = GetLastItem( + lastPivot, + mOrderFlow // + ); + if (!result) + { + return result; + } + + // + // Detect Fair Value Gaps ... + XCBasePOI *mPOIs[]; + bool hasPOI = FindPOIInPivot( + mPOIs, + X_POI_SWING_HIGH, + lastPivot, + mVisionPOIState // + ); + // TODO: + + // + bool isOrderFlowBullish = IsBullish(mOrderFlowDir); + + // + // Check Parabolic Sar is in Order of Order Flow ... + bool isPSarInDirectionOfOrderFlow = + isOrderFlowBullish + ? conditions.xchsarConditions.cSars[0] < cBar.low && + conditions.xchsarConditions.cSars[1] >= pBar.low + : conditions.xchsarConditions.cSars[0] > cBar.high && + conditions.xchsarConditions.cSars[1] <= pBar.high; + + // + // Check BOS or CHOCH Happens ... + bool hasBOS = + isOrderFlowBullish + ? + // + // Price Close Over Pivot's High ... + cBar.IsBullish() && + cBar.close > lastPivot.upper && + (pBar.close < lastPivot.upper || + pBar.low < lastPivot.upper) + // + : + // + // Price Must Close Under Pivots Low ... + cBar.IsBearish() && + cBar.close < lastPivot.lower && + (pBar.close > lastPivot.lower || + pBar.high > lastPivot.lower) + // + ; + + // + if (hasBOS) + { + mLastBOSOn = TimeCurrent(); + } + + bool hasCHOCH = + isOrderFlowBullish + ? + // + // Price Close Under Pivot's Low ... + cBar.IsBearish() && + cBar.close < lastPivot.lower && + (pBar.close > lastPivot.lower || + pBar.high > lastPivot.lower) + // + : + // + // Price Must Close Over Pivots High ... + cBar.IsBullish() && + cBar.close > lastPivot.upper && + (pBar.close < lastPivot.upper || + pBar.low < lastPivot.upper) + // + ; + + // + // Check PSar is Equals to Peak or Vale ... + bool isSAREqualsToPeak = + conditions.xchsarConditions.cSars[0] == conditions.xpvConditions.peaks[1]; + bool isSAREqualsToVale = + conditions.xchsarConditions.cSars[0] == conditions.xpvConditions.vales[1]; + + // + bool hasNewPeak = + conditions.xpvConditions.peaks[0] != conditions.xpvConditions.peaks[1]; + bool hasNewPeakOverLast = + hasNewPeak && + conditions.xpvConditions.peaks[0] > conditions.xpvConditions.peaks[1]; + bool hasNewPeakUnderLast = + hasNewPeak && + conditions.xpvConditions.peaks[0] < conditions.xpvConditions.peaks[1]; + + // + bool hasNewVale = + conditions.xpvConditions.vales[0] != conditions.xpvConditions.vales[1]; + bool hasNewValeOverLast = + hasNewVale && + conditions.xpvConditions.vales[0] > conditions.xpvConditions.vales[1]; + bool hasNewValeUnderLast = + hasNewVale && + conditions.xpvConditions.vales[0] < conditions.xpvConditions.vales[1]; + + // + // START Signalling ... + // + + // + // BOS Signals ... + bool has_BOS_Long = false; + bool has_BOS_Short = false; + + // + // CHOCH Signals ... + bool has_CHOCH_Long = false; + bool has_CHOCH_Short = false; + + // + // SAR Signals ... + bool has_SAR_Long = false; + bool has_SAR_Short = false; + + // + // PULLBACK Signals ... + bool has_PULLBK_Long = false; + bool has_PULLBK_Short = false; + + // + // PV Signals ... + bool has_PV_Long = false; + bool has_PV_Short = false; + + // + // BOS Signals ... + // + has_BOS_Long = + // + hasBOS && + isOrderFlowBullish && + isCRMEBullish && + cBar.IsBullish() && + conditions.xchsarConditions.cSars[0] < cBar.low + // + ; + + // + if (has_BOS_Long) + { + // + selectedSL = cBar.low; + provider = ToString(X_121_SMC_PROVIDER_BOS); + } + + // + has_BOS_Short = + // + hasBOS && + !isOrderFlowBullish && + isCRMEBearish && + cBar.IsBearish() && + conditions.xchsarConditions.cSars[0] > cBar.high + // + ; + if (has_BOS_Short) + { + // + selectedSL = cBar.high; + provider = ToString(X_121_SMC_PROVIDER_BOS); + } + + // + // CHOCH Signals ... + + // + has_CHOCH_Long = + // + hasCHOCH && + isCRMEBullish && + cBar.IsBullish() && + !isOrderFlowBullish && + conditions.xchsarConditions.cSars[0] < cBar.low + // + ; + if (has_CHOCH_Long) + { + // + selectedSL = cBar.low; + provider = ToString(X_121_SMC_PROVIDER_CHOCH); + } + + // + has_CHOCH_Short = + // + hasCHOCH && + isCRMEBearish && + cBar.IsBearish() && + isOrderFlowBullish && + conditions.xchsarConditions.cSars[0] > cBar.high + // + ; + if (has_CHOCH_Short) + { + // + selectedSL = cBar.high; + provider = ToString(X_121_SMC_PROVIDER_CHOCH); + } + + // + // SAR Signals ... + + // + has_SAR_Long = + // + isSAREqualsToVale && + isOrderFlowBullish && + isPSarInDirectionOfOrderFlow + // + ; + if (has_SAR_Long) + { + // + provider = ToString(X_121_SMC_PROVIDER_SAR); + selectedSL = conditions.xchsarConditions.cSars[0]; + } + + // + has_SAR_Short = + // + isSAREqualsToPeak && + !isOrderFlowBullish && + isPSarInDirectionOfOrderFlow + // + ; + if (has_SAR_Short) + { + // + provider = ToString(X_121_SMC_PROVIDER_SAR); + selectedSL = conditions.xchsarConditions.cSars[0]; + } + + // + // PULLBK Signals ... + + // + has_PULLBK_Long = + // + isCRMEBullish && + isPSarInDirectionOfOrderFlow && + (cBar.low < conditions.x3maConditions.fasts[0] && + cBar.GetDown() > conditions.x3maConditions.fasts[0]) + // + ; + if (has_PULLBK_Long) + { + // + selectedSL = cBar.low; + provider = ToString(X_121_SMC_PROVIDER_PULLBK); + } + + // + has_PULLBK_Short = + // + isCRMEBearish && + isPSarInDirectionOfOrderFlow && + (cBar.high > conditions.x3maConditions.fasts[0] && + cBar.GetUp() < conditions.x3maConditions.fasts[0]) + // + ; + if (has_PULLBK_Short) + { + // + selectedSL = cBar.high; + provider = ToString(X_121_SMC_PROVIDER_PULLBK); + } + + // + // PV Signals ... + + // + has_PV_Long = + // + isCRMEBullish && + isOrderFlowBullish && + !hasNewValeUnderLast && + cBar.low == conditions.xpvConditions.vales[0] + // + ; + if (has_PV_Long) + { + // + selectedSL = cBar.low; + provider = ToString(X_121_SMC_PROVIDER_PV); + } + + // + has_PV_Short = + // + isCRMEBearish && + !isOrderFlowBullish && + !hasNewPeakOverLast && + cBar.high == conditions.xpvConditions.peaks[0] + // + ; + if (has_PV_Short) + { + // + selectedSL = cBar.high; + provider = ToString(X_121_SMC_PROVIDER_PV); + } + + // + // END Signalling ... + // + + // + // Combine all Signals Conditions ... + + // + hasLong = + // + has_BOS_Long + // + || + // + has_CHOCH_Long + // + || + // + has_SAR_Long + // + || + // + has_PULLBK_Long + // + || + // + has_PV_Long + // + ; + + // + hasShort = + // + has_BOS_Short + // + || + // + has_CHOCH_Short + // + || + // + has_SAR_Short + // + || + // + has_PULLBK_Short + // + || + // + has_PV_Short + // + ; + + // + result = hasLong || + hasShort; + + // + // Reset Order Flow ... + if (hasCHOCH && !result) + { + ResetOrderFlow(); + } + else if (hasBOS && !result) + { + UpdateOrderFlow(); + } + + // + // Rmove Signal Condition ... + if (result) + { + // + // TYPE ... + type = + hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_POSITION_TYPES xType = + hasLong + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + entry = GetEntry( + conditions.symbol, + type // + ); + + // + sl = + hasLong + ? selectedSL - pip2 + : selectedSL + pip2; + + // + // RISK Reward ... + risk = + hasLong + ? entry - sl + : sl - entry; + reward = risk * r2r; + tp = + hasLong + ? entry + reward + : entry - reward; + + // + signal.sl = sl; + signal.tp = tp; + signal.type = type; + signal.mode = mode; + signal.entry = entry; + signal.volume = volume; + signal.symbol = _symbol; + signal.period = _period; + signal.pushers = pushers; + signal.provider = provider; + signal.time = TimeCurrent(); + + // + result = PrepareSignal(signal); + if (result) + { + // + Print("PRV: ", provider); + + // + ENUM_X_DIRECTION forDir = ToDirection(signal.type); + bool ignoreSwingHighs = false; + bool ignoreSwingLows = false; + bool ignoreSupportZones = false; + bool ignoreResistanceZones = false; + bool ignoreSupplyZones = false; + bool ignoreDemandZones = false; + bool ignoreBullishOrderBlocks = false; + bool ignoreBearishOrderBlocks = false; + bool ignoreBullishFairValueGaps = false; + bool ignoreBearishFairValueGaps = false; + bool ignoreBullishRejectionBars = false; + bool ignoreBearishRejectionBars = false; + bool ignoreBullishMomentumBars = false; + bool ignoreBearishMomentumBars = false; + if (IsBullish(forDir)) + { + // + ignoreSwingLows = false; + ignoreDemandZones = false; + ignoreSupportZones = false; + ignoreBullishOrderBlocks = false; + ignoreBullishFairValueGaps = false; + ignoreBullishRejectionBars = false; + ignoreBullishMomentumBars = false; + } + else + { + // + ignoreSwingHighs = true; + ignoreSupplyZones = true; + ignoreResistanceZones = true; + ignoreBearishOrderBlocks = true; + ignoreBearishFairValueGaps = false; + ignoreBearishRejectionBars = true; + ignoreBearishMomentumBars = true; + } + + // + RedrawOrderFlow( + true, // Force Clean ... + false, // Same Period ... + true, // Order Flow ... + true, // Order Flow State ... + false, // Only Last Order Flow ... + true, // Only Last Order Flow State ... + // + forDir, // Direction Force ... + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars, + // + false, // Vision State ... + false, // Analyse State ... + false // Trigger State ... + ); + DrawSignal(signal); + ClearDraws(); + + // + ResetOrderFlow(); + } + + // + hasLong = false; + hasShort = false; + } + + // + return result; + } + + /** + * Customize Strategy Identifier ... + */ + string GetTag() override + { + return X121SMCStrategyToken; + } + + // + // Protected ... + protected: + // + + // + // Props ... + + // + // XPV ... + XPVInputs xpvInputs; + XCXPVHelper *xpvHelper; + + // + // X3MA ... + X3MAInputs x3maInputs; + XCX3MAHelper *x3maHelper; + + // + // X3VWAP ... + X3VWAPInputs x3vwapInputs; + XCX3VWAPHelper *x3vwapHelper; + + // + // XCHSAR ... + XCHSARInputs xchsarInputs; + XCXCHSARHelper *xchsarHelper; + + // + XPVPivot mOrderFlow[]; + ENUM_X_DIRECTION mOrderFlowDir; + + // + // Holds Last CHOCH and BOS time ... + datetime mLastBOSOn; + datetime mLastCHOCHOn; + + // + // Actions ... + + /** + * Detect and Parse Market Conditions ... + * + * @return ( bool ) + */ + bool DetectConditions( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + conditions.symbol = symbol; + conditions.period = period; + conditions.time = TimeCurrent(); + + // + int conditionsLoopback = 7; + + // + // XPV ... + result = xpvHelper.GetConditions( + conditions.xpvConditions, + cIndex, + conditionsLoopback // + ); + if (!result) + { + return result; + } + + // + // X3MA ... + result = x3maHelper.GetConditions( + conditions.x3maConditions, + cIndex, + conditionsLoopback // + ); + if (!result) + { + return result; + } + + // + // X3VWAP ... + result = x3vwapHelper.GetConditions( + conditions.x3vwapConditions, + cIndex, + conditionsLoopback // + ); + if (!result) + { + return result; + } + + // + // XCHSAR ... + result = xchsarHelper.GetConditions( + conditions.xchsarConditions, + cIndex, + conditionsLoopback // + ); + if (!result) + { + return result; + } + + // + // Only Detect Order Flow when there isn't ... + if (ArraySize(mOrderFlow) == 0 || + mOrderFlowDir == X_DIRECTION_NONE) + { + // + int samePivots = 40; + int requiredPivots = 10; + + // + DetectOrderFlow( + cIndex, + samePivots, + requiredPivots, + mOrderFlow, + mOrderFlowDir // + ); + + // + result = IsValidSize(ArraySize(mOrderFlow)); + if (!result) + { + return result; + } + } + + // + if (result) + { + // + int lastPivotIDX = ArraySize(mOrderFlow) - 1; + if (IsValidSize(lastPivotIDX)) + { + // + FillPivotSate( + lastPivotIDX, + true, // Use Vision State ... + true, // Use Analyse State ... + false // Use Trigger State ... + ); + } + } + + // + return result; + } + + /** + * Detect XPV Based POI(s) ... + * + * @param barIndex: Start Bar Index ... + * @param minRepetition: minimum Repeate of POI for Validation ... + * @param requiredPivots: Number of Min Requirement POI(s) ... + * @param orderFlow: XPVPivot instance Array Reference ... + * @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ... + * @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ... + * + * @return ( bool ) + */ + bool DetectOrderFlow( + int barIndex, + int minRepetition, + int requiredPivots, + XPVPivot &orderFlow[], // OrderFlows ... + ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ... + int maxAllowedLoopbackBars = 576 // + ) + { + // + bool result = false; + + // + orderFlowDirection = X_DIRECTION_NONE; + + // + if (maxAllowedLoopbackBars <= 0) + { + maxAllowedLoopbackBars = 1000; + } + + // + int start = barIndex; + int end = start + maxAllowedLoopbackBars; + + // + Clean(orderFlow); + + // + result = minRepetition > 0 && + requiredPivots > 0; + if (!result) + { + return result; + } + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + double peak = 0; + XPVPivot peaks[]; + int peakRepeate = 0; + int peakToBarIndex = 0; + int peakFromBarIndex = 0; + + // + double vale = 0; + XPVPivot vales[]; + int valeRepeate = 0; + int valeToBarIndex = 0; + int valeFromBarIndex = 0; + + // + bool canLookupPeak = true; + bool canLookupVale = true; + bool canLookup = true; + while (canLookup) + { + // + // Check Peak ... + double iPeak = xpvHelper.GetPeak(barIndex); + if (iPeak != peak) + { + // + if (peak != 0 && + peakRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(peaks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = peaks[i]; + + // + if (iPivot.upper == iPeak) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.lower = 0; + iPivot.upper = peak; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_PEAK; + iPivot.repetition = peakRepeate; + iPivot.to = iTime( + symbol, + period, + peakToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + peakFromBarIndex // + ); + + // + iPivot.lower = iPivot.CalculateLower(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + peaks // + ); + } + } + } + + // + peak = iPeak; + peakRepeate = 0; + peakFromBarIndex = 0; + peakToBarIndex = barIndex; + } + else if (iPeak == peak) + { + // + peakRepeate++; + peakFromBarIndex = barIndex; + } + + // + // Check Vale ... + double iVale = xpvHelper.GetVale(barIndex); + if (iVale != vale) + { + // + if (vale != 0 && + valeRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(vales); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = vales[i]; + + // + if (iPivot.lower == iVale) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.upper = 0; + iPivot.lower = vale; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_VALE; + iPivot.repetition = valeRepeate; + iPivot.to = iTime( + symbol, + period, + valeToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + valeFromBarIndex // + ); + + // + iPivot.upper = iPivot.CalculateUpper(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + vales // + ); + } + } + } + + // + vale = iVale; + valeRepeate = 0; + valeFromBarIndex = 0; + valeToBarIndex = barIndex; + } + else if (iVale == vale) + { + // + valeRepeate++; + valeFromBarIndex = barIndex; + } + + // + canLookupPeak = ArraySize(peaks) < requiredPivots; + canLookupVale = ArraySize(vales) < requiredPivots; + canLookup = barIndex < end && + (canLookupPeak || + canLookupVale); + if (canLookup) + { + barIndex++; + } + } + + // + result = IsValidSize(ArraySize(peaks)) || + IsValidSize(ArraySize(vales)); + if (!result) + { + return result; + } + + // + // Detect Order Flow ... + Copy( + peaks, + orderFlow, + false // + ); + Copy( + vales, + orderFlow, + false // + ); + int count = ArraySize(orderFlow); + result = IsValidSize(orderFlow); + if (!result) + { + return result; + } + + // + // Sort Pivots ... + SortPivots(orderFlow); + + // + // Filter Broken Order Flows ... + FilterBrokenPivots(orderFlow); + + // + // Detect Order Flow Direction ... + result = DetectPivotDirection( + orderFlow, + orderFlowDirection // + ); + if (!result) + { + return result; + } + + // + // Find State Inside Pivots and Attached Them to Pivot ... + int orderFlowCount = ArraySize(mOrderFlow); + if (IsValidSize(orderFlowCount)) + { + // + // Loop Through Order Flow ... + for (int i = 0; i < orderFlowCount; i++) + { + // + FillPivotSate( + i, + true, // Use Vision State ... + true, // Use Analyse State ... + false // Use Trigger State ... + ); + } + } + + // + return result; + } + + /** + * Filling Specified Orer Flow Index ... + * + * @param pivotIDX: Integer ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + */ + void FillPivotSate( + int pivotIDX, // + bool useVisionState = true, // Use Vision State ... + bool useAnalyseState = true, // Use Analyse State ... + bool useTriggerState = true, // Use Trigger State ... + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // + ) + { + // + CalculatePivotTickZone(pivotIDX); + + // + // Trigger ... + XPOIState mTriggerState; + if (useTriggerState && + mTriggerPOIState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mTriggerPOIState, + mTriggerState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mTriggerState.HasChild()) + { + mTriggerState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Analyse ... + XPOIState mAnalyseState; + if (useAnalyseState && + mAnalysePOIState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mAnalysePOIState, + mAnalyseState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mAnalyseState.HasChild()) + { + mAnalyseState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Vision ... + XPOIState mVisionState; + if (useVisionState && + mVisionPOIState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mVisionPOIState, + mVisionState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mVisionState.HasChild()) + { + mVisionState.Fill(mOrderFlow[pivotIDX].state); + } + } + } + + /** + * When a BOS Happens ... + * we have to Update Order Flow ... + */ + void UpdateOrderFlow() + { + ResetOrderFlow(); + } + + /** + * Fill Pivot Tick Zone ... + * + * @param pivotIDX: Integer ... + */ + void CalculatePivotTickZone(int pivotIDX) + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + bool isInited = false; + + // + datetime from = mOrderFlow[pivotIDX].from; + XOHCL iFromBar; + int iFromBarIndex = iBarShift( + symbol, + period, + from // + ); + isInited = iFromBar.Init( + symbol, + period, + iFromBarIndex // + ); + if (!isInited) + { + return; + } + + // + datetime to = mOrderFlow[pivotIDX].to; + XOHCL iToBar; + int iToBarIndex = iBarShift( + symbol, + period, + to // + ); + isInited = iToBar.Init( + symbol, + period, + iToBarIndex // + ); + if (!isInited) + { + return; + } + + // + XCTicksZone *iZone; + iZone = new XCTicksZone(); + + // + int ticksLevels = mTriggerPOIDetector.TicksRangeZoneLevel(); + int ticksRange = mTriggerPOIDetector.TicksRangeZoneRange(); + isInited = ticksLevels > 0 && + ticksRange > 0; + if (!isInited) + { + return; + } + + // + isInited = iZone.Init( + iFromBar, + iToBar // + ); + if (!isInited) + { + return; + } + + // + mOrderFlow[pivotIDX].state.ticksZone = iZone; + } + + /** + * Validate Order Flow ... + * + * @return ( bool ) + */ + bool HasValidOrderFlow() + { + // + bool result = false; + + // + int orderFlowCount = ArraySize(mOrderFlow); + result = + IsValidSize(orderFlowCount) && + mOrderFlowDir != X_DIRECTION_ALL && + mOrderFlowDir != X_DIRECTION_NONE; + + // + return result; + } + + /** + * Reset Order Flow ... + */ + void ResetOrderFlow() + { + // + Clean(mOrderFlow); + mOrderFlowDir = X_DIRECTION_NONE; + + // + ClearDraws(); + } + + bool FindPOIInPivot( + XCBasePOI *&pois[], + ENUM_XPOIS type, + XPVPivot &pivot, + XPOIState &state, + ENUM_X_DIRECTION dir = X_DIRECTION_NONE // + ) + { + // + bool result = false; + + // + Clean(pois); + + // + // Validate Inputs ... + result = + // + type != X_POI_NONE && + pivot.IsValid() && + state.IsValid() && + state.HasChild() + // + ; + if (!result) + { + return result; + } + + // + int swingHighsCunt = state.CountSwingHighs(); + int swingLowsCunt = state.CountSwingLows(); + int bullishMomentumBarsCunt = state.CountBullishMomentumBars(); + int bearishMomentumBarsCunt = state.CountBearishMomentumBars(); + int bullishRejectionBarsCunt = state.CountBullishRejectionBars(); + int bearishRejectionBarsCunt = state.CountBearishRejectionBars(); + int supportZonesCunt = state.CountSupportZones(); + int resistanceZonesCunt = state.CountResistanceZones(); + int supplyZonesCunt = state.CountSupplyZones(); + int demandZonesCunt = state.CountDemandZones(); + int bullishOrderBlocksCunt = state.CountBullishOrderBlocks(); + int bearishOrderBlocksCunt = state.CountBearishOrderBlocks(); + int bullishFairValueGapsCunt = state.CountBullishFairValueGaps(); + int bearishFairValueGapsCunt = state.CountBearishFairValueGaps(); + + // + switch (type) + { + // + case X_POI_MOMENTUM_BAR: { + // + // Validate Direction ... + result = HasDirection(dir); + if (!result) + { + return result; + } + + // + bool isBullishDir = IsBullish(dir); + + // + // Validate State POI(s) ... + result = + isBullishDir + ? IsValidSize(bullishMomentumBarsCunt) + : IsValidSize(bearishMomentumBarsCunt); + if (!result) + { + break; + } + + // + if (isBullishDir) + { + // + for (int i = 0; i < bullishMomentumBarsCunt; i++) + { + // + } + } + else + { + // + for (int i = 0; i < bullishMomentumBarsCunt; i++) + { + // + } + } + + // + break; + }; + + // + case X_POI_REJECTION_BAR: { + // + // Validate Direction ... + result = HasDirection(dir); + if (!result) + { + return result; + } + + // + bool isBullishDir = IsBullish(dir); + + // + // Validate State POI(s) ... + result = + isBullishDir + ? IsValidSize(bullishMomentumBarsCunt) + : IsValidSize(bearishMomentumBarsCunt); + if (!result) + { + break; + } + + // + if (isBullishDir) + { + // + for (int i = 0; i < bullishMomentumBarsCunt; i++) + { + // + } + } + else + { + // + for (int i = 0; i < bullishMomentumBarsCunt; i++) + { + // + } + } + + // + break; + }; + + // + case X_POI_SWING_HIGH: + break; + + // + case X_POI_SWING_LOW: + break; + + // + case X_POI_SUPPORT_ZONE: + break; + + // + case X_POI_RESISTANCE_ZONE: + break; + + // + case X_POI_SUPPLY_ZONE: + break; + + // + case X_POI_DEMAND_ZONE: + break; + + // + case X_POI_BULLISH_ORDERBLOCK: + break; + + // + case X_POI_BEARISH_ORDERBLOCK: + break; + + // + case X_POI_BULLISH_FVG: + break; + + // + case X_POI_BEARISH_FVG: + break; + } + + // + return result; + } + + // + // Drawings ... + + /** + * Draw Order Flow ... + */ + void + RedrawOrderFlow( + bool forceClearDraws = true, + bool forceDrawSamePeriod = true, + bool drawOrderFlow = true, + bool drawOrderFlowState = true, + bool drawOnlyLastOrderFlow = false, + bool drawOnlyLastOrderFlowState = true, + // + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + // + // Ignores List ... + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false, + // + // States Drawing ... + bool drawVisionState = false, + bool drawAnalyseState = false, + bool drawTriggerState = false // + ) + { + // + if (forceClearDraws) + { + ClearDraws(); + } + + // + if (!drawOrderFlow || + !HasValidOrderFlow()) + { + return; + } + + // + int orderFlowCount = ArraySize(mOrderFlow); + for (int i = 0; i < orderFlowCount; i++) + { + // + bool isLast = i == orderFlowCount - 1; + bool canDraw = + !drawOnlyLastOrderFlow || + (isLast && + drawOnlyLastOrderFlow); + if (!canDraw) + { + continue; + } + + // + XPVPivot iPivot = mOrderFlow[i]; + + // + XCXPVPivotObject *iObj; + iObj = new XCXPVPivotObject(); + bool isCreated = iObj.Create( + mPOIDrawer.ChartIdentification(), + mPOIDrawer.SubWindowIdentification(), + iPivot // + ); + if (isCreated) + { + // + bool canDrawState = + drawOrderFlowState && + (!drawOnlyLastOrderFlowState || + (isLast && + drawOnlyLastOrderFlowState)); + if (canDrawState) + { + // + CustomStateDrawing( + iPivot.state, + forceDrawSamePeriod, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + if (iPivot.IsPeak()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotColor(clrAqua); + iObj.PivotStyle(STYLE_SOLID); + } + + // + if (iPivot.IsVale()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotStyle(STYLE_SOLID); + iObj.PivotColor(clrMagenta); + } + + // + AddObjectIfNotExists(iObj); + } + } + + // + // Vision ... + if (drawVisionState) + { + // + CustomStateDrawing( + mTriggerPOIState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Analyse ... + if (drawAnalyseState) + { + // + CustomStateDrawing( + mAnalysePOIState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Trigger ... + if (drawTriggerState) + { + // + CustomStateDrawing( + mVisionPOIState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + } + + /** + * Custom Drawing State ... + * + * @param state: XPOIState instance reference, Specified Which state to Draw ... + * @param forceDrawSamePeriod: Boolean ... + */ + void CustomStateDrawing( + XPOIState &state, + bool forceDrawSamePeriod = false, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + // + // Ignores List ... + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // + ) + { + // + XPOIState tmpState = state; + if (forceDrawSamePeriod) + { + // + int count = 0; + ENUM_TIMEFRAMES period = GetPeriod(); + + // + count = state.CountSwingHighs(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingHighs, + i, + 1 // + ); + } + } + } + + // + count = state.CountSwingLows(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingLows, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone iZone = state.supportZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supportZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone iZone = state.resistanceZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.resistanceZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone iZone = state.supplyZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supplyZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone iZone = state.demandZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.demandZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bullishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bearishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bullishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bearishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + } + + // + bool drawSwingHighs = true; + bool drawSwingLows = true; + bool drawSupportZones = true; + bool drawResistanceZones = true; + bool drawSupplyZones = true; + bool drawDemandZones = true; + bool drawBullishOrderBlocks = true; + bool drawBearishOrderBlocks = true; + bool drawBullishFairValueGaps = true; + bool drawBearishFairValueGaps = true; + bool drawBullishRejectionBars = true; + bool drawBearishRejectionBars = true; + bool drawBullishMomentumBars = true; + bool drawBearishMomentumBars = true; + + // + // Change Drawing Specs Conditions based on + // Provided Direction ... + if (forDir == X_DIRECTION_BULLISH) + { + // + drawSwingLows = true; + drawDemandZones = true; + drawSupportZones = true; + drawBullishOrderBlocks = true; + drawBullishFairValueGaps = true; + drawBullishRejectionBars = true; + drawBullishMomentumBars = true; + + // + drawSwingHighs = false; + drawSupplyZones = false; + drawResistanceZones = false; + drawBearishOrderBlocks = false; + drawBearishFairValueGaps = false; + drawBearishRejectionBars = false; + drawBearishMomentumBars = false; + } + else if (forDir == X_DIRECTION_BEARISH) + { + // + drawSwingLows = false; + drawDemandZones = false; + drawSupportZones = false; + drawBullishOrderBlocks = false; + drawBullishFairValueGaps = false; + drawBullishRejectionBars = false; + drawBullishMomentumBars = false; + + // + drawSwingHighs = true; + drawSupplyZones = true; + drawResistanceZones = true; + drawBearishOrderBlocks = true; + drawBearishFairValueGaps = true; + drawBearishRejectionBars = true; + drawBearishMomentumBars = true; + } + + // + // Apply Ignore List ... + + // + if (ignoreSwingHighs) + { + drawSwingHighs = false; + } + + // + if (ignoreSwingLows) + { + drawSwingLows = false; + } + + // + if (ignoreSupportZones) + { + drawSupportZones = false; + } + + // + if (ignoreResistanceZones) + { + drawResistanceZones = false; + } + + // + if (ignoreSupplyZones) + { + drawSupplyZones = false; + } + + // + if (ignoreDemandZones) + { + drawDemandZones = false; + } + + // + if (ignoreBullishOrderBlocks) + { + drawBullishOrderBlocks = false; + } + + // + if (ignoreBearishOrderBlocks) + { + drawBearishOrderBlocks = false; + } + + // + if (ignoreBullishFairValueGaps) + { + drawBullishFairValueGaps = false; + } + + // + if (ignoreBearishFairValueGaps) + { + drawBearishFairValueGaps = false; + } + + // + if (ignoreBullishRejectionBars) + { + drawBullishRejectionBars = false; + } + + // + if (ignoreBearishRejectionBars) + { + drawBearishRejectionBars = false; + } + + // + if (ignoreBullishMomentumBars) + { + drawBullishMomentumBars = false; + } + + // + if (ignoreBearishMomentumBars) + { + drawBearishMomentumBars = false; + } + + // + DrawState( + tmpState, // State ... + true, // Update To of all Drawings Till now ... + drawSwingHighs, // Draw SwingHighs .. + drawSwingLows, // Draw SwingLows .. + drawSupportZones, // Draw SupportZones .. + drawResistanceZones, // Draw ResistanceZones .. + drawSupplyZones, // Draw SupplyZones .. + drawDemandZones, // Draw DemandZones .. + drawBullishOrderBlocks, // Draw BullishOrderBlocks .. + drawBearishOrderBlocks, // Draw BearishOrderBlocks .. + drawBullishFairValueGaps, // Draw BullishFairValueGaps .. + drawBearishFairValueGaps, // Draw BearishFairValueGaps .. + drawBullishRejectionBars, // Draw BullishRejectionBars .. + drawBearishRejectionBars, // Draw BearishRejectionBars .. + drawBullishMomentumBars, // Draw BullishMomentumBars .. + drawBearishMomentumBars, // Draw BearishMomentumBars .. + true // Draw Ticks Zone ... + ); + } + + // + // Private ... + private: + // + // Props ... + + /** + * Initial Required Indicators Helper ... + */ + void InitialHelpers() + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + // Short ... + ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + + // + // Medium ... + ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + + // + // Long ... + ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + + // + // Hind ... + ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + + // + // XPV ... + + // + xpvInputs.Default(); + + // + xpvInputs.scMethod = scMethod; + xpvInputs.scPeriod = scPeriod; + xpvInputs.mcMethod = mcMethod; + xpvInputs.mcPeriod = mcPeriod; + xpvInputs.lcMethod = lcMethod; + xpvInputs.lcPeriod = lcPeriod; + xpvInputs.hcMethod = hcMethod; + xpvInputs.hcPeriod = hcPeriod; + + // + xpvInputs.showPeaksAndVales = true; + xpvInputs.showLevels = false; + xpvInputs.showConsolidations = false; + xpvInputs.showFibo1Levels = false; + xpvInputs.showFibo2Levels = false; + xpvInputs.showFibo3Levels = false; + xpvInputs.showFibo4Levels = false; + xpvInputs.showFibo5Levels = false; + + // + xpvHelper = new XCXPVHelper(); + xpvHelper.Init( + symbol, + period, + xpvInputs // + ); + + // + // X3MA ... + + // + x3maInputs.Default(); + + // + x3maInputs.showFast = true; + x3maInputs.showMid = false; + x3maInputs.showSlow = false; + + // + x3maHelper = new XCX3MAHelper(); + x3maHelper.Init( + symbol, + period, + x3maInputs // + ); + + // + // X3VWAP ... + + // + x3vwapInputs.Default(); + + // + x3vwapInputs.showFast = true; + x3vwapInputs.showMid = true; + x3vwapInputs.showSlow = true; + + // + x3vwapHelper = new XCX3VWAPHelper(); + x3vwapHelper.Init( + symbol, + period, + x3vwapInputs // + ); + + // + // XCHCHSAR ... + + // + xchsarInputs.Default(); + + // + xchsarInputs.scMethod = scMethod; + xchsarInputs.scPeriod = scPeriod; + xchsarInputs.mcMethod = mcMethod; + xchsarInputs.mcPeriod = mcPeriod; + xchsarInputs.lcMethod = lcMethod; + xchsarInputs.lcPeriod = lcPeriod; + xchsarInputs.hcMethod = hcMethod; + xchsarInputs.hcPeriod = hcPeriod; + + // + xchsarInputs.showCurrent = true; + xchsarInputs.showShort = false; + xchsarInputs.showMedium = false; + xchsarInputs.showLong = false; + xchsarInputs.showHind = false; + + // + xchsarHelper = new XCXCHSARHelper(); + xchsarHelper.Init( + symbol, + period, + xchsarInputs // + ); + } + + // +}; + +// \ No newline at end of file diff --git a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 index 184ee21e..ec2cf845 100644 --- a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 @@ -369,21 +369,39 @@ class XCX121SMCBaseStrategy : public XCBaseAlert // // Trigger ... - ENUM_XPOI_EVENTS triggerPOIEvents[]; - mTriggerPOIDetector.Update(triggerPOIEvents); - mTriggerPOIDetector.GetState(mTriggerPOIState); + ENUM_XPOI_EVENTS mTriggerEvents[]; + mTriggerDetector.Update(mTriggerEvents); + mTriggerDetector.GetState(mTriggerState); + + // + // Decision ... + ENUM_XPOI_EVENTS mDecisionEvents[]; + mDecisionDetector.Update(mDecisionEvents); + mDecisionDetector.GetState(mDecisionState); // // Analyse ... - ENUM_XPOI_EVENTS analysePOIEvents[]; - mAnalysePOIDetector.Update(analysePOIEvents); - mAnalysePOIDetector.GetState(mAnalysePOIState); + ENUM_XPOI_EVENTS mAnalyseEvents[]; + mAnalyseDetector.Update(mAnalyseEvents); + mAnalyseDetector.GetState(mAnalyseState); // - // Trigger ... - ENUM_XPOI_EVENTS visionPOIEvents[]; - mVisionPOIDetector.Update(visionPOIEvents); - mVisionPOIDetector.GetState(mVisionPOIState); + // Verification ... + ENUM_XPOI_EVENTS mVerificationEvents[]; + mVerificationDetector.Update(mVerificationEvents); + mVerificationDetector.GetState(mVerificationState); + + // + // Consolidation ... + ENUM_XPOI_EVENTS mConsolidationEvents[]; + mConsolidationDetector.Update(mConsolidationEvents); + mConsolidationDetector.GetState(mConsolidationState); + + // + // Vision ... + ENUM_XPOI_EVENTS mVisionEvents[]; + mVisionDetector.Update(mVisionEvents); + mVisionDetector.GetState(mVisionState); // // Check Current Processing Tick has Signal or not ... @@ -474,14 +492,20 @@ class XCX121SMCBaseStrategy : public XCBaseAlert // // Point Of Interests ... - XCPOIDetector *mTriggerPOIDetector; - XCPOIDetector *mAnalysePOIDetector; - XCPOIDetector *mVisionPOIDetector; + XCPOIDetector *mVisionDetector; + XCPOIDetector *mConsolidationDetector; + XCPOIDetector *mVerificationDetector; + XCPOIDetector *mAnalyseDetector; + XCPOIDetector *mDecisionDetector; + XCPOIDetector *mTriggerDetector; // - XPOIState mTriggerPOIState; - XPOIState mAnalysePOIState; - XPOIState mVisionPOIState; + XPOIState mVisionState; + XPOIState mConsolidationState; + XPOIState mVerificationState; + XPOIState mAnalyseState; + XPOIState mDecisionState; + XPOIState mTriggerState; // XCPOIDrawer *mPOIDrawer; // POI Drawer Class ... @@ -1522,32 +1546,58 @@ class XCX121SMCBaseStrategy : public XCBaseAlert // // Trigger ... - mTriggerPOIDetector = new XCPOIDetector( + mTriggerDetector = new XCPOIDetector( symbol, - period // + PERIOD_M1 // ); - mTriggerPOIDetector.MaxNumberOfRequiredPOIs(poiRequired); - mTriggerPOIDetector.Init(); + mTriggerDetector.MaxNumberOfRequiredPOIs(poiRequired); + mTriggerDetector.Init(); + + // + // Decision ... + mDecisionDetector = new XCPOIDetector( + symbol, + PERIOD_M5 // + ); + mDecisionDetector.MaxNumberOfRequiredPOIs(poiRequired); + mDecisionDetector.Init(); // // Analyse ... - ENUM_TIMEFRAMES analysePeriod = GetAnalysePeriod(period); - mAnalysePOIDetector = new XCPOIDetector( + mAnalyseDetector = new XCPOIDetector( symbol, - analysePeriod // + PERIOD_M15 // ); - mAnalysePOIDetector.MaxNumberOfRequiredPOIs(poiRequired); - mAnalysePOIDetector.Init(); + mAnalyseDetector.MaxNumberOfRequiredPOIs(poiRequired); + mAnalyseDetector.Init(); + + // + // Verification ... + mVerificationDetector = new XCPOIDetector( + symbol, + PERIOD_M30 // + ); + mVerificationDetector.MaxNumberOfRequiredPOIs(poiRequired); + mVerificationDetector.Init(); + + // + // Consolidation ... + mConsolidationDetector = new XCPOIDetector( + symbol, + PERIOD_H1 // + ); + mConsolidationDetector.MaxNumberOfRequiredPOIs(poiRequired); + mConsolidationDetector.Init(); // // Vision ... - ENUM_TIMEFRAMES visionPeriod = GetVisionPeriod(period); - mVisionPOIDetector = new XCPOIDetector( + mVisionDetector = new XCPOIDetector( symbol, - visionPeriod // + PERIOD_H4 // ); - mVisionPOIDetector.MaxNumberOfRequiredPOIs(poiRequired); - mVisionPOIDetector.Init(); + mVisionDetector.MaxNumberOfRequiredPOIs(poiRequired); + mVisionDetector.Init(); + // } @@ -1558,9 +1608,12 @@ class XCX121SMCBaseStrategy : public XCBaseAlert void DeInit() { // - delete mTriggerPOIDetector; - delete mAnalysePOIDetector; - delete mVisionPOIDetector; + delete mVisionDetector; + delete mConsolidationDetector; + delete mVerificationDetector; + delete mAnalyseDetector; + delete mDecisionDetector; + delete mTriggerDetector; // delete mPOIDrawer; diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 new file mode 100644 index 00000000..2b817acd --- /dev/null +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -0,0 +1,468 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XC121SMCCycleHelper +// Description: provides all based classes for use ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... + +// +// Implementations ... + +class XC121SMCCycleHelper : public XCBase +{ + // + public: + // + // Props ... + + // + // XPV ... + XCXPVHelper *mXPVHelper; + + // + // X3MA ... + XCX3MAHelper *mX3MAHelper; + + // + // X3VWAP ... + XCX3VWAPHelper *mX3VWAPHelper; + + // + // XCHSAR ... + XCXCHSARHelper *mXCHSARHelper; + + // + // Constructor(s) ... + XC121SMCCycleHelper() + { + } + + // + // Deconstructor ... + ~XC121SMCCycleHelper() + { + DeInit(); + } + + // + // Getter/Setter(s) ... + + // + // Actions ... + + /** + * Initialize ... + * + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... + * @param xpvInputs: XPVInputs instance ... + * @param x3maInputs: X3MAInputs instance ... + * @param x3vwapInputs: X3VWAPInputs instance ... + * @param xchsarInputs: XCHSARInputs instance ... + * + * @return ( bool ) + */ + bool Init( + string symbol, + ENUM_TIMEFRAMES period, + XPVInputs &xpvInputs, + X3MAInputs &x3maInputs, + X3VWAPInputs &x3vwapInputs, + XCHSARInputs &xchsarInputs // + ) + { + // + bool result = false; + + // + result = IsValid(symbol) && + IsValid(period); + if (!result) + { + return result; + } + + // + // XPV ... + + // + result = xpvInputs.IsValid(); + if (!result) + { + return result; + } + + // + mXPVHelper = new XCXPVHelper(); + result = mXPVHelper.Init( + symbol, + period, + xpvInputs // + ); + if (!result) + { + return result; + } + + // + // X3MA ... + + // + result = x3maInputs.IsValid(); + if (!result) + { + return result; + } + + // + mX3MAHelper = new XCX3MAHelper(); + result = mX3MAHelper.Init( + symbol, + period, + x3maInputs // + ); + if (!result) + { + return result; + } + + // + // X3VWAP ... + + // + result = x3vwapInputs.IsValid(); + if (!result) + { + return result; + } + + // + mX3VWAPHelper = new XCX3VWAPHelper(); + result = mX3VWAPHelper.Init( + symbol, + period, + x3vwapInputs // + ); + if (!result) + { + return result; + } + + // + // XCHSAR ... + + // + result = xchsarInputs.IsValid(); + if (!result) + { + return result; + } + + // + mXCHSARHelper = new XCXCHSARHelper(); + result = mXCHSARHelper.Init( + symbol, + period, + xchsarInputs // + ); + if (!result) + { + return result; + } + + // + // Set Chart Style ... + ApplyChartStyle(); + + // + return result; + } + + /** + * Retrieve Cycle Conditions ... + * + * @param conditions: X121SMCCycleConditions instance ... + * @param barIndex: Integer ... + * @param loopback: Integer ... + * + * @return ( bool ) + */ + bool GetConditions( + X121SMCCycleConditions &conditions, + int barIndex = 0, + int loopback = 7 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + result = mXPVHelper.GetConditions( + conditions.xpvConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + result = mX3MAHelper.GetConditions( + conditions.x3maConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + result = mX3VWAPHelper.GetConditions( + conditions.x3vwapConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + result = mXCHSARHelper.GetConditions( + conditions.xchsarConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + conditions.symbol = conditions.xpvConditions.symbol; + conditions.period = conditions.xpvConditions.period; + conditions.time = TimeCurrent(); + + // + result = conditions.IsValid(); + + // + return result; + } + + // + // POI Tools ... + + /** + * Detect Nearest Current SAR Change ... + * + * @param changeBar: XOHCL instance, Holds Nearest Change Bar ... + * @param bar: XOHCL instance, represents Current Bar for Loopback ... + * + * @return ( bool ) + */ + bool DetectNearestCSARChange( + XOHCL &changeBar, + XOHCL &bar // + ) + { + // + bool result = false; + + // + changeBar.Clean(); + + // + result = + bar.IsValid(); + if (!result) + { + return result; + } + + // + int barIndex = bar.Index(); + double sar = mXCHSARHelper.GetC(barIndex); + bool isBullish = sar > 0 && + sar < bar.low; + bool isBearish = sar > 0 && + sar > bar.high; + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Loop Back to Find Nearest Sar Change ... + bool canContinue = true; + while (canContinue) + { + // + barIndex++; + + // + XOHCL iBar; + canContinue = iBar.Init( + bar.symbol, + bar.period, + barIndex // + ); + if (!canContinue) + { + break; + } + + // + double iSar = mXCHSARHelper.GetC(barIndex); + bool isISarBullish = + iSar > 0 && + iSar < iBar.low; + bool isISarBearish = + iSar > 0 && + iSar > iBar.high; + bool isSarChanged = + isBullish + ? !isISarBullish + : !isISarBearish; + + // + if (isSarChanged) + { + // + changeBar = iBar; + canContinue = false; + break; + } + } + + // + result = changeBar.IsValid(); + + // + return result; + } + + // + // Virtuals ... + + // + protected: + // + + // + private: + // + // Props ... + + // + // Actions ... + + /** + * Release All Resources ... + */ + void DeInit() + { + } + + /** + * Apply Chart Style ... + */ + void ApplyChartStyle() + { + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + + // + ENUM_CHART_MODE mMode = CHART_CANDLES; // chart's mMode + bool mShowBidLine = true; // show bid line + bool mShowAskLine = true; // show ask line + bool mShowGrid = false; // show grids on chart + bool mShowVolumes = false; // show volumes + bool mShowTradeLevels = true; // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true; // chart autoscroll + bool mQuickNavigation = true; // chart quick navigation state + color mForeGroundColor = clrWhite; // chart's foreground color + color mBackGroundColor = clrBlack; // chart's background color + color mUpColor = clrGreen; // Up Color + color mDownColor = clrRed; // Down Color + color mBullishColor = clrGreen; // Bullish color + color mBearishColor = clrRed; // Bearish color + color mGridColor = clrGray; // grid color + color mBidLineColor = clrGray; // bid line color + color mAskLineColor = clrRed; // ask line color + color mLineColor = clrLime; // line mMode and doji candlestick color + color mStopColor = clrGold; // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen; // volumes color + + // + ChartSetInteger(chartId, CHART_MODE, mMode); + ChartSetInteger(chartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(chartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(chartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(chartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(chartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(chartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(chartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(chartId, CHART_COLOR_VOLUME, mVolumesColor); + } +}; diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index e88a3ac2..064107e6 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -426,8 +426,9 @@ struct XPVPivot }; // -// Model Signalling Conditions ... -struct X121SMCStrategyConditions +// Each Market Cycle (Time Frame) Conditions +// Model as this Structure ... +struct X121SMCCycleConditions { // string symbol; @@ -440,6 +441,9 @@ struct X121SMCStrategyConditions X3VWAPConditions x3vwapConditions; XCHSARConditions xchsarConditions; + // + XPOIState state; + // void X121SMCStrategyConditions() { @@ -460,9 +464,11 @@ struct X121SMCStrategyConditions time = NULL; // + state.Clean(); xpvConditions.Clean(); x3maConditions.Clean(); x3vwapConditions.Clean(); + xchsarConditions.Clean(); } /** @@ -479,6 +485,96 @@ struct X121SMCStrategyConditions result = IsSpecifiedValid(symbol) && IsSpecifiedValid(period) && IsSpecifiedValid(time); + // + ; + + // + return result; + } + + /** + * Check Cycle Conditions Has Bullish State ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool IsBullish( + XOHCL &bar // + ) + { + // + bool result = false; + + // + int index = bar.Index(); + + // + result = + // + // Check Conditions Validation ... + IsValid() && + // + // Check Bar Validation ... + bar.IsValid() && + // + // Check XCHSar Current is Bullish ... + xchsarConditions.isCBullish && + // + // Check X3VWAP is Bullish State ... + x3vwapConditions.isBullishState && + // + // Check X3VWAP is Bullish Ordered ... + x3vwapConditions.isBullishOrdered && + // + // Check Close Over X3MA Fast ... + bar.close > x3maConditions.fasts[index] + // + ; + + // + return result; + } + + /** + * Check Cycle Conditions Has Bearish State ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool IsBearish( + XOHCL &bar // + ) + { + // + bool result = false; + + // + int index = bar.Index(); + + // + result = + // + // Check Conditions Validation ... + IsValid() && + // + // Check Bar Validation ... + bar.IsValid() && + // + // Check XCHSar Current is Bearish ... + xchsarConditions.isCBearish && + // + // Check X3VWAP is Bearish State ... + x3vwapConditions.isBearishState && + // + // Check X3VWAP is Bearish Ordered ... + x3vwapConditions.isBearishOrdered && + // + // Check Close Under X3MA Fast ... + bar.close < x3maConditions.fasts[index] + // + ; // return result; @@ -611,15 +707,18 @@ struct X121SMCStrategyConditions // string result = NULL; + // + string typeName = GetTypeName(this); + // if (!forObject) { - result = X121SMCStrategyToken; + result = typeName; } else { // - result = X121SMCStrategyToken + "_" + + result = typeName + "_" + symbol + "_" + ToString(period) + "_" + ToMD5(time); } @@ -631,160 +730,398 @@ struct X121SMCStrategyConditions // }; +// +// Model Signalling Conditions ... +struct X121SMCStrategyConditions +{ + // + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Cycles Conditions here ... + X121SMCCycleConditions triggerConditions; + X121SMCCycleConditions decisionConditions; + X121SMCCycleConditions analyseConditions; + X121SMCCycleConditions verificationConditions; + X121SMCCycleConditions consolidationConditions; + X121SMCCycleConditions visionConditions; + + // + void X121SMCStrategyConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + time = NULL; + + // + triggerConditions.Clean(); + decisionConditions.Clean(); + analyseConditions.Clean(); + verificationConditions.Clean(); + consolidationConditions.Clean(); + visionConditions.Clean(); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(time); + + // + return result; + } + + bool HasDirection( + ENUM_X_DIRECTION &dir, + XOHCL &bar // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + result = IsValid() && + bar.IsValid() && + bar.Index() > 0; + if (!result) + { + return result; + } + + // + int index = bar.Index(); + + // + // Parse Cycles Conditions ... + + // + // Vision ... + + // + bool isVisionBullish = + // + // XCHSar Current is Bullish ... + visionConditions.xchsarConditions.isCBullish && + // + // Close Over X3MA Fast ... + bar.close > visionConditions.x3maConditions.fasts[index] && + // + // X3VWap Fast is Bullish ... + visionConditions.x3vwapConditions.fastStates[index] == + X3VWAP_STATE_BULLISH + // + ; + + // + bool isVisionBearish = + // + // XCHSar Current is Bearish ... + visionConditions.xchsarConditions.isCBearish && + // + // Close Under X3MA Fast ... + bar.close < visionConditions.x3maConditions.fasts[index] && + // + // X3VWap Fast is Bearish ... + visionConditions.x3vwapConditions.fastStates[index] == + X3VWAP_STATE_BEARISH + // + ; + + // + // Check Vision Has Conditions or not ... + bool hasVisionConditions = + isVisionBullish || + isVisionBearish; + result = hasVisionConditions; + if (!result) + { + return result; + } + + // + // Consolidation ... + + // + bool isConsolidationBullish = consolidationConditions.IsBullish(bar); + bool isConsolidationBearish = consolidationConditions.IsBearish(bar); + bool hasConsolidationConditions = + isConsolidationBullish || + isConsolidationBearish; + result = hasConsolidationConditions; + if (!result) + { + return result; + } + + // + // Verification ... + + // + bool isVerificationBullish = verificationConditions.IsBullish(bar); + bool isVerificationBearish = verificationConditions.IsBearish(bar); + bool hasVerificationConditions = + isVerificationBullish || + isVerificationBearish; + result = hasVerificationConditions; + if (!result) + { + return result; + } + + // + // Analyse ... + + // + bool isAnalyseBullish = analyseConditions.IsBullish(bar); + bool isAnalyseBearish = analyseConditions.IsBearish(bar); + bool hasAnalyseConditions = + isAnalyseBullish || + isAnalyseBearish; + result = hasAnalyseConditions; + if (!result) + { + return result; + } + + // + // Decision ... + + // + bool isDecisionBullish = decisionConditions.IsBullish(bar); + bool isDecisionBearish = decisionConditions.IsBearish(bar); + bool hasDecisionConditions = + isDecisionBullish || + isDecisionBearish; + result = hasDecisionConditions; + if (!result) + { + return result; + } + + // + // Analyse Conditions ... + bool hasBullishConditions = + // + isVisionBullish && + isConsolidationBullish && + isVerificationBullish && + isAnalyseBullish && + isDecisionBullish + // + ; + bool hasBearishConditions = + // + isVisionBearish && + isConsolidationBearish && + isVerificationBearish && + isAnalyseBearish && + isDecisionBearish + // + ; + result = hasBullishConditions || + hasBearishConditions; + if (!result) + { + return result; + } + + // + // Specified Conditions Direction ... + dir = + hasBullishConditions + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + // + // Reporter Functions ... + + /** + * Generate Provided Scores ... + * + * @param bullishScore: Integer, reference ... + * @param bearishScore: Integer, referenceF ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + if (!IsValid()) + { + return; + } + + // + double bullScore = 0; + double bearScore = 0; + + // // + // // XPV ... + // pvConditions.GenerateScore( + // bullScore, + // bearScore // + // ); + // bullishScore += bullScore; + // bearishScore += bearScore; + } + + /** + * Generate Summary ... + * + * @param onlyCommons: Boolean ... + * @param onlyConditions: Boolean ... + * @param includeScores: Boolean ... + * @param ignoreFalseConditions: Boolean ... + * @param separator: String ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores, + true // + ); + + // // + // // XPV ... + // string pvStr = pvConditions.GenerateSummary( + // false, + // true, + // false, + // ignoreFalseConditions // + // ); + + // + string conditionsStr = + // + // pvStr + separator + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + "----------" + separator + + (onlyConditions + ? "" + : commonStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Get Unique Identifier ... + * + * @param forObject: Boolean ... + * + * @return ( string ) + */ + string GetTag( + bool forObject = false // + ) + { + // + string result = NULL; + + // + string typeName = GetTypeName(this); + + // + if (!forObject) + { + result = typeName; + } + else + { + // + result = typeName + "_" + + symbol + "_" + ToString(period) + "_" + + ToMD5(time); + } + + // + return result; + } + + // +}; + +// +// +// + typedef void (*TOnX121SMCSignal)( XSignal &signal, X121SMCStrategyConditions &conditions // ); -// -// Time Frames Tools ... - -/** - * Calculate Analyse Period ... - * - * @param value: ENUM_TIMEFRAMES member, Specified Trigger Period ... - * - * @return ( ENUM_TIMEFRAMES ) - */ -ENUM_TIMEFRAMES GetAnalysePeriod(ENUM_TIMEFRAMES value) -{ - // - ENUM_TIMEFRAMES result = NULL; - - // - value = NormalizePeriod(value); - - // - switch (value) - { - // - case PERIOD_M1: - case PERIOD_M2: - case PERIOD_M3: - case PERIOD_M4: - case PERIOD_M5: - case PERIOD_M6: - case PERIOD_M10: - case PERIOD_M12: - result = PERIOD_M15; - break; - - // - case PERIOD_M15: - case PERIOD_M20: - result = PERIOD_M30; - break; - - // - case PERIOD_H1: - case PERIOD_H2: - case PERIOD_H3: - result = PERIOD_H4; - break; - - // - case PERIOD_H4: - case PERIOD_H6: - case PERIOD_H8: - result = PERIOD_H12; - break; - - // - default: - result = NULL; - } - - // - return result; -} -bool HasValidAnalysePeriod( - ENUM_TIMEFRAMES value, - ENUM_TIMEFRAMES &period // -) -{ - // - bool result = false; - - period = GetAnalysePeriod(value); - result = IsValid(period); - - // - return result; -} - -/** - * Calculate Vision Period ... - * - * @param value: ENUM_TIMEFRAMES member, Specified Trigger Period ... - * - * @return ( ENUM_TIMEFRAMES ) - */ -ENUM_TIMEFRAMES GetVisionPeriod(ENUM_TIMEFRAMES value) -{ - // - ENUM_TIMEFRAMES result = NULL; - - // - value = NormalizePeriod(value); - - // - switch (value) - { - // - case PERIOD_M1: - case PERIOD_M2: - case PERIOD_M3: - case PERIOD_M4: - case PERIOD_M5: - case PERIOD_M6: - case PERIOD_M10: - case PERIOD_M12: - result = PERIOD_H1; - break; - - // - case PERIOD_M15: - case PERIOD_M20: - result = PERIOD_H2; - break; - - // - case PERIOD_H1: - case PERIOD_H2: - case PERIOD_H3: - result = PERIOD_H6; - break; - - // - case PERIOD_H4: - case PERIOD_H6: - case PERIOD_H8: - result = PERIOD_D1; - break; - - // - default: - result = NULL; - } - - // - return result; -} -bool HasValidVisionPeriod( - ENUM_TIMEFRAMES value, - ENUM_TIMEFRAMES &period // -) -{ - // - bool result = false; - - period = GetVisionPeriod(value); - result = IsValid(period); - - // - return result; -} - // // Extentions ... diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index 49ce616c..bdb3be81 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -23,11 +23,8 @@ // Imports ... // -#include "../../Helpers/x-saherelm.x3ma.helper.mq5" -#include "../../Helpers/x-saherelm.x3vwap.helper.mq5" -#include "../../Helpers/x-saherelm.xchsar.helper.mq5" -#include "../../Helpers/x-saherelm.xpv.helper.mq5" #include "../Classes/x-121.smc.base.strategy.class.mq5" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" // // Definitions ... @@ -69,10 +66,12 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy void Destroy() override { // - delete xpvHelper; - delete x3maHelper; - delete xchsarHelper; - delete x3vwapHelper; + delete mTriggerCycleHelper; + delete mDecisionCycleHelper; + delete mAnalyseCycleHelper; + delete mVerificationCycleHelper; + delete mConsolidationCycleHelper; + delete mVisionCycleHelper; } /** @@ -180,537 +179,41 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy double bid = GetBid(_symbol); // - // Check Momentum Bar ... - ENUM_X_DIRECTION momentumCBarDir; - bool isCMomentumBar = mBarAnalyser.IsMomentumBar( - cBar, - momentumCBarDir // - ); - bool isCBullishMomentumBar = - isCMomentumBar && - IsBullish(momentumCBarDir); - bool isCBearishMomentumBar = - isCMomentumBar && - IsBearish(momentumCBarDir); - - // - // Check Momentum Bar ... - ENUM_X_DIRECTION momentumPBarDir; - bool isPMomentumBar = mBarAnalyser.IsMomentumBar( - pBar, - momentumPBarDir // - ); - bool isPBullishMomentumBar = - isPMomentumBar && - IsBullish(momentumPBarDir); - bool isPBearishMomentumBar = - isPMomentumBar && - IsBearish(momentumPBarDir); - - // - // Check Rejection Bar ... - ENUM_X_DIRECTION rejectionCBarDir; - bool isCRejectionBar = mBarAnalyser.IsRejectionBar( - cBar, - rejectionCBarDir // - ); - bool isCBullishRejectionBar = - isCRejectionBar && - IsBullish(rejectionCBarDir); - bool isCBearishRejectionBar = - isCRejectionBar && - IsBearish(rejectionCBarDir); - - // - // Check Rejection Bar ... - ENUM_X_DIRECTION rejectionPBarDir; - bool isPRejectionBar = mBarAnalyser.IsRejectionBar( - pBar, - rejectionPBarDir // - ); - bool isPBullishRejectionBar = - isPRejectionBar && - IsBullish(rejectionPBarDir); - bool isPBearishRejectionBar = - isPRejectionBar && - IsBearish(rejectionPBarDir); - - // - // Check Engulfing ... - ENUM_X_DIRECTION engulfCBarDir; - bool isCEngulfed = mBarAnalyser.IsEngulfBar( - cBar, - engulfCBarDir // - ); - bool isCBullishEngulfed = - isCEngulfed && - IsBullish(engulfCBarDir); - bool isCBearishEngulfed = - isCEngulfed && - IsBearish(engulfCBarDir); - - // - // Check Engulfing ... - ENUM_X_DIRECTION engulfPBarDir; - bool isPEngulfed = mBarAnalyser.IsEngulfBar( - pBar, - engulfPBarDir // - ); - bool isPBullishEngulfed = - isPEngulfed && - IsBullish(engulfPBarDir); - bool isPBearishEngulfed = - isPEngulfed && - IsBearish(engulfPBarDir); - - // - bool isCRMEBullish = - // - isCBullishEngulfed - // - || - // - isCBullishMomentumBar - // - || - // - isCBullishRejectionBar - // - ; - - // - bool isPRMEBullish = - // - isPBullishEngulfed - // - || - // - isPBullishMomentumBar - // - || - // - isPBullishRejectionBar - // - ; - - // - bool isCRMEBearish = - // - isCBearishEngulfed - // - || - // - isCBearishMomentumBar - // - || - // - isCBearishRejectionBar - // - ; - - // - bool isPRMEBearish = - // - isPBearishEngulfed - // - || - // - isPBearishMomentumBar - // - || - // - isPBearishRejectionBar - // - ; - - // + // Check Spread ... bool isSpreadPassed = IsSpreadPass(); result = isSpreadPassed; if (!result) { + // + // string message = "Spread is not Passed for Analysing ..."; + // LogAlert(message); + + // return result; } // - // Try to Implement SMC Based Conditions ... + // Detect Conditions ... result = DetectConditions(conditions); if (!result) { return result; } - // - // Validate Order Flow ... - bool isValidOrderFlow = HasValidOrderFlow(); - result = isValidOrderFlow; - if (!result) - { - return result; - } - - // - XPVPivot lastPivot; - result = GetLastItem( - lastPivot, - mOrderFlow // - ); - if (!result) - { - return result; - } - - // - // Detect Fair Value Gaps ... - bool hasPOI = FindPOIInPivot( - X_POI_SWING_HIGH, - lastPivot, - mVisionPOIStat); - // TODO: - - // - bool isOrderFlowBullish = IsBullish(mOrderFlowDir); - - // - // Check Parabolic Sar is in Order of Order Flow ... - bool isPSarInDirectionOfOrderFlow = - isOrderFlowBullish - ? conditions.xchsarConditions.cSars[0] < cBar.low && - conditions.xchsarConditions.cSars[1] >= pBar.low - : conditions.xchsarConditions.cSars[0] > cBar.high && - conditions.xchsarConditions.cSars[1] <= pBar.high; - - // - // Check BOS or CHOCH Happens ... - bool hasBOS = - isOrderFlowBullish - ? - // - // Price Close Over Pivot's High ... - cBar.IsBullish() && - cBar.close > lastPivot.upper && - (pBar.close < lastPivot.upper || - pBar.low < lastPivot.upper) - // - : - // - // Price Must Close Under Pivots Low ... - cBar.IsBearish() && - cBar.close < lastPivot.lower && - (pBar.close > lastPivot.lower || - pBar.high > lastPivot.lower) - // - ; - - // - if (hasBOS) - { - mLastBOSOn = TimeCurrent(); - } - - bool hasCHOCH = - isOrderFlowBullish - ? - // - // Price Close Under Pivot's Low ... - cBar.IsBearish() && - cBar.close < lastPivot.lower && - (pBar.close > lastPivot.lower || - pBar.high > lastPivot.lower) - // - : - // - // Price Must Close Over Pivots High ... - cBar.IsBullish() && - cBar.close > lastPivot.upper && - (pBar.close < lastPivot.upper || - pBar.low < lastPivot.upper) - // - ; - - // - // Check PSar is Equals to Peak or Vale ... - bool isSAREqualsToPeak = - conditions.xchsarConditions.cSars[0] == conditions.xpvConditions.peaks[1]; - bool isSAREqualsToVale = - conditions.xchsarConditions.cSars[0] == conditions.xpvConditions.vales[1]; - - // - bool hasNewPeak = - conditions.xpvConditions.peaks[0] != conditions.xpvConditions.peaks[1]; - bool hasNewPeakOverLast = - hasNewPeak && - conditions.xpvConditions.peaks[0] > conditions.xpvConditions.peaks[1]; - bool hasNewPeakUnderLast = - hasNewPeak && - conditions.xpvConditions.peaks[0] < conditions.xpvConditions.peaks[1]; - - // - bool hasNewVale = - conditions.xpvConditions.vales[0] != conditions.xpvConditions.vales[1]; - bool hasNewValeOverLast = - hasNewVale && - conditions.xpvConditions.vales[0] > conditions.xpvConditions.vales[1]; - bool hasNewValeUnderLast = - hasNewVale && - conditions.xpvConditions.vales[0] < conditions.xpvConditions.vales[1]; - - // - // START Signalling ... - // - - // - // BOS Signals ... - bool has_BOS_Long = false; - bool has_BOS_Short = false; - - // - // CHOCH Signals ... - bool has_CHOCH_Long = false; - bool has_CHOCH_Short = false; - - // - // SAR Signals ... - bool has_SAR_Long = false; - bool has_SAR_Short = false; - - // - // PULLBACK Signals ... - bool has_PULLBK_Long = false; - bool has_PULLBK_Short = false; - - // - // PV Signals ... - bool has_PV_Long = false; - bool has_PV_Short = false; - - // - // BOS Signals ... - // - has_BOS_Long = - // - hasBOS && - isOrderFlowBullish && - isCRMEBullish && - cBar.IsBullish() && - conditions.xchsarConditions.cSars[0] < cBar.low - // - ; - - // - if (has_BOS_Long) - { - // - selectedSL = cBar.low; - provider = ToString(X_121_SMC_PROVIDER_BOS); - } - - // - has_BOS_Short = - // - hasBOS && - !isOrderFlowBullish && - isCRMEBearish && - cBar.IsBearish() && - conditions.xchsarConditions.cSars[0] > cBar.high - // - ; - if (has_BOS_Short) - { - // - selectedSL = cBar.high; - provider = ToString(X_121_SMC_PROVIDER_BOS); - } - - // - // CHOCH Signals ... - - // - has_CHOCH_Long = - // - hasCHOCH && - isCRMEBullish && - cBar.IsBullish() && - !isOrderFlowBullish && - conditions.xchsarConditions.cSars[0] < cBar.low - // - ; - if (has_CHOCH_Long) - { - // - selectedSL = cBar.low; - provider = ToString(X_121_SMC_PROVIDER_CHOCH); - } - - // - has_CHOCH_Short = - // - hasCHOCH && - isCRMEBearish && - cBar.IsBearish() && - isOrderFlowBullish && - conditions.xchsarConditions.cSars[0] > cBar.high - // - ; - if (has_CHOCH_Short) - { - // - selectedSL = cBar.high; - provider = ToString(X_121_SMC_PROVIDER_CHOCH); - } - - // - // SAR Signals ... - - // - has_SAR_Long = - // - isSAREqualsToVale && - isOrderFlowBullish && - isPSarInDirectionOfOrderFlow - // - ; - if (has_SAR_Long) - { - // - provider = ToString(X_121_SMC_PROVIDER_SAR); - selectedSL = conditions.xchsarConditions.cSars[0]; - } - - // - has_SAR_Short = - // - isSAREqualsToPeak && - !isOrderFlowBullish && - isPSarInDirectionOfOrderFlow - // - ; - if (has_SAR_Short) - { - // - provider = ToString(X_121_SMC_PROVIDER_SAR); - selectedSL = conditions.xchsarConditions.cSars[0]; - } - - // - // PULLBK Signals ... - - // - has_PULLBK_Long = - // - isCRMEBullish && - isPSarInDirectionOfOrderFlow && - (cBar.low < conditions.x3maConditions.fasts[0] && - cBar.GetDown() > conditions.x3maConditions.fasts[0]) - // - ; - if (has_PULLBK_Long) - { - // - selectedSL = cBar.low; - provider = ToString(X_121_SMC_PROVIDER_PULLBK); - } - - // - has_PULLBK_Short = - // - isCRMEBearish && - isPSarInDirectionOfOrderFlow && - (cBar.high > conditions.x3maConditions.fasts[0] && - cBar.GetUp() < conditions.x3maConditions.fasts[0]) - // - ; - if (has_PULLBK_Short) - { - // - selectedSL = cBar.high; - provider = ToString(X_121_SMC_PROVIDER_PULLBK); - } - - // - // PV Signals ... - - // - has_PV_Long = - // - isCRMEBullish && - isOrderFlowBullish && - !hasNewValeUnderLast && - cBar.low == conditions.xpvConditions.vales[0] - // - ; - if (has_PV_Long) - { - // - selectedSL = cBar.low; - provider = ToString(X_121_SMC_PROVIDER_PV); - } - - // - has_PV_Short = - // - isCRMEBearish && - !isOrderFlowBullish && - !hasNewPeakOverLast && - cBar.high == conditions.xpvConditions.peaks[0] - // - ; - if (has_PV_Short) - { - // - selectedSL = cBar.high; - provider = ToString(X_121_SMC_PROVIDER_PV); - } - - // - // END Signalling ... - // - // // Combine all Signals Conditions ... // hasLong = // - has_BOS_Long - // - || - // - has_CHOCH_Long - // - || - // - has_SAR_Long - // - || - // - has_PULLBK_Long - // - || - // - has_PV_Long + false // ; // hasShort = // - has_BOS_Short - // - || - // - has_CHOCH_Short - // - || - // - has_SAR_Short - // - || - // - has_PULLBK_Short - // - || - // - has_PV_Short + false // ; @@ -718,17 +221,6 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy result = hasLong || hasShort; - // - // Reset Order Flow ... - if (hasCHOCH && !result) - { - ResetOrderFlow(); - } - else if (hasBOS && !result) - { - UpdateOrderFlow(); - } - // // Rmove Signal Condition ... if (result) @@ -850,11 +342,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ignoreBullishRejectionBars, ignoreBearishRejectionBars, ignoreBullishMomentumBars, - ignoreBearishMomentumBars, - // - false, // Vision State ... - false, // Analyse State ... - false // Trigger State ... + ignoreBearishMomentumBars // ); DrawSignal(signal); ClearDraws(); @@ -889,33 +377,17 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // Props ... // - // XPV ... - XPVInputs xpvInputs; - XCXPVHelper *xpvHelper; - - // - // X3MA ... - X3MAInputs x3maInputs; - XCX3MAHelper *x3maHelper; - - // - // X3VWAP ... - X3VWAPInputs x3vwapInputs; - XCX3VWAPHelper *x3vwapHelper; - - // - // XCHSAR ... - XCHSARInputs xchsarInputs; - XCXCHSARHelper *xchsarHelper; - - // + // Trigger Order Flow ... XPVPivot mOrderFlow[]; ENUM_X_DIRECTION mOrderFlowDir; // - // Holds Last CHOCH and BOS time ... - datetime mLastBOSOn; - datetime mLastCHOCHOn; + XC121SMCCycleHelper *mTriggerCycleHelper; + XC121SMCCycleHelper *mDecisionCycleHelper; + XC121SMCCycleHelper *mAnalyseCycleHelper; + XC121SMCCycleHelper *mVerificationCycleHelper; + XC121SMCCycleHelper *mConsolidationCycleHelper; + XC121SMCCycleHelper *mVisionCycleHelper; // // Actions ... @@ -942,6 +414,30 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy int pIndex = cIndex + 1; int ppIndex = pIndex + 1; + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + // conditions.symbol = symbol; conditions.period = period; @@ -951,55 +447,79 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy int conditionsLoopback = 7; // - // XPV ... - result = xpvHelper.GetConditions( - conditions.xpvConditions, - cIndex, + // Fill Cycles Conditions ... + + // + // Trigger ... + mTriggerCycleHelper.GetConditions( + conditions.triggerConditions, + zIndex, conditionsLoopback // ); + conditions.triggerConditions.state = mTriggerState; + + // + // Decision ... + mDecisionCycleHelper.GetConditions( + conditions.decisionConditions, + zIndex, + conditionsLoopback // + ); + conditions.decisionConditions.state = mDecisionState; + + // + // Analyse ... + mAnalyseCycleHelper.GetConditions( + conditions.analyseConditions, + zIndex, + conditionsLoopback // + ); + conditions.analyseConditions.state = mAnalyseState; + + // + // Verification ... + mVerificationCycleHelper.GetConditions( + conditions.verificationConditions, + zIndex, + conditionsLoopback // + ); + conditions.verificationConditions.state = mVerificationState; + + // + // Consolidation ... + mConsolidationCycleHelper.GetConditions( + conditions.consolidationConditions, + zIndex, + conditionsLoopback // + ); + conditions.consolidationConditions.state = mConsolidationState; + + // + // Vision ... + mVisionCycleHelper.GetConditions( + conditions.visionConditions, + zIndex, + conditionsLoopback // + ); + conditions.visionConditions.state = mVisionState; + + // + // Check Market Conditions for + // Specified Structure ... + ENUM_X_DIRECTION marketStructureDir = X_DIRECTION_NONE; + result = conditions.HasDirection( + marketStructureDir, + cBar // + ); if (!result) { + // + conditions.Clean(); return result; } // - // X3MA ... - result = x3maHelper.GetConditions( - conditions.x3maConditions, - cIndex, - conditionsLoopback // - ); - if (!result) - { - return result; - } - - // - // X3VWAP ... - result = x3vwapHelper.GetConditions( - conditions.x3vwapConditions, - cIndex, - conditionsLoopback // - ); - if (!result) - { - return result; - } - - // - // XCHSAR ... - result = xchsarHelper.GetConditions( - conditions.xchsarConditions, - cIndex, - conditionsLoopback // - ); - if (!result) - { - return result; - } - - // - // Only Detect Order Flow when there isn't ... + // Detect Trigger Order Flow ... if (ArraySize(mOrderFlow) == 0 || mOrderFlowDir == X_DIRECTION_NONE) { @@ -1012,6 +532,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy cIndex, samePivots, requiredPivots, + mTriggerCycleHelper, mOrderFlow, mOrderFlowDir // ); @@ -1023,22 +544,124 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } } - - // - if (result) + result = HasValidOrderFlow() && + mOrderFlowDir == marketStructureDir; + if (!result) { // - int lastPivotIDX = ArraySize(mOrderFlow) - 1; - if (IsValidSize(lastPivotIDX)) - { - // - FillPivotSate( - lastPivotIDX, - true, // Use Vision State ... - true, // Use Analyse State ... - false // Use Trigger State ... - ); - } + conditions.Clean(); + return result; + } + + // + // Detect Nearest Sar Change ... + XOHCL sarChangeBar; + result = mTriggerCycleHelper.DetectNearestCSARChange( + sarChangeBar, + cBar // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + // TODO: Remove This ... + bool ignoreSwingHighs = true; + bool ignoreSwingLows = true; + bool ignoreSupportZones = true; + bool ignoreResistanceZones = true; + bool ignoreSupplyZones = true; + bool ignoreDemandZones = true; + bool ignoreBullishOrderBlocks = true; + bool ignoreBearishOrderBlocks = true; + bool ignoreBullishFairValueGaps = true; + bool ignoreBearishFairValueGaps = true; + bool ignoreBullishRejectionBars = true; + bool ignoreBearishRejectionBars = true; + bool ignoreBullishMomentumBars = true; + bool ignoreBearishMomentumBars = true; + + // + if (IsBullish(marketStructureDir)) + { + // + ignoreSwingLows = false; + ignoreSupportZones = false; + ignoreDemandZones = false; + ignoreBullishOrderBlocks = false; + ignoreBullishFairValueGaps = false; + ignoreBullishRejectionBars = false; + ignoreBullishMomentumBars = false; + + // + ignoreSwingHighs = true; + ignoreResistanceZones = true; + ignoreSupplyZones = true; + ignoreBearishOrderBlocks = true; + ignoreBearishFairValueGaps = true; + ignoreBearishRejectionBars = true; + ignoreBearishMomentumBars = true; + } + else + { + // + ignoreSwingLows = true; + ignoreSupportZones = true; + ignoreDemandZones = true; + ignoreBullishOrderBlocks = true; + ignoreBullishFairValueGaps = true; + ignoreBullishRejectionBars = true; + ignoreBullishMomentumBars = true; + + // + ignoreSwingHighs = true; + ignoreResistanceZones = true; + ignoreSupplyZones = true; + ignoreBearishOrderBlocks = true; + ignoreBearishFairValueGaps = false; + ignoreBearishRejectionBars = false; + ignoreBearishMomentumBars = false; + } + + // + RedrawOrderFlow( + true, // Force Clean ... + false, // Same Period ... + true, // Order Flow ... + true, // Order Flow State ... + false, // Only Last Order Flow ... + true, // Only Last Order Flow State ... + // + marketStructureDir, // Direction Force ... + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + + // + // Here we Have to Detect Entry Conditions ... + // TODO: Implement this ... + + // + if (!result) + { + // + conditions.Clean(); + return result; } // @@ -1051,6 +674,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy * @param barIndex: Start Bar Index ... * @param minRepetition: minimum Repeate of POI for Validation ... * @param requiredPivots: Number of Min Requirement POI(s) ... + * @param pivotHelper: XC121SMCCycleHelper instance Pointer ... * @param orderFlow: XPVPivot instance Array Reference ... * @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ... * @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ... @@ -1061,6 +685,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy int barIndex, int minRepetition, int requiredPivots, + XC121SMCCycleHelper *pivotHelper, // XPV Helper ... XPVPivot &orderFlow[], // OrderFlows ... ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ... int maxAllowedLoopbackBars = 576 // @@ -1087,7 +712,8 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // result = minRepetition > 0 && - requiredPivots > 0; + requiredPivots > 0 && + pivotHelper != NULL; if (!result) { return result; @@ -1119,7 +745,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy { // // Check Peak ... - double iPeak = xpvHelper.GetPeak(barIndex); + double iPeak = pivotHelper.mXPVHelper.GetPeak(barIndex); if (iPeak != peak) { // @@ -1200,7 +826,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // Check Vale ... - double iVale = xpvHelper.GetVale(barIndex); + double iVale = pivotHelper.mXPVHelper.GetVale(barIndex); if (iVale != vale) { // @@ -1349,9 +975,12 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // FillPivotSate( i, - true, // Use Vision State ... - true, // Use Analyse State ... - false // Use Trigger State ... + false, // Use Vision State ... + false, // Use Consolidation State ... + false, // Use Verification State ... + false, // Use Analyse State ... + true, // Use Decision State ... + false // Use Trigger State ... ); } } @@ -1380,10 +1009,13 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy * @param lookupBearishMomentumBars: Boolean ... */ void FillPivotSate( - int pivotIDX, // - bool useVisionState = true, // Use Vision State ... - bool useAnalyseState = true, // Use Analyse State ... - bool useTriggerState = true, // Use Trigger State ... + int pivotIDX, // + bool useVisionState = true, // Use Vision State ... + bool useConsolidationState = true, // Use Consolidation State ... + bool useVerificationState = true, // Use Verification State ... + bool useAnalyseState = true, // Use Analyse State ... + bool useDecisionState = true, // Use Decision State ... + bool useTriggerState = true, // Use Trigger State ... bool lookupSwingHighs = true, bool lookupSwingLows = true, bool lookupSupportZones = true, @@ -1405,15 +1037,15 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // Trigger ... - XPOIState mTriggerState; + XPOIState mPivotTriggerState; if (useTriggerState && - mTriggerPOIState.HasChild()) + mTriggerState.HasChild()) { // DetectPivotPOIs( mOrderFlow[pivotIDX], - mTriggerPOIState, mTriggerState, + mPivotTriggerState, lookupSwingHighs, lookupSwingLows, lookupSupportZones, @@ -1431,23 +1063,57 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ); // - if (mTriggerState.HasChild()) + if (mPivotTriggerState.HasChild()) { - mTriggerState.Fill(mOrderFlow[pivotIDX].state); + mPivotTriggerState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Decision ... + XPOIState mPivotDecisionState; + if (useDecisionState && + mDecisionState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mDecisionState, + mPivotDecisionState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotDecisionState.HasChild()) + { + mPivotDecisionState.Fill(mOrderFlow[pivotIDX].state); } } // // Analyse ... - XPOIState mAnalyseState; + XPOIState mPivotAnalyseState; if (useAnalyseState && - mAnalysePOIState.HasChild()) + mAnalyseState.HasChild()) { // DetectPivotPOIs( mOrderFlow[pivotIDX], - mAnalysePOIState, mAnalyseState, + mPivotAnalyseState, lookupSwingHighs, lookupSwingLows, lookupSupportZones, @@ -1465,23 +1131,91 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ); // - if (mAnalyseState.HasChild()) + if (mPivotAnalyseState.HasChild()) { - mAnalyseState.Fill(mOrderFlow[pivotIDX].state); + mPivotAnalyseState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Verification ... + XPOIState mPivotVerificationState; + if (useVerificationState && + mVerificationState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mVerificationState, + mPivotVerificationState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotVerificationState.HasChild()) + { + mPivotVerificationState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Consolidation ... + XPOIState mPivotConsolidationState; + if (useConsolidationState && + mConsolidationState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mConsolidationState, + mPivotConsolidationState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotConsolidationState.HasChild()) + { + mPivotConsolidationState.Fill(mOrderFlow[pivotIDX].state); } } // // Vision ... - XPOIState mVisionState; + XPOIState mPivotVisionState; if (useVisionState && - mVisionPOIState.HasChild()) + mVisionState.HasChild()) { // DetectPivotPOIs( mOrderFlow[pivotIDX], - mVisionPOIState, mVisionState, + mPivotVisionState, lookupSwingHighs, lookupSwingLows, lookupSupportZones, @@ -1499,9 +1233,9 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ); // - if (mVisionState.HasChild()) + if (mPivotVisionState.HasChild()) { - mVisionState.Fill(mOrderFlow[pivotIDX].state); + mPivotVisionState.Fill(mOrderFlow[pivotIDX].state); } } } @@ -1570,8 +1304,8 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy iZone = new XCTicksZone(); // - int ticksLevels = mTriggerPOIDetector.TicksRangeZoneLevel(); - int ticksRange = mTriggerPOIDetector.TicksRangeZoneRange(); + int ticksLevels = mTriggerDetector.TicksRangeZoneLevel(); + int ticksRange = mTriggerDetector.TicksRangeZoneRange(); isInited = ticksLevels > 0 && ticksRange > 0; if (!isInited) @@ -1627,222 +1361,6 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ClearDraws(); } - bool FindPOIInPivot( - XCBasePOI *&pois[], - ENUM_XPOIS type, - XPVPivot &pivot, - XPOIState &state, - ENUM_X_DIRECTION dir = X_DIRECTION_NONE // - ) - { - // - bool result = false; - - // - Clean(pois); - - // - // Validate Inputs ... - result = - // - type != X_POI_NONE && - pivot.IsValid() && - state.IsValid() && - state.HasChild() - // - ; - if (!result) - { - return result; - } - - // - int swingHighsCunt = CountSwingHighs(); - int swingLowsCunt = CountSwingLows(); - int bullishMomentumBarsCunt = CountBullishMomentumBars(); - int bearishMomentumBarsCunt = CountBearishMomentumBars(); - int bullishRejectionBarsCunt = CountBullishRejectionBars(); - int bearishRejectionBarsCunt = CountBearishRejectionBars(); - int supportZonesCunt = CountSupportZones(); - int resistanceZonesCunt = CountResistanceZones(); - int supplyZonesCunt = CountSupplyZones(); - int demandZonesCunt = CountDemandZones(); - int bullishOrderBlocksCunt = CountBullishOrderBlocks(); - int bearishOrderBlocksCunt = CountBearishOrderBlocks(); - int bullishFairValueGapsCunt = CountBullishFairValueGaps(); - int bearishFairValueGapsCunt = CountBearishFairValueGaps(); - - // - switch (type) - { - // - case X_POI_MOMENTUM_BAR: { - // - // Validate Direction ... - result = HasDirection(dir); - if (!result) - { - return result; - } - - // - // Validate State POI(s) ... - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - } - - // - case X_POI_REJECTION_BAR: - // - // Validate Direction ... - result = HasDirection(dir); - if (!result) - { - return result; - } - - // - // Validate State POI(s) ... - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_SWING_HIGH: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_SWING_LOW: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_SUPPORT_ZONE: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_RESISTANCE_ZONE: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_SUPPLY_ZONE: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_DEMAND_ZONE: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_BULLISH_ORDERBLOCK: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_BEARISH_ORDERBLOCK: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_BULLISH_FVG: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - - // - case X_POI_BEARISH_FVG: - // - result = IsValidSize(); - if (!result) - { - break; - } - - // - break; - } - - // - return result; - } - // // Drawings ... @@ -1877,7 +1395,10 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // States Drawing ... bool drawVisionState = false, + bool drawConsolidationState = false, + bool drawVerificationState = false, bool drawAnalyseState = false, + bool drawDecisionState = false, bool drawTriggerState = false // ) { @@ -1977,13 +1498,68 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy } } + // + // Draw States ... + // // Vision ... if (drawVisionState) { // CustomStateDrawing( - mTriggerPOIState, + mVisionState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Consolidation ... + if (drawConsolidationState) + { + // + CustomStateDrawing( + mConsolidationState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Verification ... + if (drawVerificationState) + { + // + CustomStateDrawing( + mVerificationState, false, forDir, ignoreSwingHighs, @@ -2009,7 +1585,33 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy { // CustomStateDrawing( - mAnalysePOIState, + mAnalyseState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Decision ... + if (drawDecisionState) + { + // + CustomStateDrawing( + mDecisionState, false, forDir, ignoreSwingHighs, @@ -2035,7 +1637,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy { // CustomStateDrawing( - mVisionPOIState, + mTriggerState, false, forDir, ignoreSwingHighs, @@ -2749,6 +2351,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // XPV ... + XPVInputs xpvInputs; // xpvInputs.Default(); @@ -2773,16 +2376,9 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy xpvInputs.showFibo4Levels = false; xpvInputs.showFibo5Levels = false; - // - xpvHelper = new XCXPVHelper(); - xpvHelper.Init( - symbol, - period, - xpvInputs // - ); - // // X3MA ... + X3MAInputs x3maInputs; // x3maInputs.Default(); @@ -2792,16 +2388,9 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy x3maInputs.showMid = false; x3maInputs.showSlow = false; - // - x3maHelper = new XCX3MAHelper(); - x3maHelper.Init( - symbol, - period, - x3maInputs // - ); - // // X3VWAP ... + X3VWAPInputs x3vwapInputs; // x3vwapInputs.Default(); @@ -2812,15 +2401,8 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy x3vwapInputs.showSlow = true; // - x3vwapHelper = new XCX3VWAPHelper(); - x3vwapHelper.Init( - symbol, - period, - x3vwapInputs // - ); - - // - // XCHCHSAR ... + // XCHSAR ... + XCHSARInputs xchsarInputs; // xchsarInputs.Default(); @@ -2843,10 +2425,71 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy xchsarInputs.showHind = false; // - xchsarHelper = new XCXCHSARHelper(); - xchsarHelper.Init( + // Initialize Cycle Helpers ... + + // + mTriggerCycleHelper = new XC121SMCCycleHelper(); + mTriggerCycleHelper.Init( symbol, - period, + PERIOD_M1, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mDecisionCycleHelper = new XC121SMCCycleHelper(); + mDecisionCycleHelper.Init( + symbol, + PERIOD_M5, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mAnalyseCycleHelper = new XC121SMCCycleHelper(); + mAnalyseCycleHelper.Init( + symbol, + PERIOD_M15, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mVerificationCycleHelper = new XC121SMCCycleHelper(); + mVerificationCycleHelper.Init( + symbol, + PERIOD_M30, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mConsolidationCycleHelper = new XC121SMCCycleHelper(); + mConsolidationCycleHelper.Init( + symbol, + PERIOD_H1, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mVisionCycleHelper = new XC121SMCCycleHelper(); + mVisionCycleHelper.Init( + symbol, + PERIOD_H4, + xpvInputs, + x3maInputs, + x3vwapInputs, xchsarInputs // ); }