From 1060997f8281c41f964b71e0b9bafbbfbc9087f4 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 7 Feb 2025 18:27:55 +0330 Subject: [PATCH] last ... --- Libraries/x-saherelm.x-poi.lib.mq5 | 180 ++ X121SMCEA/Libraries/x-121.smc.lib.mq5 | 12 +- .../Signals/x-121.smc.xobs.signal.lib.mq5 | 342 ++- .../x-121.smc.xsupdemobs.signal.lib.mq5 | 2507 +++++++++++++++++ .../Strategy/x-121.smc.strategy.class.mq5 | 496 ++-- 5 files changed, 3214 insertions(+), 323 deletions(-) create mode 100644 X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index a489972b..ade8ac8d 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -6593,6 +6593,96 @@ int GetYoungest( return result; } +template +int GetLowest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetLowest(boxes); + + // + Clean(boxes); + + // + return result; +} + +template +int GetHighest( + T *&source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone boxes[]; + bool isConverted = ToBox( + source, + boxes // + ); + if (!isConverted) + { + return result; + } + + // + int boxesCount = ArraySize(boxes); + + // + if (count != boxesCount) + { + return result; + } + + // + result = GetHighest(boxes); + + // + Clean(boxes); + + // + return result; +} + template bool IsSame( T *source, @@ -7794,6 +7884,96 @@ int GetYoungest( return result; } +/** + * Get Highest Box Index ... + * + * @param source: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +int GetHighest( + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone selected; + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = source[i]; + + // + bool canSet = + !selected.IsValid() + ? true + : selected.upper < iBox.upper; + if (canSet) + { + // + result = i; + selected = iBox; + } + } + + // + return result; +} + +/** + * Get Lowest Box Index ... + * + * @param source: XBoxZone instance Reference Collection ... + * + * @return ( int ) + */ +int GetLowest( + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(source); + if (!IsValidSize(count)) + { + return result; + } + + // + XBoxZone selected; + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = source[i]; + + // + bool canSet = + !selected.IsValid() + ? true + : selected.lower > iBox.lower; + if (canSet) + { + // + result = i; + selected = iBox; + } + } + + // + return result; +} + // typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event, XCBasePOI *param // diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index c458bad4..a2fd0660 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -35,8 +35,8 @@ const string X121SMCStrategyToken = "X121SMC"; // -const string X121SMCXToken = "X121X"; const string X121SMCXOBSToken = "X121XOBS"; +const string X121SMCXSupDemOBSToken = "X121XSupDemOBS"; // // X121 SMC Providers ... @@ -44,8 +44,8 @@ enum ENUM_X_121_SMC_PROVIDERS { // X_121_SMC_PROVIDER_NONE, - X_121_SMC_PROVIDER_X, X_121_SMC_PROVIDER_XOBS, + X_121_SMC_PROVIDER_XSUPDEMOBS, }; // @@ -709,8 +709,8 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) switch (value) { // - case X_121_SMC_PROVIDER_X: - result = X121SMCXToken; + case X_121_SMC_PROVIDER_XSUPDEMOBS: + result = X121SMCXSupDemOBSToken; break; // @@ -742,9 +742,9 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) } // - if (Contains(X121SMCXToken, value)) + if (Contains(X121SMCXSupDemOBSToken, value)) { - result = X_121_SMC_PROVIDER_X; + result = X_121_SMC_PROVIDER_XSUPDEMOBS; } else if (Contains(X121SMCXOBSToken, value)) { diff --git a/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 index 55c3db86..efd1acb8 100644 --- a/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xobs.signal.lib.mq5 @@ -680,77 +680,141 @@ bool DetectX121SMCXOBSSignalSetup( UpdateTo(conditions.validBullishOBs); UpdateTo(conditions.validBearishOBs); + // + DrawX121SMCXOBSConditions( + conditions, + drawer // + ); + + // + DrawX121SMCXOBSPOIs( + visionState, + drawer // + ); + + // + DrawX121SMCXOBSPOIs( + consolidationState, + drawer // + ); + // // Lookup for new Order Block ... // for Clearing Conditions .... // - XCOrderBlock *newBullishOB = NULL; - bool hasNewBullishOB = Contains( - X_BULLISH_ORDERBLOCK_DETECTED, - consolidationPoiEvents // - ); - if (hasNewBullishOB) - { - // - int hasOBs = consolidationState.HasBullishOrderBlocks(); - int count = consolidationState.CountBullishOrderBlocks(); - if (hasOBs) - { - // - newBullishOB = consolidationState.bullishOrderBlocks[count - 1]; - } - - // - hasNewBullishOB = newBullishOB != NULL && - newBullishOB.IsValid(); - } - - // - XCOrderBlock *newBearishOB = NULL; - bool hasNewBearishOB = Contains( - X_BEARISH_ORDERBLOCK_DETECTED, - consolidationPoiEvents // - ); - if (hasNewBearishOB) - { - // - int hasOBs = consolidationState.HasBearishOrderBlocks(); - int count = consolidationState.CountBearishOrderBlocks(); - if (hasOBs) - { - newBearishOB = consolidationState.bearishOrderBlocks[count - 1]; - } - - // - hasNewBearishOB = newBearishOB != NULL && - newBearishOB.IsValid(); - } - - // - bool isNewOBDetected = hasNewBullishOB || - hasNewBearishOB; - if (isNewOBDetected) + if (hasYoungestOB) { // + XCOrderBlock *newBullishOB = NULL; + bool hasNewBullishOB = Contains( + X_BULLISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); if (hasNewBullishOB) { // - DrawX121SMCXOBSOrderBlock( - newBullishOB, - consolidationCycleHelper.mPOIDrawer // - ); + int hasOBs = consolidationState.HasBullishOrderBlocks(); + int count = consolidationState.CountBullishOrderBlocks(); + if (hasOBs) + { + // + newBullishOB = consolidationState.bullishOrderBlocks[count - 1]; + } + + // + hasNewBullishOB = newBullishOB != NULL && + newBullishOB.IsValid(); } // + XCOrderBlock *newBearishOB = NULL; + bool hasNewBearishOB = Contains( + X_BEARISH_ORDERBLOCK_DETECTED, + consolidationPoiEvents // + ); if (hasNewBearishOB) { // - DrawX121SMCXOBSOrderBlock( - newBearishOB, - consolidationCycleHelper.mPOIDrawer // - ); + int hasOBs = consolidationState.HasBearishOrderBlocks(); + int count = consolidationState.CountBearishOrderBlocks(); + if (hasOBs) + { + newBearishOB = consolidationState.bearishOrderBlocks[count - 1]; + } + + // + hasNewBearishOB = newBearishOB != NULL && + newBearishOB.IsValid(); } + + // + bool isNewOBDetected = hasNewBullishOB || + hasNewBearishOB; + if (isNewOBDetected) + { + // + if (hasNewBullishOB) + { + // + DrawX121SMCXOBSOrderBlock( + newBullishOB, + drawer // + ); + } + + // + if (hasNewBearishOB) + { + // + DrawX121SMCXOBSOrderBlock( + newBearishOB, + drawer // + ); + } + } + + // + // Check Conditions ... + if (isNewOBDetected) + { + // + bool isSameOB = false; + + // + if (hasNewBullishOB && + hasYoungestBullishOB) + { + // + isSameOB = IsSame( + newBullishOB, + conditions.youngestBullishOB // + ); + } + + // + if (!isSameOB && + hasNewBearishOB && + hasYoungestBearishOB) + { + // + isSameOB = IsSame( + newBearishOB, + conditions.youngestBearishOB // + ); + } + + // + if (!isSameOB) + { + // + result = false; + conditions.Clean(); + mX121SMCXOBSObjects.Clear(); + } + } + + // } // @@ -1104,12 +1168,6 @@ bool DetectX121SMCXOBSSignalSetup( return result; } - // - DrawX121SMCXOBSConditions( - conditions, - visionCycleHelper.mPOIDrawer // - ); - // return false; @@ -1536,7 +1594,7 @@ bool DetectX121SMCXOBSGuards( bool result = false; // - string provider = ToString(X_121_SMC_PROVIDER_X); + string provider = ToString(X_121_SMC_PROVIDER_XOBS); // result = DetectX121SMCGuards( @@ -1855,3 +1913,165 @@ void DrawX121SMCXOBSConditions( } // +void DrawX121SMCXOBSPOIs( + XPOIState &state, + XCPOIDrawer *drawer // +) +{ + // + if (!state.IsValid() && + drawer == NULL && + !state.HasChild()) + { + return; + } + + // + bool hasSupplyZones = state.HasSupplyZones(); + int supplyZonesCount = state.CountSupplyZones(); + if (hasSupplyZones) + { + // + int idx = GetHighest(state.supplyZones); + if (IsValidIndex(idx)) + { + // + XCSupplyZone *iZone = state.supplyZones[idx]; + + // + iZone.To(TimeCurrent()); + + // + XCSupplyZoneObject *iObj; + bool isCreated = drawer.CreateSupplyZone( + iZone, + iObj // + ); + if (isCreated) + { + iObj.ZoneColor(clrRed); + mX121SMCXOBSObjects.Add(iObj); + } + } + + // + // for (int i = 0; i < supplyZonesCount; i++) + // { + // // + // XCSupplyZone *iZone = state.supplyZones[i]; + + // // + // iZone.To(TimeCurrent()); + + // // + // XCSupplyZoneObject *iObj; + // bool isCreated = drawer.CreateSupplyZone( + // iZone, + // iObj // + // ); + // if (isCreated) + // { + // iObj.ZoneColor(clrRed); + // mX121SMCXOBSObjects.Add(iObj); + // } + // } + } + + // + bool hasDemandZones = state.HasDemandZones(); + int demandZonesCount = state.CountDemandZones(); + if (hasDemandZones) + { + int idx = GetLowest(state.demandZones); + if (IsValidIndex(idx)) + { + // + XCDemandZone *iZone = state.demandZones[idx]; + + // + iZone.To(TimeCurrent()); + + // + XCDemandZoneObject *iObj; + bool isCreated = drawer.CreateDemandZone( + iZone, + iObj // + ); + if (isCreated) + { + // + iObj.ZoneColor(clrLime); + mX121SMCXOBSObjects.Add(iObj); + } + } + + // + // for (int i = 0; i < demandZonesCount; i++) + // { + // // + // XCDemandZone *iZone = state.demandZones[i]; + + // // + // iZone.To(TimeCurrent()); + + // // + // XCDemandZoneObject *iObj; + // bool isCreated = drawer.CreateDemandZone( + // iZone, + // iObj // + // ); + // if (isCreated) + // { + // // + // iObj.ZoneColor(clrLime); + // mX121SMCXOBSObjects.Add(iObj); + // } + // } + } + + // + // bool hasBullishOrderBlocks = state.HasBullishOrderBlocks(); + // int bullishOrderBlocksCount = state.CountBullishOrderBlocks(); + // if (hasBullishOrderBlocks) + // { + // // + // for (int i = 0; i < bullishOrderBlocksCount; i++) + // { + // // + // XCOrderBlock *iZone = state.bullishOrderBlocks[i]; + + // // + // iZone.To(TimeCurrent()); + + // // + // DrawX121SMCXOBSOrderBlock( + // iZone, + // drawer // + // ); + // } + // } + + // + // bool hasBearishOrderBlocks = state.HasBearishOrderBlocks(); + // int bearishOrderBlocksCount = state.CountBearishOrderBlocks(); + // if (hasBearishOrderBlocks) + // { + // // + // for (int i = 0; i < bearishOrderBlocksCount; i++) + // { + // // + // XCOrderBlock *iZone = state.bearishOrderBlocks[i]; + + // // + // iZone.To(TimeCurrent()); + + // // + // DrawX121SMCXOBSOrderBlock( + // iZone, + // drawer // + // ); + // } + // } +} + +// diff --git a/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 new file mode 100644 index 00000000..c7d9d16b --- /dev/null +++ b/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5 @@ -0,0 +1,2507 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XSupDemOBS +// Description: provide all Signalling functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +// #include "../../Libraries/x-trade.lib" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +enum ENUM_X121SMC_XSUPDEMOBS_PRIORITY +{ + X121SMC_XSUPDEMOBS_PRIORITY_NONE, + X121SMC_XSUPDEMOBS_PRIORITY_LOW, + X121SMC_XSUPDEMOBS_PRIORITY_REGULAR, + X121SMC_XSUPDEMOBS_PRIORITY_HIGH, +}; + +// +struct X121SMCXSupDemOBSWorkingZone +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + double zoneUpper; + double zoneLower; + + // + double quarter1; + double quarter2; + double quarter3; + + // + datetime from; + + // + X121SMCXSupDemOBSWorkingZone() + { + Clean(); + } + + // + void Clean() + { + // + upper = 0; + lower = 0; + quarter1 = 0; + quarter2 = 0; + quarter3 = 0; + zoneLower = 0; + zoneUpper = 0; + + // + from = NULL; + symbol = NULL; + period = NULL; + + // + ZeroMemory(this); + } + + // + bool IsValid() + { + // + bool result = false; + + // + result = + lower > 0 && + upper > 0 && + quarter1 > 0 && + quarter2 > 0 && + quarter3 > 0 && + upper > lower && + zoneLower > 0 && + zoneUpper > 0 && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + zoneUpper > upper && + zoneLower < lower; + + // + return result; + } + + // + bool DetectOveralTrend( + XOHCL &touchedBar, + ENUM_X_DIRECTION &trendDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + trendDir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + int fromBarIndex = iBarShift( + symbol, + period, + from // + ); + result = IsValidIndex(fromBarIndex); + if (!result) + { + return result; + } + + // + XOHCL nearestUpperTouchedBar; + XOHCL nearestLowerTouchedBar; + bool hasNearestUpperTouchedBar = false; + bool hasNearestLowerTouchedBar = false; + for (int i = barIndex; i < fromBarIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + period, + i // + ); + + // + hasNearestUpperTouchedBar = nearestUpperTouchedBar.IsValid(); + if (!hasNearestUpperTouchedBar) + { + // + bool isBarTouchedUpper = iBar.high > upper; + if (isBarTouchedUpper) + { + // + nearestUpperTouchedBar = iBar; + hasNearestUpperTouchedBar = true; + } + } + + // + hasNearestLowerTouchedBar = nearestLowerTouchedBar.IsValid(); + if (!hasNearestLowerTouchedBar) + { + // + bool isBarTouchedLower = iBar.low < lower; + if (isBarTouchedLower) + { + // + nearestLowerTouchedBar = iBar; + hasNearestLowerTouchedBar = true; + } + } + + // + if (hasNearestUpperTouchedBar && + hasNearestLowerTouchedBar) + { + break; + } + } + + // + result = hasNearestUpperTouchedBar || + hasNearestLowerTouchedBar; + if (result) + { + // + if (hasNearestUpperTouchedBar && + !hasNearestLowerTouchedBar) + { + // + trendDir = X_DIRECTION_BEARISH; + touchedBar = nearestUpperTouchedBar; + } + else if (!hasNearestUpperTouchedBar && + hasNearestLowerTouchedBar) + { + // + trendDir = X_DIRECTION_BULLISH; + touchedBar = nearestLowerTouchedBar; + } + else if (hasNearestUpperTouchedBar && + hasNearestLowerTouchedBar) + { + // + trendDir = + nearestUpperTouchedBar.time > nearestLowerTouchedBar.time + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + if (IsBullish(trendDir)) + { + touchedBar = nearestLowerTouchedBar; + } + else + { + touchedBar = nearestUpperTouchedBar; + } + } + } + + // + return result; + } + + // + bool IsDestroyed( + ENUM_X_DIRECTION &destroyedDir, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + destroyedDir = X_DIRECTION_NONE; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + XOHCL bar; + result = bar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + return result; + } + + // + bool isUpperBreaked = + bar.high > zoneUpper && + bar.close > zoneUpper; + + // + bool isLowerBreaked = + bar.low < zoneLower && + bar.close < zoneLower; + + // + result = isUpperBreaked || + isLowerBreaked; + if (result) + { + // + destroyedDir = + isUpperBreaked + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + // +}; + +// +// Definitions ... +struct X121SMCStrategyXSupDemOBSSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + // Working Area ... + + // + XCSupplyZone *visionHighestSupplyZone; + XCSupplyZone *consolidationHighestSupplyZone; + + // + XCDemandZone *visionLowestDemandZone; + XCDemandZone *consolidationLowestDemandZone; + + // + X121SMCXSupDemOBSWorkingZone workingZone; + + // + // Constructor ... + X121SMCStrategyXSupDemOBSSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + + // + ZeroMemory(this); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + pivot = 0; + point = 0; + + // + workingZone.Clean(); + + // + visionLowestDemandZone = NULL; + visionHighestSupplyZone = NULL; + consolidationLowestDemandZone = NULL; + consolidationHighestSupplyZone = NULL; + + // + ZeroMemory(visionLowestDemandZone); + ZeroMemory(visionHighestSupplyZone); + ZeroMemory(consolidationLowestDemandZone); + ZeroMemory(consolidationHighestSupplyZone); + } + + // + // + // + + // + bool HasVisionHighestSupplyZone() + { + // + return visionHighestSupplyZone != NULL && + visionHighestSupplyZone.IsValid(); + } + + // + bool HasConsolidationHighestSupplyZone() + { + // + return consolidationHighestSupplyZone != NULL && + consolidationHighestSupplyZone.IsValid(); + } + + // + bool HasVisionLowestDemandZone() + { + // + return visionLowestDemandZone != NULL && + visionLowestDemandZone.IsValid(); + } + + // + bool HasConsolidationLowestDemandZone() + { + // + return consolidationLowestDemandZone != NULL && + consolidationLowestDemandZone.IsValid(); + } + + // + // X_DIRECTION_BULLISH: + // Supply Zone of Consolidation Cycle appears inside + // Supply Zone of Vision Cycle ... + // + // X_DIRECTION_BEARISH: + // Demnad Zone of Consolidation Cycle appears inside + // Demnad Zone of Vision Cycle ... + bool HasHighImpactSide(ENUM_X_DIRECTION &highImpactDir) + { + // + bool result = false; + + // + highImpactDir = X_DIRECTION_NONE; + + // + bool isSupplyInside = false; + bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone(); + bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone(); + if (hasVisionHighestSupplyZone && + hasConsolidationHighestSupplyZone) + { + isSupplyInside = IsInside( + consolidationHighestSupplyZone, + visionHighestSupplyZone // + ); + } + + // + bool isDemandInside = false; + bool hasVisionLowestDemandZone = HasVisionLowestDemandZone(); + bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone(); + if (hasVisionLowestDemandZone && + hasConsolidationLowestDemandZone) + { + // + isDemandInside = IsInside( + consolidationLowestDemandZone, + visionLowestDemandZone // + ); + } + + // + result = isSupplyInside || + isDemandInside; + if (result) + { + // + highImpactDir = + isSupplyInside + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + // + datetime ExtractNearestFromDate() + { + // + datetime result = NULL; + + // + bool hasVisionLowestDemandZone = HasVisionLowestDemandZone(); + bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone(); + bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone(); + bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone(); + if (hasVisionLowestDemandZone) + { + // + bool canSet = + !IsValid(result) + ? true + : visionLowestDemandZone.From() > result; + if (canSet) + { + result = visionLowestDemandZone.From(); + } + } + if (hasVisionHighestSupplyZone) + { + // + bool canSet = + !IsValid(result) + ? true + : visionHighestSupplyZone.From() > result; + if (canSet) + { + result = visionHighestSupplyZone.From(); + } + } + if (hasConsolidationLowestDemandZone) + { + // + bool canSet = + !IsValid(result) + ? true + : consolidationLowestDemandZone.From() > result; + if (canSet) + { + result = consolidationLowestDemandZone.From(); + } + } + if (hasConsolidationHighestSupplyZone) + { + // + bool canSet = + !IsValid(result) + ? true + : consolidationHighestSupplyZone.From() > result; + if (canSet) + { + result = consolidationHighestSupplyZone.From(); + } + } + + // + return result; + } + + // + datetime ExtractFarestFromDate() + { + // + datetime result = NULL; + + // + bool hasVisionLowestDemandZone = HasVisionLowestDemandZone(); + bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone(); + bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone(); + bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone(); + if (hasVisionLowestDemandZone) + { + // + bool canSet = + !IsValid(result) + ? true + : visionLowestDemandZone.From() < result; + if (canSet) + { + result = visionLowestDemandZone.From(); + } + } + if (hasVisionHighestSupplyZone) + { + // + bool canSet = + !IsValid(result) + ? true + : visionHighestSupplyZone.From() < result; + if (canSet) + { + result = visionHighestSupplyZone.From(); + } + } + if (hasConsolidationLowestDemandZone) + { + // + bool canSet = + !IsValid(result) + ? true + : consolidationLowestDemandZone.From() < result; + if (canSet) + { + result = consolidationLowestDemandZone.From(); + } + } + if (hasConsolidationHighestSupplyZone) + { + // + bool canSet = + !IsValid(result) + ? true + : consolidationHighestSupplyZone.From() < result; + if (canSet) + { + result = consolidationHighestSupplyZone.From(); + } + } + + // + return result; + } + + // + // Working Zone is an Area which + // we decide to trade inside it ... + bool ExtractWorkingZone( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = workingZone.IsValid(); + if (result) + { + return result; + } + + // + XOHCL bar; + result = bar.Init( + symbol, + forPeriod, + barIndex // + ); + + // + double upper = 0; + double lower = 0; + double quarter1 = 0; + double quarter2 = 0; + double quarter3 = 0; + double zoneUpper = 0; + double zoneLower = 0; + + // + ENUM_X_DIRECTION highImpactDir; + bool hasHighImpactSide = HasHighImpactSide(highImpactDir); + result = hasHighImpactSide; + if (!result) + { + return result; + } + + // + // Select Newest Zone From time ... + datetime from = ExtractFarestFromDate(); + + // + bool isSupplyHighImpacted = IsBullish(highImpactDir); + bool isDemandHighImpacted = IsBearish(highImpactDir); + + // + if (isSupplyHighImpacted) + { + // + upper = visionHighestSupplyZone.Lower(); + if (HasConsolidationLowestDemandZone()) + { + lower = consolidationLowestDemandZone.Upper(); + } + else + { + lower = visionLowestDemandZone.Upper(); + } + + // + zoneUpper = visionHighestSupplyZone.Upper(); + if (HasConsolidationLowestDemandZone()) + { + zoneLower = consolidationLowestDemandZone.Lower(); + } + else + { + zoneLower = visionLowestDemandZone.Lower(); + } + } + else + { + // + if (HasConsolidationHighestSupplyZone()) + { + upper = consolidationHighestSupplyZone.Lower(); + } + else + { + upper = visionHighestSupplyZone.Lower(); + } + lower = visionLowestDemandZone.Upper(); + + // + if (HasConsolidationHighestSupplyZone()) + { + zoneUpper = consolidationHighestSupplyZone.Upper(); + } + else + { + zoneUpper = visionHighestSupplyZone.Upper(); + } + zoneLower = visionLowestDemandZone.Lower(); + } + + // + result = + lower > 0 && + upper > 0 && + upper > lower && + zoneUpper > 0 && + zoneLower > 0 && + zoneUpper > upper && + zoneLower < lower; + if (!result) + { + return result; + } + + // + double range = (upper - lower) / 100; + double quarter = range * 25; + + // + quarter1 = upper - (1 * quarter); + quarter2 = upper - (2 * quarter); + quarter3 = upper - (3 * quarter); + + // + workingZone.from = from; + workingZone.upper = upper; + workingZone.lower = lower; + workingZone.symbol = symbol; + workingZone.period = period; + workingZone.quarter1 = quarter1; + workingZone.quarter2 = quarter2; + workingZone.quarter3 = quarter3; + workingZone.zoneUpper = zoneUpper; + workingZone.zoneLower = zoneLower; + + // + result = workingZone.IsValid(); + + // + return result; + } + + // + bool IsWorkingZoneDestroyed( + ENUM_X_DIRECTION &destroyedDir, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + destroyedDir = X_DIRECTION_NONE; + + // + result = workingZone.IsValid(); + if (!result) + { + return result; + } + + // + result = workingZone.IsDestroyed( + destroyedDir, + barIndex, + forPeriod // + ); + + // + return result; + } + + // + bool DetectOveralTrend( + XOHCL &touchedBar, + ENUM_X_DIRECTION &trendDir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + trendDir = X_DIRECTION_NONE; + + // + result = workingZone.IsValid(); + if (!result) + { + return result; + } + + // + result = workingZone.DetectOveralTrend( + touchedBar, + trendDir, + barIndex // + ); + + // + return result; + } + + // + void UpdateTo(datetime value) + { + // + value = NormalizeTime(value); + + // + bool hasVisionLowestDemandZone = HasVisionLowestDemandZone(); + if (hasVisionLowestDemandZone) + { + visionLowestDemandZone.To(value); + } + + bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone(); + if (hasVisionHighestSupplyZone) + { + visionHighestSupplyZone.To(value); + } + + bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone(); + if (hasConsolidationLowestDemandZone) + { + consolidationLowestDemandZone.To(value); + } + + bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone(); + if (hasConsolidationHighestSupplyZone) + { + consolidationHighestSupplyZone.To(value); + } + } + + // +}; + +// +// Signaller Data Sources ... +X121SMCStrategyXSupDemOBSSignalConditions mX121SMCXSupDemOBSConditions; +X121SMCStrategyXSupDemOBSSignalConditions mX121SMCXSupDemOBSConditionsCollection[]; +CArrayObj mX121SMCXSupDemOBSObjects; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXSupDemOBSSignalSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXSupDemOBSSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int resetAfterUnActedZoneInMinutes = 120 + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions triggerXConditions = triggerConditions.x121Conditions; + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions verificationXConditions = verificationConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // Setup Conditions ... + + // + XOHCL decisionZBar; + XOHCL decisionCBar; + XOHCL decisionPBar; + double decisionCBarBullishZoneChechValue = 0; + double decisionCBarBearishZoneChechValue = 0; + + // + result = decisionZBar.Init( + decisionState.symbol, + decisionState.period, + 0 // + ); + if (!result) + { + return result; + } + + // + result = decisionZBar + .GetPreviousBar(decisionCBar); + if (!result) + { + return result; + } + + // + result = decisionCBar + .GetPreviousBar(decisionPBar); + if (!result) + { + return result; + } + + // + decisionCBarBullishZoneChechValue = decisionCBar + .GetZoneCheckValue(X_DIRECTION_BULLISH); + decisionCBarBearishZoneChechValue = decisionCBar + .GetZoneCheckValue(X_DIRECTION_BEARISH); + + // + // 1- Detect Valid Working Area ... + + // + bool hasVisionHighestSupplyZone = conditions.HasVisionHighestSupplyZone(); + bool hasConsolidationHighestSupplyZone = conditions.HasConsolidationHighestSupplyZone(); + + // + bool hasVisionLowestDemandZone = conditions.HasVisionLowestDemandZone(); + bool hasConsolidationLowestDemandZone = conditions.HasConsolidationLowestDemandZone(); + + // + bool hasWorkingZone = conditions.workingZone.IsValid(); + + // + bool isDestroyed = false; + ENUM_X_DIRECTION destroyedDir; + + // + XOHCL trendStartBar; + ENUM_X_DIRECTION trendDir; + bool hasTrend = false; + bool hasBullishTrend = false; + bool hasBearishTrend = false; + + // + if (!hasVisionHighestSupplyZone) + { + // + int hasZones = visionState.HasSupplyZones(); + int zonesCount = visionState.HasSupplyZones(); + + // + if (hasZones) + { + // + int idx = GetHighest(visionState.supplyZones); + hasVisionHighestSupplyZone = IsValidIndex(idx); + if (hasVisionHighestSupplyZone) + { + // + // Validate Zone ... + XCSupplyZone *zone = visionState.supplyZones[idx]; + bool isBelow = IsBelow( + decisionCBarBearishZoneChechValue, + zone // + ); + if (isBelow) + { + conditions.visionHighestSupplyZone = zone; + } + } + } + + // + hasVisionHighestSupplyZone = conditions.HasVisionHighestSupplyZone(); + } + + // + if (!hasVisionLowestDemandZone) + { + // + int hasZones = visionState.HasDemandZones(); + int zonesCount = visionState.HasDemandZones(); + + // + if (hasZones) + { + // + int idx = GetLowest(visionState.demandZones); + hasVisionLowestDemandZone = IsValidIndex(idx); + if (hasVisionLowestDemandZone) + { + // + // Validate Zone ... + XCDemandZone *zone = visionState.demandZones[idx]; + bool isAbove = IsAbove( + decisionCBarBullishZoneChechValue, + zone // + ); + if (isAbove) + { + conditions.visionLowestDemandZone = zone; + } + } + } + + // + hasVisionLowestDemandZone = conditions.HasVisionLowestDemandZone(); + } + + // + if (!hasConsolidationHighestSupplyZone) + { + // + int hasZones = consolidationState.HasSupplyZones(); + int zonesCount = consolidationState.HasSupplyZones(); + + // + if (hasZones) + { + // + int idx = GetHighest(consolidationState.supplyZones); + hasConsolidationHighestSupplyZone = IsValidIndex(idx); + if (hasConsolidationHighestSupplyZone) + { + // + // Validate Zone ... + XCSupplyZone *zone = consolidationState.supplyZones[idx]; + bool isBelow = IsBelow( + decisionCBarBearishZoneChechValue, + zone // + ); + if (isBelow) + { + // + if (conditions.workingZone.IsValid()) + { + // + result = false; + conditions.Clean(); + RemoveX121SMCXSupDemOBSDraws(); + return result; + } + + // + conditions.consolidationHighestSupplyZone = zone; + } + } + } + + // + hasConsolidationHighestSupplyZone = conditions.HasConsolidationHighestSupplyZone(); + } + + // + if (!hasConsolidationLowestDemandZone) + { + // + int hasZones = consolidationState.HasDemandZones(); + int zonesCount = consolidationState.HasDemandZones(); + + // + if (hasZones) + { + // + int idx = GetLowest(consolidationState.demandZones); + hasConsolidationLowestDemandZone = IsValidIndex(idx); + if (hasConsolidationLowestDemandZone) + { + // + // Validate Zone ... + XCDemandZone *zone = consolidationState.demandZones[idx]; + bool isAbove = IsAbove( + decisionCBarBullishZoneChechValue, + zone // + ); + if (isAbove) + { + // + if (conditions.workingZone.IsValid()) + { + // + result = false; + conditions.Clean(); + RemoveX121SMCXSupDemOBSDraws(); + return result; + } + + // + conditions.consolidationLowestDemandZone = zone; + } + } + } + + // + hasConsolidationLowestDemandZone = conditions.HasConsolidationLowestDemandZone(); + } + + // + // 2- Detect Working Zone ... + if (!hasWorkingZone) + { + hasWorkingZone = conditions.ExtractWorkingZone(); + } + + // + conditions.UpdateTo(cTime); + + // + DrawX121SMCXSupDemOBSConditions( + conditions, + visionCycleHelper.mPOIDrawer // + ); + + // + // Check Working Zone Destroy ... + isDestroyed = conditions.IsWorkingZoneDestroyed( + destroyedDir, // Direction ... + 0, // Bar Index ... + decisionState.period // Period ... + ); + if (isDestroyed) + { + // + result = false; + conditions.Clean(); + RemoveX121SMCXSupDemOBSDraws(); + return result; + } + + // + // 2- Detect Market Trend Based On Nearest Zone Hunting ... + hasTrend = conditions.DetectOveralTrend( + trendStartBar, + trendDir, + 0 // + ); + hasBullishTrend = IsBullish(trendDir); + hasBearishTrend = IsBearish(trendDir); + + // + result = hasTrend; + if (!result) + { + return result; + } + + // + // 3- Checking Price Inside Valid Quarters Based on Trend ... + + // + // in Bullish Trend: + // ----------------------------- + // - if Price Under Lower: HIGH; + // - if Price Under Quarter 3 and Above Lower: REGULAR; + // - if Price Under Quarter 2 and Above Quarter 3: LOW; + // - if Price Above Quarter 2: NONE; + + // + // in Bearish Trend: + // ----------------------------- + // - if Price Above Upper: HIGH; + // - if Price Above Quarter 1 and Below Upper: REGULAR; + // - if Price Above Quarter 2 and Below Quarter 1: LOW; + // - if Price Below Quarter 2: NONE; + + // + ENUM_X121SMC_XSUPDEMOBS_PRIORITY bullishPriority; + ENUM_X121SMC_XSUPDEMOBS_PRIORITY bearishPriority; + + // + bool isPriceAboveUpper = + // + decisionZBar.high < conditions.workingZone.zoneUpper && + decisionCBar.high < conditions.workingZone.zoneUpper && + // + decisionZBar.low > conditions.workingZone.upper && + decisionCBar.low > conditions.workingZone.upper + // + ; + if (isPriceAboveUpper) + { + // + bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; + bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_HIGH; + } + + // + bool isPriceInQuarterOne = + // + decisionZBar.high < conditions.workingZone.upper && + decisionCBar.high < conditions.workingZone.upper && + // + decisionZBar.low > conditions.workingZone.quarter1 && + decisionCBar.low > conditions.workingZone.quarter1 + // + ; + if (isPriceInQuarterOne) + { + // + bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; + bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_REGULAR; + } + + // + bool isPriceInQuarterTwo = + // + decisionZBar.high < conditions.workingZone.quarter1 && + decisionCBar.high < conditions.workingZone.quarter1 && + // + decisionZBar.low > conditions.workingZone.quarter2 && + decisionCBar.low > conditions.workingZone.quarter2 + // + ; + if (isPriceInQuarterTwo) + { + // + bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; + bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_LOW; + } + + // + bool isPriceInQuarterThree = + // + decisionZBar.high < conditions.workingZone.quarter2 && + decisionCBar.high < conditions.workingZone.quarter2 && + // + decisionZBar.low > conditions.workingZone.quarter3 && + decisionCBar.low > conditions.workingZone.quarter3 + // + ; + if (isPriceInQuarterThree) + { + // + bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_LOW; + bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; + } + + // + bool isPriceInQuarterFour = + // + decisionZBar.high < conditions.workingZone.quarter3 && + decisionCBar.high < conditions.workingZone.quarter3 && + // + decisionZBar.low > conditions.workingZone.lower && + decisionCBar.low > conditions.workingZone.lower + // + ; + if (isPriceInQuarterFour) + { + // + bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_REGULAR; + bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; + } + + // + bool isPriceBelowLower = + // + decisionZBar.high < conditions.workingZone.lower && + decisionCBar.high < conditions.workingZone.lower && + // + decisionZBar.low > conditions.workingZone.zoneLower && + decisionCBar.low > conditions.workingZone.zoneLower + // + ; + if (isPriceBelowLower) + { + // + bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_HIGH; + bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE; + } + + // + bool lookingForLong = bullishPeriority != X121SMC_XSUPDEMOBS_PRIORITY_NONE; + bool lookingForShort = bearishPeriority != X121SMC_XSUPDEMOBS_PRIORITY_NONE; + + // + result = lookingForLong || + lookingForShort; + if (result) + { + return result; + } + + // + // 4- Detect Order Blocks in Direction of Trend ... + + // + // In Direction of Trend Order Blocks ... + + // + return false; + + // + double upper = 0; + double lower = 0; + + // + // + // + + // + // Summarize Conditions ... + + // + bool isCondition1Bullish = + // + false + // + ; + + // + bool isCondition1Bearish = + // + false + // + ; + + // + bool hasCondition1 = isCondition1Bullish || + isCondition1Bearish; + if (hasCondition1) + { + // + ENUM_X_DIRECTION pzDir = + isCondition1Bullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + double point = GetEntry( + conditions.symbol, + pzDir // + ); + + // + double longPivot = lower; // triggerXConditions.valesBuffer[1]; + double shortPivot = upper; // triggerXConditions.peaksBuffer[1]; + + // + // Manipulate Conditions Point ... + + // + conditions.point = + isCondition1Bullish + ? shortPivot + : longPivot; + + // + // Manipulate Conditions Pivot ... + + // + conditions.pivot = + isCondition1Bullish + ? longPivot + : shortPivot; + } + + // + // + // + + // + isBullish = + // + isCondition1Bullish + // + ; + + // + isBearish = + // + isCondition1Bearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Detect PriceOB Lifetime Bars ... + + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Cleanup Arrays ... + Clean(triggerPoiEvents); + Clean(triggerCycleEvents); + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + Clean(verificationPoiEvents); + Clean(verificationCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + Clean(visionPoiEvents); + Clean(visionCycleEvents); + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXSupDemOBSSignalTrigger( + // + X121SMCStrategyXSupDemOBSSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = decisionCycleHelper.GetBar( + zBar, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = decisionCycleHelper.GetBar( + cBar, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = decisionCycleHelper.GetBar( + pBar, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + // Slopes ... + + // + bool isRsiSlopeBullish = decisionXConditions.isRsiSlopeBullish; + bool isStrSlopeBullish = decisionXConditions.isStrSlopeBullish; + bool isAtrUpperSlopeBullish = decisionXConditions.isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish = decisionXConditions.isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish = decisionXConditions.isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish = decisionXConditions.isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish = decisionXConditions.isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish = decisionXConditions.isRsiSlopeBearish; + bool isStrSlopeBearish = decisionXConditions.isStrSlopeBearish; + bool isAtrUpperSlopeBearish = decisionXConditions.isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish = decisionXConditions.isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish = decisionXConditions.isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish = decisionXConditions.isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish = decisionXConditions.isVwapSlowSlopeBearish; + + // + bool isSlopesBullish = + isRsiSlopeBullish && + isStrSlopeBullish && + isAtrUpperSlopeBullish && + isAtrLowerSlopeBullish && + isVwapFastSlopeBullish && + isVwapMidSlopeBullish && + isVwapSlowSlopeBullish; + + // + bool isSlopesBearish = + isRsiSlopeBearish && + isStrSlopeBearish && + isAtrUpperSlopeBearish && + isAtrLowerSlopeBearish && + isVwapFastSlopeBearish && + isVwapMidSlopeBearish && + isVwapSlowSlopeBearish; + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish && + isPointBreaked && + isSlopesBullish + // + ; + + // + isBearish = + // + isBearish && + isPointBreaked && + isSlopesBearish + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + double iAtr = decisionConditions.x121Conditions.atrBuffer[1]; + iAtr *= 1.5; + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - iAtr + : slsMax + iAtr; + double risk = MathAbs(entry - sl); + + // + // Filling Conditions Props ... + conditions.sl = sl; + // conditions.target = target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup Arrays ... + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + return result; +} + +// +// Detect Guards ... +bool DetectX121SMCXSupDemOBSGuards( + X121SMCGuard &guards[], + const XPosition &positions[], + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper // +) +{ + // + bool result = false; + + // + string provider = ToString(X_121_SMC_PROVIDER_XSUPDEMOBS); + + // + result = DetectX121SMCGuards( + provider, + guards, + positions, + triggerCycleHelper, + decisionCycleHelper, + analyseCycleHelper, + verificationCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + true, // CloseOnTPNear Guard ... + true, // CloseLongsOnBearishTrend Guard ... + true, // CloseShortsOnBullishTrend Guard ... + true, // CloseAllWeekend Guard ... + true, // PartialCloseOnTrendChange Guard ... + true, // TrailStop Guard ... + true, // TrailTarget Guard ... + true // Hedge Guard ... + // + ); + + // + return result; +} + +// +// Add Conditions to Conditions Collection ... +int AddX121SMCXSupDemOBSConditionsIfNotExists( + X121SMCStrategyXSupDemOBSSignalConditions &item, + X121SMCStrategyXSupDemOBSSignalConditions &items[], + int maxAllowed = 10 // +) +{ + // + int result = 0; + + // + bool isSetuped = IsValid(item.setupTime) && + HasDirection(item.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(items); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXSupDemOBSSignalConditions tmpItems[]; + Copy( + items, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(item.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXSupDemOBSSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = item.dir == iItem.dir && + item.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + items, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + item, + items // + ); + + // + // Remove Olds ... + CleanupArray( + items, + maxAllowed // + ); + + // + result = ArraySize(items); + + // + return result; +} + +// +// Draws ... +// + +// +void RemoveX121SMCXSupDemOBSDraws() +{ + mX121SMCXSupDemOBSObjects.Clear(); +} + +// +void DrawX121SMCXSupDemOBSOrderBlock( + XCOrderBlock *ob, + XCPOIDrawer *drawer // +) +{ + // + if (ob == NULL || + drawer == NULL) + { + return; + } + + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + + // + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + color forColor = IsBullish(forDir) + ? bullishColor + : bearishColor; + + // + // Draw Order Block ... + XCBaseObject *obj; + bool isCreated = drawer.CreateOrderBlock( + ob, + obj // + ); + if (isCreated) + { + mX121SMCXSupDemOBSObjects.Add(obj); + } + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = ob.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (isStarted) + { + // + datetime to = startedBar.time + (PeriodSeconds(startedBar.period)); + + // + XCOHCLObject *obj; + bool isCreated = drawer.CreateBar( + startedBar, + obj, + to // + ); + if (isCreated) + { + // + obj.BodyColor(clrYellow); + obj.HighShadowColor(clrYellow); + obj.LowShadowColor(clrYellow); + + // + obj.BodyStyle(STYLE_SOLID); + obj.HighShadowStyle(STYLE_SOLID); + obj.LowShadowStyle(STYLE_SOLID); + + // + mX121SMCXSupDemOBSObjects.Add(obj); + } + + // + string startVLineName = "Start_" + ob.GetTag(); + + // + CChartObjectVLine *startVLine; + startVLine = new CChartObjectVLine(); + isCreated = startVLine.Create( + chartID, + startVLineName, + subWindow, + startedBar.time // + ); + if (isCreated) + { + // + startVLine.Color(forColor); + + // + mX121SMCXSupDemOBSObjects.Add(startVLine); + } + } +} + +// +void DrawX121SMCXSupDemOBSConditions( + X121SMCStrategyXSupDemOBSSignalConditions &conditions, + XCPOIDrawer *drawer, + bool forceClean = false // +) +{ + // + if (drawer == NULL) + { + return; + } + + // + if (forceClean) + { + mX121SMCXSupDemOBSObjects.Clear(); + } + + // + bool isCreated = false; + + // + bool hasVisionHighestSupplyZone = conditions.HasVisionHighestSupplyZone(); + if (hasVisionHighestSupplyZone) + { + // + XCSupplyZoneObject *ivhSupObj; + isCreated = drawer.CreateSupplyZone( + conditions.visionHighestSupplyZone, + ivhSupObj // + ); + if (isCreated) + { + mX121SMCXSupDemOBSObjects.Add(ivhSupObj); + } + } + + // + bool hasConsolidationHighestSupplyZone = conditions.HasConsolidationHighestSupplyZone(); + if (hasConsolidationHighestSupplyZone) + { + // + XCSupplyZoneObject *ichSupObj; + isCreated = drawer.CreateSupplyZone( + conditions.consolidationHighestSupplyZone, + ichSupObj // + ); + if (isCreated) + { + mX121SMCXSupDemOBSObjects.Add(ichSupObj); + } + } + + // + bool hasVisionLowestDemandZone = conditions.HasVisionLowestDemandZone(); + if (hasVisionLowestDemandZone) + { + // + XCDemandZoneObject *ivlSupObj; + isCreated = drawer.CreateDemandZone( + conditions.visionLowestDemandZone, + ivlSupObj // + ); + if (isCreated) + { + mX121SMCXSupDemOBSObjects.Add(ivlSupObj); + } + } + + // + bool hasConsolidationLowestDemandZone = conditions.HasConsolidationLowestDemandZone(); + if (hasConsolidationLowestDemandZone) + { + // + XCDemandZoneObject *iclSupObj; + isCreated = drawer.CreateDemandZone( + conditions.consolidationLowestDemandZone, + iclSupObj // + ); + if (isCreated) + { + mX121SMCXSupDemOBSObjects.Add(iclSupObj); + } + } + + // + bool hasWorkingZone = conditions.workingZone.IsValid(); + if (hasWorkingZone) + { + // + string zonePrefix = "X121_WZ_" + conditions.workingZone.symbol + "_" + ToString(conditions.workingZone.period); + string fromStr = ToFormatString(conditions.workingZone.from); + string fromMD5 = ToMD5(fromStr); + + // + string upperName = zonePrefix + "_Upper_" + fromMD5; + string lowerName = zonePrefix + "_Lower_" + fromMD5; + string zoneUpperName = zonePrefix + "_ZoneUpper_" + fromMD5; + string zoneLowerName = zonePrefix + "_ZoneLower_" + fromMD5; + + // + string q1Name = zonePrefix + "_Q1_" + fromMD5; + string q2Name = zonePrefix + "_Q2_" + fromMD5; + string q3Name = zonePrefix + "_Q3_" + fromMD5; + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + bool isCreated = false; + + // + // Lower ... + CChartObjectHLine *lowerHLine; + lowerHLine = new CChartObjectHLine(); + isCreated = lowerHLine.Create( + chartID, + lowerName, + subWindow, + conditions.workingZone.lower // + ); + if (isCreated) + { + // + lowerHLine.Color(clrLime); + mX121SMCXSupDemOBSObjects.Add(lowerHLine); + } + + // + CChartObjectHLine *upperHLine; + upperHLine = new CChartObjectHLine(); + isCreated = upperHLine.Create( + chartID, + upperName, + subWindow, + conditions.workingZone.upper // + ); + if (isCreated) + { + // + upperHLine.Color(clrLime); + mX121SMCXSupDemOBSObjects.Add(upperHLine); + } + + // + CChartObjectHLine *zoneLowerHLine; + zoneLowerHLine = new CChartObjectHLine(); + isCreated = zoneLowerHLine.Create( + chartID, + zoneLowerName, + subWindow, + conditions.workingZone.zoneLower // + ); + if (isCreated) + { + // + zoneLowerHLine.Color(clrRed); + mX121SMCXSupDemOBSObjects.Add(zoneLowerHLine); + } + + // + CChartObjectHLine *zoneUpperHLine; + zoneUpperHLine = new CChartObjectHLine(); + isCreated = zoneUpperHLine.Create( + chartID, + zoneUpperName, + subWindow, + conditions.workingZone.zoneUpper // + ); + if (isCreated) + { + // + zoneUpperHLine.Color(clrRed); + mX121SMCXSupDemOBSObjects.Add(zoneUpperHLine); + } + + // + CChartObjectHLine *quarter1HLine; + quarter1HLine = new CChartObjectHLine(); + isCreated = quarter1HLine.Create( + chartID, + q1Name, + subWindow, + conditions.workingZone.quarter1 // + ); + if (isCreated) + { + // + quarter1HLine.Color(clrYellow); + mX121SMCXSupDemOBSObjects.Add(quarter1HLine); + } + + // + CChartObjectHLine *quarter2HLine; + quarter2HLine = new CChartObjectHLine(); + isCreated = quarter2HLine.Create( + chartID, + q2Name, + subWindow, + conditions.workingZone.quarter2 // + ); + if (isCreated) + { + // + quarter2HLine.Color(clrYellow); + mX121SMCXSupDemOBSObjects.Add(quarter2HLine); + } + + // + CChartObjectHLine *quarter3HLine; + quarter3HLine = new CChartObjectHLine(); + isCreated = quarter3HLine.Create( + chartID, + q3Name, + subWindow, + conditions.workingZone.quarter3 // + ); + if (isCreated) + { + // + quarter3HLine.Color(clrYellow); + mX121SMCXSupDemOBSObjects.Add(quarter3HLine); + } + + // // + // XCTicksZone *tZone; + // tZone = new XCTicksZone(); + + // // + // XOHCL fromBar; + // bool isInitedFrom = fromBar.Init( + // conditions.workingZone.symbol, + // conditions.workingZone.period, + // conditions.workingZone.from // + // ); + + // // + // XOHCL toBar; + // bool isInitedTo = toBar.Init( + // conditions.workingZone.symbol, + // conditions.workingZone.period, + // 1 // + // ); + + // // + // if (isInitedTo && + // isInitedFrom) + // { + // // + // bool isZoneInited = tZone.Init( + // fromBar, + // toBar // + // ); + // if (isZoneInited) + // { + // // + // XCTicksZoneObject *tZoneObj; + // bool isCreated = drawer.CreateTicksZone( + // tZone, + // tZoneObj // + // ); + // if (isCreated) + // { + // mX121SMCXSupDemOBSObjects.Add(tZoneObj); + // } + // } + // } + } +} + +// +// +// + +// \ No newline at end of file diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 245db577..3fca7063 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -27,8 +27,8 @@ #include "../Classes/x-121.smc.market.cycle.helper.class.mq5" // -#include "../Signals/x-121.smc.x.signal.lib.mq5" #include "../Signals/x-121.smc.xobs.signal.lib.mq5" +#include "../Signals/x-121.smc.xsupdemobs.signal.lib.mq5" // // Definitions ... @@ -42,8 +42,8 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy public: // // Props ... - bool useXSignal; bool useXOBSSignal; + bool useXSupDemOBSSignal; // // Constructor(s) ... @@ -104,8 +104,8 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy void Destroy() override { // - Clean(mXConditionsCollection); Clean(mX121SMCXOBSConditionsCollection); + Clean(mX121SMCXSupDemOBSConditionsCollection); // ZeroMemory(mTriggerCycleHelper); @@ -200,17 +200,8 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy bool hasSignal = false; // - bool hasXSignal = false; bool hasXOBSSignal = false; - - // - // X Signal ... - if (useXSignal && !hasSignal) - { - // - hasXSignal = DetectXSignal(conditions); - hasSignal = hasXSignal; - } + bool hasXSupDemOBSSignal = false; // // XOBS Signal ... @@ -221,6 +212,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy hasSignal = hasXOBSSignal; } + // + // XSupDemOBS Signal ... + if (useXSupDemOBSSignal && !hasSignal) + { + // + hasXSupDemOBSSignal = DetectXSupDemOBSSignal(conditions); + hasSignal = hasXSupDemOBSSignal; + } + // result = hasSignal; if (!result) @@ -377,11 +377,11 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy } // - // X Guard Detection ... - if (useXSignal) + // XOBS Guard Detection ... + if (useXOBSSignal) { // - bool hasGuard = DetectX121SMCXGuards( + bool hasGuard = DetectX121SMCXOBSGuards( guards, positions, mTriggerCycleHelper, @@ -394,11 +394,11 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy } // - // XOBS Guard Detection ... - if (useXOBSSignal) + // XSupDemOBS Guard Detection ... + if (useXSupDemOBSSignal) { // - bool hasGuard = DetectX121SMCXOBSGuards( + bool hasGuard = DetectX121SMCXSupDemOBSGuards( guards, positions, mTriggerCycleHelper, @@ -448,241 +448,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // Signalling Functions ... - // - // X Signal ... - bool DetectXSignal( - X121SMCStrategyConditions &conditions // - ) - { - // - bool result = false; - - // - bool isBullish = false; - bool isBearish = false; - - // - int zIndex = 0; - int cIndex = zIndex + 1; - int pIndex = cIndex + 1; - int ppIndex = pIndex + 1; - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - XOHCL zBar; - result = zBar.Init( - symbol, - period, - zIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL cBar; - result = cBar.Init( - symbol, - period, - cIndex // - ); - if (!result) - { - return result; - } - - // - XOHCL pBar; - result = pBar.Init( - symbol, - period, - pIndex // - ); - if (!result) - { - return result; - } - - // - double cLL = cBar.FindLowest(7, MODE_LOW); - double cHH = cBar.FindHighest(7, MODE_HIGH); - - // - datetime cTime = TimeCurrent(); - - // - ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_X; - string providerStr = ToString(provider); - - // - // Detect Setup Conditions ... - datetime setupTime = mXConditions.setupTime; - bool isSetuped = mXConditions.IsSetuped(); - ENUM_X_DIRECTION setupDir = mXConditions.dir; - if (!isSetuped) - { - // - // Detect Signal Setup ... - isSetuped = DetectX121SMCXSignalSetup( - symbol, - period, - mXConditions, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - setupDir = mXConditions.dir; - setupTime = mXConditions.setupTime; - - // // - // bool hasPivot = mXConditions.pivotZone.IsValid(); - // if (hasPivot) - // { - // // - // XCBaseObject *drawnObjects[]; - // int drawnCount = DrawX121SMCXConditions( - // mXConditions, - // drawnObjects, - // mPOIDrawer // - // ); - // if (IsValidSize(drawnCount)) - // { - // AddObjectsIfNotExists(drawnObjects); - // } - // } - - // - if (isSetuped) - { - // - int items = AddX121SMCXConditionsIfNotExists( - mXConditions, - mXConditionsCollection // - ); - - // - mXConditions.Clean(); - } - } - - // - int conditionsCount = ArraySize(mXConditionsCollection); - result = IsValidSize(conditionsCount); - if (!result) - { - return result; - } - - // - // Looking For Conditions ... - int selectedIndex = 0; - X121SMCStrategyXSignalConditions mTmpConditions[]; - Copy( - mXConditionsCollection, - mTmpConditions // - ); - X121SMCStrategyXSignalConditions mConditions; - for (int i = 0; i < conditionsCount; i++) - { - // - // Check Triggers ... - bool canTrigger = mTmpConditions[i].CanTrigger(); - datetime triggerTime = mTmpConditions[i].triggerTime; - if (!canTrigger) - { - // - // Detect Signal Trigger ... - canTrigger = DetectX121SMCXSignalTrigger( - mTmpConditions[i], - symbol, - period, - mTriggerCycleHelper, - mDecisionCycleHelper, - mAnalyseCycleHelper, - mVerificationCycleHelper, - mConsolidationCycleHelper, - mVisionCycleHelper // - ); - - // - result = canTrigger; - if (!result) - { - // - bool isISetuped = mTmpConditions[i].IsSetuped(); - if (!isISetuped) - { - // - ArrayRemove( - mXConditionsCollection, - i, - 1 // - ); - } - continue; - } - - // - triggerTime = mTmpConditions[i].triggerTime; - } - - // - if (canTrigger) - { - // - selectedIndex = i; - mConditions = mTmpConditions[i]; - break; - } - } - - // - result = IsValid(mConditions.setupTime) && - HasDirection(mConditions.dir); - if (!result) - { - return result; - } - - // - // Remove Selected Index from Main Collection ... - ArrayRemove( - mXConditionsCollection, - selectedIndex, - 1 // - ); - - // - // Check Signal Direction ... - isBullish = IsBullish(mConditions.dir); - isBearish = IsBearish(mConditions.dir); - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - // Issues Signal on Conditions ... - conditions.sl = mConditions.sl; - conditions.provider = providerStr; - conditions.signalDir = mConditions.dir; - conditions.target = mConditions.target; - - // - return result; - } - // // XOBS Signal ... bool DetectXOBSSignal( @@ -901,6 +666,225 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } + // + // XSupDemOBS Signal ... + bool DetectXSupDemOBSSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double cLL = cBar.FindLowest(7, MODE_LOW); + double cHH = cBar.FindHighest(7, MODE_HIGH); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XSUPDEMOBS; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mX121SMCXSupDemOBSConditions.setupTime; + bool isSetuped = mX121SMCXSupDemOBSConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mX121SMCXSupDemOBSConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXSupDemOBSSignalSetup( + symbol, + period, + mX121SMCXSupDemOBSConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mX121SMCXSupDemOBSConditions.dir; + setupTime = mX121SMCXSupDemOBSConditions.setupTime; + + // + if (isSetuped) + { + // + int items = AddX121SMCXSupDemOBSConditionsIfNotExists( + mX121SMCXSupDemOBSConditions, + mX121SMCXSupDemOBSConditionsCollection // + ); + + // + mX121SMCXSupDemOBSConditions.Clean(); + } + } + + // + int conditionsCount = ArraySize(mX121SMCXSupDemOBSConditionsCollection); + result = IsValidSize(conditionsCount); + if (!result) + { + return result; + } + + // + // Looking For Conditions ... + int selectedIndex = 0; + X121SMCStrategyXSupDemOBSSignalConditions mTmpConditions[]; + Copy( + mX121SMCXSupDemOBSConditionsCollection, + mTmpConditions // + ); + X121SMCStrategyXSupDemOBSSignalConditions mConditions; + for (int i = 0; i < conditionsCount; i++) + { + // + // Check Triggers ... + bool canTrigger = mTmpConditions[i].CanTrigger(); + datetime triggerTime = mTmpConditions[i].triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXSupDemOBSSignalTrigger( + mTmpConditions[i], + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + // + bool isISetuped = mTmpConditions[i].IsSetuped(); + if (!isISetuped) + { + // + ArrayRemove( + mX121SMCXSupDemOBSConditionsCollection, + i, + 1 // + ); + } + continue; + } + + // + triggerTime = mTmpConditions[i].triggerTime; + } + + // + if (canTrigger) + { + // + selectedIndex = i; + mConditions = mTmpConditions[i]; + break; + } + } + + // + result = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!result) + { + return result; + } + + // + // Remove Selected Index from Main Collection ... + ArrayRemove( + mX121SMCXSupDemOBSConditionsCollection, + selectedIndex, + 1 // + ); + + // + // Check Signal Direction ... + isBullish = IsBullish(mConditions.dir); + isBearish = IsBearish(mConditions.dir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.sl = mConditions.sl; + conditions.provider = providerStr; + conditions.signalDir = mConditions.dir; + conditions.target = mConditions.target; + + // + return result; + } + + // // Private ... private: @@ -916,8 +900,8 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy void InitialHelpers() { // - useXSignal = false; - useXOBSSignal = true; + useXOBSSignal = false; + useXSupDemOBSSignal = true; // string symbol = GetSymbol();