/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 X121 SMC Signal Class // ------------------------------------------------- // Name: XOBS // 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" // struct XOBTest { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // XCOrderBlock *ob; XCFVG *fvgs[]; // datetime fvgBreakedAt; datetime rewardedAt; // double reward; // // Constructor ... XOBTest() { Clean(); } // // Tools ... // void Clean() { // ob = NULL; symbol = NULL; period = NULL; rewardedAt = NULL; fvgBreakedAt = NULL; // reward = 0; // Clean(fvgs); } // bool HasOB() { return ob != NULL && ob.IsValid(); } // int CountFVGs() { return ArraySize(fvgs); } // bool HasFVGs() { return IsValidSize(CountFVGs()); } }; // // Definitions ... struct X121SMCStrategyXOBSSignalConditions { // // 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; // // Extwnsion ... XOBTest obTests[]; // // Constructor ... X121SMCStrategyXOBSSignalConditions() { 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; // Clean(obTests); } // }; // // Signaller Data Sources ... X121SMCStrategyXOBSSignalConditions mXOBSConditions; X121SMCStrategyXOBSSignalConditions mXOBSConditionsCollection[]; // // Extension Functions ... // // Detect Setup Conditions ... bool DetectX121SMCXOBSSignalSetup( string _symbol, ENUM_TIMEFRAMES _period, // X121SMCStrategyXOBSSignalConditions &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; // XC121SMCCycleHelper *barCycle = triggerCycleHelper; // XOHCL zBar; result = barCycle.GetBar( zBar, zIndex // ); if (!result) { return result; } // XOHCL cBar; result = barCycle.GetBar( cBar, cIndex // ); if (!result) { return result; } // XOHCL pBar; result = barCycle.GetBar( pBar, pIndex // ); if (!result) { return result; } // double ask = GetAsk(symbol); double bid = GetBid(symbol); datetime cTime = TimeCurrent(); double points = GetPoints(symbol); // int swingLoopback = 7; double ll = cBar.FindLowest(swingLoopback, MODE_LOW); double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); double ll50 = cBar.FindLowest(50, MODE_LOW); double hh50 = cBar.FindHighest(50, MODE_HIGH); double llDown = cBar.FindLowesttDown(swingLoopback); double hhUp = cBar.FindHighestUp(swingLoopback); // // Cycles Conditions ... // // Trigger ... ENUM_XPOI_EVENTS triggerPoiEvents[]; ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; X121SMCCycleConditions triggerConditions; result = triggerCycleHelper.GetConditions( triggerCycleEvents, triggerPoiEvents, triggerConditions, zIndex, loopback // ); if (!result) { return result; } // // Decision ... ENUM_XPOI_EVENTS decisionPoiEvents[]; ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; X121SMCCycleConditions decisionConditions; result = decisionCycleHelper.GetConditions( decisionCycleEvents, decisionPoiEvents, decisionConditions, zIndex, loopback // ); if (!result) { return result; } // // Analyse ... ENUM_XPOI_EVENTS analysePoiEvents[]; ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; X121SMCCycleConditions analyseConditions; result = analyseCycleHelper.GetConditions( analyseCycleEvents, analysePoiEvents, analyseConditions, zIndex, loopback // ); if (!result) { return result; } // // Verification ... ENUM_XPOI_EVENTS verificationPoiEvents[]; ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; X121SMCCycleConditions verificationConditions; result = verificationCycleHelper.GetConditions( verificationCycleEvents, verificationPoiEvents, verificationConditions, zIndex, loopback // ); if (!result) { return result; } // // Consolidation ... ENUM_XPOI_EVENTS consolidationPoiEvents[]; ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; X121SMCCycleConditions consolidationConditions; result = consolidationCycleHelper.GetConditions( consolidationCycleEvents, consolidationPoiEvents, consolidationConditions, zIndex, loopback // ); if (!result) { return result; } // // Vision ... ENUM_XPOI_EVENTS visionPoiEvents[]; ENUM_X_CYCLE_EVENTS visionCycleEvents[]; X121SMCCycleConditions visionConditions; result = visionCycleHelper.GetConditions( visionCycleEvents, visionPoiEvents, visionConditions, zIndex, loopback // ); if (!result) { return result; } // // Cycles POI States ... XPOIState triggerState = triggerConditions.state; XPOIState decisionState = decisionConditions.state; XPOIState analyseState = analyseConditions.state; XPOIState verificationState = verificationConditions.state; XPOIState consolidationState = consolidationConditions.state; XPOIState visionState = visionConditions.state; // // 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 ... // // Detect Bar State ... // // PinBar ... ENUM_X_DIRECTION cBarPinDir; bool isCBarPin = decisionCycleHelper .mBarAnalyser .IsPinBar( cBar, cBarPinDir, 1 // ); bool isCBarBullishPin = isCBarPin && IsBullish(cBarPinDir); bool isCBarBearishPin = isCBarPin && IsBearish(cBarPinDir); // // Engulf ... ENUM_X_DIRECTION cBarEngulfDir; bool isCBarEngulfed = decisionCycleHelper .mBarAnalyser .IsEngulfBar( cBar, cBarEngulfDir, 0 // Extended ... ); bool isCBarBullishEngulfed = isCBarEngulfed && IsBullish(cBarEngulfDir); bool isCBarBearishEngulfed = isCBarEngulfed && IsBearish(cBarEngulfDir); // // Momentum ... ENUM_X_DIRECTION cBarMomentumDir; bool isCBarMomentum = decisionCycleHelper .mBarAnalyser .IsMomentumBar( cBar, cBarMomentumDir, 0 // Extended ... ); bool isCBarBullishMomentum = isCBarMomentum && IsBullish(cBarMomentumDir); bool isCBarBearishMomentum = isCBarMomentum && IsBearish(cBarMomentumDir); // // Reject ... ENUM_X_DIRECTION cBarRejectDir; bool isCBarRejected = decisionCycleHelper .mBarAnalyser .IsRejectionBar( cBar, cBarRejectDir, 0 // Extended ... ); bool isCBarBullishRejected = isCBarRejected && IsBullish(cBarRejectDir); bool isCBarBearishRejected = isCBarRejected && IsBearish(cBarRejectDir); // // Pull Back ... ENUM_X_DIRECTION cBarPullbackDir; bool isCBarPullbacked = decisionCycleHelper .mBarAnalyser .HasPullBack( cBarPullbackDir, cBar // ); bool isCBarBullishPullbacked = isCBarPullbacked && IsBullish(cBarPullbackDir); bool isCBarBearishPullbacked = isCBarPullbacked && IsBearish(cBarPullbackDir); // // HH/LL Break ... // bool isCBarBreaksUpHH = IsBarBreak( hh, X_DIRECTION_BULLISH, cBar // ); // bool isCBarBreaksDownLL = IsBarBreak( hh, X_DIRECTION_BEARISH, cBar // ); // // Bars Pattern and Power and Pressures ... // bool hasCBarBullishPattern = decisionCycleHelper .mBarAnalyser .HasBullishPattern( cBar, 2 // ); // bool hasCBarBearishPattern = decisionCycleHelper .mBarAnalyser .HasBearishPattern( cBar, 2 // ); // bool isCBarHasBullishPower = decisionCycleHelper .mBarAnalyser .HasBullishPower( cBar, 2 // ); // bool isCBarHasBearishPower = decisionCycleHelper .mBarAnalyser .HasBearishPower( cBar, 2 // ); // bool isCBarHasBullishPressure = decisionCycleHelper .mBarAnalyser .HasBullishPressure( cBar, 2 // ); // bool isCBarHasBearishPressure = decisionCycleHelper .mBarAnalyser .HasBearishPressure( cBar, 2 // ); // // Bar Checking Summary ... // // Bullish ... bool isCBarBullishFormed = // ( // hasCBarBullishPattern && isCBarHasBullishPower && isCBarHasBullishPressure // ) // || // ( // isCBarBullishPin || isCBarBreaksUpHH || isCBarBullishEngulfed || isCBarBullishMomentum || isCBarBullishRejected // ) // ; // // Bearish ... bool isCBarBearishFormed = // ( // hasCBarBearishPattern && isCBarHasBearishPower && isCBarHasBearishPressure // ) // || // ( // isCBarBearishPin || isCBarBreaksDownLL || isCBarBearishEngulfed || isCBarBearishMomentum || isCBarBearishRejected // ) // ; // // Detect Order Flow ... // // Test Market For Order Flow ... int obTestsCount = ArraySize(conditions.obTests); bool isOBTested = obTestsCount == 2; if (!isOBTested) { // bool hasTest = ReTestMarket( conditions.obTests, consolidationState, analyseState, decisionState, visionCycleHelper.mPOIDrawer // ); } // // TODO: 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 DetectX121SMCXOBSSignalTrigger( // X121SMCStrategyXOBSSignalConditions &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 DetectX121SMCXOBSGuards( 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_X); // 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 AddX121SMCXOBSConditionsIfNotExists( X121SMCStrategyXOBSSignalConditions &item, X121SMCStrategyXOBSSignalConditions &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 ... X121SMCStrategyXOBSSignalConditions tmpItems[]; Copy( items, tmpItems // ); // // Prese Item Data ... bool isBullish = IsBullish(item.dir); // for (int i = 0; i < count; i++) { // X121SMCStrategyXOBSSignalConditions 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; } // // // /** * Retest Market ... * * @param test: XOBTest instance Reference, Represet Result Test ... * @param tests: XOBTest instance Reference Collection, Represet Founded Tests till now ... * @param htfState: XPOIState instance Reference ... * @param mtfState: XPOIState instance Reference ... * @param ttfState: XPOIState instance Reference ... * * @return ( bool ) */ bool ReTestMarket( XOBTest &tests[], XPOIState &htfState, XPOIState &mtfState, XPOIState &ttfState, // // XCPOIDrawer *drawer // ) { // bool result = false; // Clean(tests); // datetime cTime = TimeCurrent(); // // Detect Order Blocks ... // HTF ... // // Bullish OBs ... XCOrderBlock *bullOBs[]; bool hasYoungestBullOB = false; XOHCL youngestBullOBStartedBar; bool isYoungestBullOBStarted = false; ENUM_X_DIRECTION youngestBullOBStartedDir; XCOrderBlock *youngestBullOB = NULL; int bullOBsCount = ExtractUnActivatedOBs( htfState.bullishOrderBlocks, bullOBs // ); // bool isBullOBsPassed = bullOBsCount >= 1; if (isBullOBsPassed) { // XBoxZone boxes[]; int boxesCount = ToBox( bullOBs, boxes // ); int youngestBoxIDX = GetYoungest(boxes); hasYoungestBullOB = IsValidIndex(youngestBoxIDX); if (hasYoungestBullOB) { // youngestBullOB = bullOBs[youngestBoxIDX]; // isYoungestBullOBStarted = youngestBullOB.IsStarted( X_DIRECTION_BULLISH, youngestBullOBStartedBar, youngestBullOBStartedDir // ); } } // // Bearish OBs ... XCOrderBlock *bearOBs[]; bool hasYoungestBearOB = false; XOHCL youngestBearOBStartedBar; bool isYoungestBearOBStarted = false; ENUM_X_DIRECTION youngestBearOBStartedDir; XCOrderBlock *youngestBearOB = NULL; int bearOBsCount = ExtractUnActivatedOBs( htfState.bearishOrderBlocks, bearOBs // ); // bool isBearOBsPassed = bearOBsCount >= 1; if (isBearOBsPassed) { // XBoxZone boxes[]; int boxesCount = ToBox( bearOBs, boxes // ); int youngestBoxIDX = GetYoungest(boxes); hasYoungestBearOB = IsValidIndex(youngestBoxIDX); if (hasYoungestBearOB) { // youngestBearOB = bearOBs[youngestBoxIDX]; // isYoungestBearOBStarted = youngestBearOB.IsStarted( X_DIRECTION_BEARISH, youngestBearOBStartedBar, youngestBearOBStartedDir // ); } } // bool hasYoungestOB = hasYoungestBullOB || hasYoungestBearOB; result = hasYoungestOB; if (!result) { return result; } // // Since Youngest Order Blocks is UnActivated ... // here we found Order Flow ... // Order Blocks in consequences of Youngest OB which they // Breaked ... // // Bullish OB ... int breakedBullOBsCount = 0; XCOrderBlock *breakedBullOBs[]; bool hasBreakedBullOBs = false; if (hasYoungestBullOB) { // bool hasOBs = htfState.HasBullishOrderBlocks(); int count = htfState.CountBullishOrderBlocks(); if (hasOBs) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iOB = htfState.bullishOrderBlocks[i]; ENUM_X_DIRECTION forDir = iOB.IsBullish() ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // // Check iOB isn't Same as Youngest OB ... bool isSameAsYoungest = IsSame( youngestBullOB, iOB // ); if (isSameAsYoungest) { continue; } // // Bullish Order Blocks must appears Below // Youngest One ... bool isBelow = IsBelow( iOB, youngestBullOB // ); if (!isBelow) { continue; } // XOHCL iBreakerBar; ENUM_X_DIRECTION iBreakerDir; bool isIBreaked = iOB.IsBreaked( forDir, iBreakerBar, iBreakerDir // ); if (!isIBreaked) { continue; } // // Bullish Order Block Must Valid ... // Means Price Must be On Top of it after its breake out ... // bool isValid = false; int fromIndex = iBreakerBar.Index() - 1; for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( iOB.GetSymbol(), iOB.GetPeriod(), i // ); if (!isInited) { continue; } // isValid = iBar.low > iOB.Upper(); if (!isValid) { break; } } if (!isValid) { continue; } // // Set OB's To Time to Breaker Bar's Time ... iOB.To(iBreakerBar.time); // // Check Order Block Not Exists ... int iOBIDX = -1; bool isIOBExists = FindIndex( iOBIDX, iOB, breakedBullOBs // ); if (isIOBExists) { continue; } // Add( iOB, breakedBullOBs // ); // } } // breakedBullOBsCount = ArraySize(breakedBullOBs); hasBreakedBullOBs = IsValidSize(breakedBullOBsCount); } // // Bearish OB ... int breakedBearOBsCount = 0; XCOrderBlock *breakedBearOBs[]; bool hasBreakedBearOBs = false; if (hasYoungestBearOB) { // bool hasOBs = htfState.HasBearishOrderBlocks(); int count = htfState.CountBearishOrderBlocks(); if (hasOBs) { // for (int i = 0; i < count; i++) { // XCOrderBlock *iOB = htfState.bearishOrderBlocks[i]; ENUM_X_DIRECTION forDir = iOB.IsBullish() ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // // Check iOB isn't Same as Youngest OB ... bool isSameAsYoungest = IsSame( youngestBearOB, iOB // ); if (isSameAsYoungest) { continue; } // // Bearish Order Blocks must appears Above // Youngest One ... bool isAbove = IsAbove( iOB, youngestBearOB // ); if (!isAbove) { continue; } // XOHCL iBreakerBar; ENUM_X_DIRECTION iBreakerDir; bool isIBreaked = iOB.IsBreaked( forDir, iBreakerBar, iBreakerDir // ); if (!isIBreaked) { continue; } // // Bearish Order Block Must Valid ... // Means Price Must be On Bottom of it after its breake out ... // bool isValid = false; int fromIndex = iBreakerBar.Index() - 1; for (int i = fromIndex; i >= 0; i--) { // XOHCL iBar; bool isInited = iBar.Init( iOB.GetSymbol(), iOB.GetPeriod(), i // ); if (!isInited) { continue; } // isValid = iBar.high < iOB.Lower(); if (!isValid) { break; } } if (!isValid) { continue; } // // Set OB's To Time to Breaker Bar's Time ... iOB.To(iBreakerBar.time); // // Check Order Block Not Exists ... int iOBIDX = -1; bool isIOBExists = FindIndex( iOBIDX, iOB, breakedBearOBs // ); if (isIOBExists) { continue; } // Add( iOB, breakedBearOBs // ); // } } // breakedBearOBsCount = ArraySize(breakedBearOBs); hasBreakedBearOBs = IsValidSize(breakedBearOBsCount); } // bool hasBreakedOBs = hasBreakedBullOBs || hasBreakedBearOBs; result = hasBreakedOBs; if (!result) { return result; } // // Update Youngest OB To time ... // if (hasYoungestBullOB) { youngestBullOB.To(cTime); } // if (hasYoungestBearOB) { youngestBearOB.To(cTime); } // // Now we Have to Validate Breaked Order Blocks Count in additions to Youngest OB directions ... // bool hasBullishOrderFlow = // hasYoungestBullOB && isYoungestBullOBStarted && // breakedBullOBsCount >= 2 // ; // bool hasBearishOrderFlow = // hasYoungestBearOB && isYoungestBearOBStarted && // breakedBearOBsCount >= 2 // ; // ENUM_X_DIRECTION orderFlowDir = X_DIRECTION_NONE; bool hasOrderFlow = hasBullishOrderFlow || hasBearishOrderFlow; if (hasOrderFlow) { // orderFlowDir = hasBullishOrderFlow ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; } result = hasOrderFlow; if (!result) { return result; } // // here we have try to detect Fair Value Gaps in Related to OrderFlow ... if (hasBullishOrderFlow) { // for (int i = 0; i < breakedBullOBsCount; i++) { // XCOrderBlock *iOB = breakedBullOBs[i]; // XOHCL iOBBreakerBar; ENUM_X_DIRECTION iOBBreakerDir; bool isIOBBreaked = iOB.IsBreaked( X_DIRECTION_BULLISH, iOBBreakerBar, iOBBreakerDir // ); if (!isIOBBreaked) { continue; } // int fvgsCount = mtfState.CountBullishFairValueGaps(); bool hasFVGs = mtfState.HasBullishFairValueGaps(); if (!hasFVGs) { break; } // XCFVG *iOBFVGs[]; for (int j = 0; j < fvgsCount; j++) { // XCFVG *jFVG = mtfState.bullishFairValueGaps[j]; // bool isFromPassed = jFVG.From() >= iOB.From(); if (!isFromPassed) { continue; } // bool isAbovePassed = IsAboveDiff( jFVG, iOB, true // Ignore Inside FVG ... ); if (!isAbovePassed) { continue; } // jFVG.To(iOB.To()); // Add( jFVG, iOBFVGs // ); } // // Check Order Block Has FVG or Not ... int iOBFVGsCount = ArraySize(iOBFVGs); bool iOBHasFVG = IsValidSize(iOBFVGsCount); if (iOBHasFVG) { // XOBTest iTest; // iTest.ob = iOB; iTest.symbol = iOB.GetSymbol(); iTest.period = iOB.GetPeriod(); // Copy( iOBFVGs, iTest.fvgs // ); // AddRef( iTest, tests // ); // iTest.Clean(); } } } else if (hasBearishOrderFlow) { // for (int i = 0; i < breakedBearOBsCount; i++) { // XCOrderBlock *iOB = breakedBearOBs[i]; // XOHCL iOBBreakerBar; ENUM_X_DIRECTION iOBBreakerDir; bool isIOBBreaked = iOB.IsBreaked( X_DIRECTION_BULLISH, iOBBreakerBar, iOBBreakerDir // ); if (!isIOBBreaked) { continue; } // int fvgsCount = mtfState.CountBearishFairValueGaps(); bool hasFVGs = mtfState.HasBearishFairValueGaps(); if (!hasFVGs) { break; } // XCFVG *iOBFVGs[]; for (int j = 0; j < fvgsCount; j++) { // XCFVG *jFVG = mtfState.bearishFairValueGaps[j]; // bool isFromPassed = jFVG.From() >= iOB.From(); if (!isFromPassed) { continue; } // bool isBelowPassed = IsBelowDiff( jFVG, iOB, true // Ignore Inside FVG ... ); if (!isBelowPassed) { continue; } // jFVG.To(iOB.To()); // Add( jFVG, iOBFVGs // ); } // // Check Order Block Has FVG or Not ... int iOBFVGsCount = ArraySize(iOBFVGs); bool iOBHasFVG = IsValidSize(iOBFVGsCount); if (iOBHasFVG) { // XOBTest iTest; // iTest.ob = iOB; iTest.symbol = iOB.GetSymbol(); iTest.period = iOB.GetPeriod(); // Copy( iOBFVGs, iTest.fvgs // ); // AddRef( iTest, tests // ); // iTest.Clean(); } } } // // Now we Have to Works On Tests Collection ... // int testsCount = ArraySize(tests); bool hasTests = testsCount >= 2; result = hasTests; if (!result) { return result; } // // DRAW ... // // XCBaseObject *drawnObjects[]; // if (hasYoungestBullOB) { // XCBullishOrderBlockObject *iObj; bool isCreated = drawer .CreateBullishOrderBlock( youngestBullOB, iObj // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // if (hasYoungestBearOB) { // XCBearishOrderBlockObject *iObj; bool isCreated = drawer .CreateBearishOrderBlock( youngestBearOB, iObj // ); // if (isCreated) { // Add( (XCBaseObject *)iObj, drawnObjects // ); } } // // // // Draw Breaked Bullish OrderBlocks ... // if (hasBreakedBullOBs) // { // // // for (int i = 0; i < breakedBullOBsCount; i++) // { // // // XCOrderBlock *iOB = breakedBullOBs[i]; // // iOB.To(cTime); // // // XCBullishOrderBlockObject *iObj; // bool isCreated = drawer // .CreateBullishOrderBlock( // iOB, // iObj // // ); // // // if (isCreated) // { // // // Add( // (XCBaseObject *)iObj, // drawnObjects // // ); // } // } // } // // // // Draw Breaked Bearish OrderBlocks ... // if (hasBreakedBearOBs) // { // // // for (int i = 0; i < breakedBearOBsCount; i++) // { // // // XCOrderBlock *iOB = breakedBearOBs[i]; // // iOB.To(cTime); // // // XCBearishOrderBlockObject *iObj; // bool isCreated = drawer // .CreateBearishOrderBlock( // iOB, // iObj // // ); // // // if (isCreated) // { // // // Add( // (XCBaseObject *)iObj, // drawnObjects // // ); // } // } // } // // Draw Tests ... if (hasTests) { // for (int i = 0; i < testsCount; i++) { // XOBTest iTest = tests[i]; // bool hasOB = iTest.HasOB(); if (hasOB) { // bool isBullish = iTest.ob.IsBullish(); // XCBaseObject *obObj; bool isCreated = drawer .CreateOrderBlock( iTest.ob, obObj // ); if (isCreated) { // Add( obObj, drawnObjects // ); } } // bool hasFVGs = iTest.HasFVGs(); int fvgsCount = iTest.CountFVGs(); for (int j = 0; j < fvgsCount; j++) { // XCFVG *jFVG = iTest.fvgs[j]; jFVG.To(iTest.ob.To()); // XCBaseObject *fvgObj; bool isCreated = drawer .CreateFairValueGap( jFVG, fvgObj // ); if (isCreated) { // Add( fvgObj, drawnObjects // ); } } } } // // END DRAW ... // // Print("OBs Passed ..."); // return result; } /** * Extract UnActivated Order Blocks ... * * @return ( int ) */ int ExtractUnActivatedOBs( XCOrderBlock *&source[], XCOrderBlock *&obs[] // ) { // int result = 0; // Clean(obs); // int count = ArraySize(source); bool hasOB = IsValidSize(count); if (!hasOB) { return result; } // for (int i = 0; i < count; i++) { // bool isBullish = source[i].IsBullish(); ENUM_X_DIRECTION forDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // // // // XOHCL activatedBar; ENUM_X_DIRECTION activatedDir; bool isActivated = source[i].IsActivated( forDir, activatedBar, activatedDir // ); if (!isActivated) { // Add( source[i], obs // ); } } // result = ArraySize(obs); // return result; } //