diff --git a/Documents/BKP/xsupdem/x-121.smc.xwz.signal.class.mq5 b/Documents/BKP/xsupdem/x-121.smc.xwz.signal.class.mq5 new file mode 100644 index 00000000..757942e0 --- /dev/null +++ b/Documents/BKP/xsupdem/x-121.smc.xwz.signal.class.mq5 @@ -0,0 +1,2996 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XWZ +// Description: provide all Signalling functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Libraries/x-121.smc.guard.lib.mq5" +#include "../Libraries/x-121.smc.lib.mq5" +#include "./x-121.smc.xwz.signal.lib.mq5" + +// +// Definition ... +class XCX121SMCXWZSignalDetector : public XCBase +{ + // + public: + // + // Props ... + X121SMCStrategyXWZSignalConditions mConditions; + X121SMCStrategyXWZSignalConditions mConditionsCollection[]; + + // + // Constructor(s) ... + XCX121SMCXWZSignalDetector() + { + Init(); + } + + // + // Deconstructor ... + ~XCX121SMCXWZSignalDetector() + { + DeInit(); + } + + // + // + // + + // + // Detect Setup Conditions ... + bool DetectSignalSetup( + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // + ) + { + // + bool result = false; + + // + // Validate Cycle Helpers ... + result = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + 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; + + // + mConditions.symbol = symbol; + mConditions.period = period; + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + double target = 0; + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + mConditions.Clean(); + + // + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.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) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + result = decisionZBar + .GetPreviousBar(decisionCBar); + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + result = decisionCBar + .GetPreviousBar(decisionPBar); + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + decisionCBarBullishZoneChechValue = decisionCBar + .GetZoneCheckValue(X_DIRECTION_BULLISH); + decisionCBarBearishZoneChechValue = decisionCBar + .GetZoneCheckValue(X_DIRECTION_BEARISH); + + // + // Check Working Zone ... + bool hasWorkingZone = mConditions.HasWorkingZone(); + if (!hasWorkingZone) + { + // + hasWorkingZone = mConditions.ExtractWorkingZone( + visionState, + consolidationState, + analyseState, + zIndex // + ); + } + + // + result = hasWorkingZone; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // + return result; + } + + // + mConditions.UpdateTo(cTime); + + // + // Check Working Zone still Alive ... + ENUM_X_DIRECTION destroyedDir = X_DIRECTION_NONE; + bool isWorkingZoneDestroyed = mConditions + .IsWorkingZoneDestroyed( + destroyedDir, + zIndex, + decisionState.period // + ); + if (isWorkingZoneDestroyed) + { + RemoveWorkingZoneDraws(); + } + + // + result = !isWorkingZoneDestroyed; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // + return result; + } + + // + // Detecting Trend ... + ENUM_X_DIRECTION trend; + bool hasTrend = mConditions.DetectTrend( + trend, + period // + ); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + result = hasTrend; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // + return result; + } + + // + // Detect Start Zones ... + bool hasStartZone = mConditions.HasStartZone(); + if (!hasStartZone) + { + // + hasStartZone = mConditions.DetectStartZone( + trend, + analyseState, + decisionCycleHelper // + ); + } + + // + mConditions.UpdateTo(cTime); + + // + // Detect Condition Priority ... + ENUM_X121SMC_XWZ_PRIORITY bullishPriority; + ENUM_X121SMC_XWZ_PRIORITY bearishPriority; + mConditions.DetectPriority( + bullishPriority, + bearishPriority // + ); + + // + bool canLookupLong = bullishPriority != X121SMC_XWZ_PRIORITY_NONE && + bullishPriority != X121SMC_XWZ_PRIORITY_WEAK; + bool canLookupShort = bearishPriority != X121SMC_XWZ_PRIORITY_NONE && + bearishPriority != X121SMC_XWZ_PRIORITY_WEAK; + bool isPriorityPassed = + hasBullishTrend + ? canLookupLong + : hasBearishTrend + ? canLookupShort + : false; + + // + double pivot = 0; + double point = 0; + bool hasCondition = false; + ENUM_X_DIRECTION conditionsDir = X_DIRECTION_NONE; + + // + // Detect Start Zone Based Conditions ... + if (hasStartZone) + { + // + DrawConditions( + mConditions, + visionCycleHelper.mPOIDrawer // + ); + + // + // Detect Start Zone Conditions ... + hasCondition = mConditions + .startZone + .HasCondition( + decisionState, + zIndex, + NULL // period // + ); + conditionsDir = mConditions + .startZone + .GetDirection(); + if (hasCondition) + { + // + XBoxZone startZoneBox; + bool hasBox = mConditions.startZone.AsBox(startZoneBox); + if (hasBox) + { + // + bool isBullish = IsBullish(conditionsDir); + + // + pivot = + isBullish + ? startZoneBox.lower + : startZoneBox.upper; + + // + point = + isBullish + ? startZoneBox.upper + : startZoneBox.lower; + } + } + } + + // + RemoveWorkingZoneDraws(); + DrawWorkingZone(mConditions, visionCycleHelper.mPOIDrawer); + + // + // Detect Supply and Deman Zone Based Conditions ... + if (!hasCondition) + { + // + bool isPriceInsideSupplyZone = + bearishPriority == X121SMC_XWZ_PRIORITY_STRONG_HIGH; + + // + bool isPriceInsideDemandZone = + bullishPriority == X121SMC_XWZ_PRIORITY_STRONG_HIGH; + + // + bool isPriceInsideSupDem = isPriceInsideSupplyZone || + isPriceInsideDemandZone; + if (isPriceInsideSupDem) + { + // + hasCondition = mConditions.HasWorkingZoneConditions( + conditionsDir, + decisionState // + ); + + // + if (hasCondition) + { + // + if (IsBullish(conditionsDir)) + { + // + pivot = mConditions.demandZone.Lower(); + point = mConditions.demandZone.Upper(); + } + else if (IsBearish(conditionsDir)) + { + // + pivot = mConditions.supplyZone.Upper(); + point = mConditions.supplyZone.Lower(); + } + } + } + } + + // + isBullish = IsBullish(conditionsDir); + isBearish = IsBearish(conditionsDir); + + // + double reward; + double amountPercent; + ENUM_X121SMC_XWZ_PRIORITY priority = + isBullish + ? bullishPriority + : bearishPriority; + bool hasRewardAmount = CalculateRiskReward( + priority, + reward, + amountPercent // + ); + + // + bool hasLastBullishConsolidationZone = false; + bool hasLastBearishConsolidationZone = false; + bool hasPrevBullishConsolidationZone = false; + bool hasPrevBearishConsolidationZone = false; + XConsolidationZone lastBullishConsolidationZone; + XConsolidationZone lastBearishConsolidationZone; + XConsolidationZone prevBullishConsolidationZone; + XConsolidationZone prevBearishConsolidationZone; + bool hasConsolidationZones = decisionCycleHelper.HasConsolidationZones(); + if (hasConsolidationZones) + { + // + int cZCount = 0; + XConsolidationZone tmp[]; + + // + cZCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BULLISH, + tmp // + ); + if (IsValidSize(cZCount)) + { + // + lastBullishConsolidationZone = tmp[cZCount - 1]; + if (cZCount >= 2) + { + prevBullishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + cZCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BEARISH, + tmp // + ); + if (IsValidSize(cZCount)) + { + // + lastBearishConsolidationZone = tmp[cZCount - 1]; + if (cZCount >= 2) + { + prevBearishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + + // + hasLastBullishConsolidationZone = lastBullishConsolidationZone.IsValid(); + hasLastBearishConsolidationZone = lastBearishConsolidationZone.IsValid(); + hasPrevBullishConsolidationZone = prevBullishConsolidationZone.IsValid(); + hasPrevBearishConsolidationZone = prevBearishConsolidationZone.IsValid(); + } + + // + RemoveDraws(); + + // + if (hasLastBullishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + lastBullishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + if (hasLastBearishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + lastBearishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + if (hasPrevBullishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + prevBullishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + if (hasPrevBearishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + prevBearishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + bool isConsolidationZonePassed = + isBullish + ? (point > 0 && + hasPrevBullishConsolidationZone && + point >= prevBullishConsolidationZone.upper) + : (point > 0 && + hasPrevBearishConsolidationZone && + point <= prevBearishConsolidationZone.lower); + + // + result = hasCondition && + hasRewardAmount && + isPriorityPassed && + trend == conditionsDir && + isConsolidationZonePassed; + if (!result) + { + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + + // + mConditions.Clean(); + + // + return result; + } + + // + // Apply Traget ... + switch (priority) + { + // + case X121SMC_XWZ_PRIORITY_STRONG_HIGH: + // + target = + isBullish + ? mConditions.workingZone.quarter3 + : mConditions.workingZone.quarter1; + break; + + // + case X121SMC_XWZ_PRIORITY_HIGH: + // + target = + isBullish + ? mConditions.workingZone.quarter3 + : mConditions.workingZone.quarter1; + break; + + // + case X121SMC_XWZ_PRIORITY_REGULAR: + // + target = + isBullish + ? mConditions.workingZone.quarter2 + : mConditions.workingZone.quarter2; + break; + + // + case X121SMC_XWZ_PRIORITY_LOW: + // + target = + isBullish + ? mConditions.workingZone.quarter1 + : mConditions.workingZone.quarter3; + break; + + // + default: + target = 0; + break; + } + + // + mConditions.pivot = pivot; + mConditions.point = point; + mConditions.reward = reward; + mConditions.target = target; + mConditions.setupTime = cTime; + mConditions.priority = priority; + mConditions.dir = conditionsDir; + mConditions.amountPercent = amountPercent; + + // + mConditions.UpdateTo(cTime); + + // + DrawConditions( + mConditions, + visionCycleHelper.mPOIDrawer // + ); + + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(decisionPoiEvents); + Clean(visionCycleEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionZBar.Clean(); + decisionCBar.Clean(); + decisionPBar.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + consolidationState.Clean(); + decisionConditions.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + + // + return result; + } + + // + // Detect Trigger Conditions ... + bool DetectSignalTrigger( + // + X121SMCStrategyXWZSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 + // + ) + { + // + bool result = false; + + // + result = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + if (!result) + { + return result; + } + + // + 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) + { + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + + // + // Trigger Conditions ... + + // + double point = conditions.point; + bool isPointBreaked = IsBarBreak( + point, + setupDir, + cBar // + ); + + // + // Summary ... + + // + isBullish = + // + isBullish + // && + // isPointBreaked + // + ; + + // + isBearish = + // + isBearish + // && + // isPointBreaked + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionState.Clean(); + decisionConditions.Clean(); + decisionXConditions.Clean(); + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + // Manipulate SL Based on Consolidation Zones ... + + // + double sls[]; + Add( + conditions.pivot, + sls // + ); + + // + double iAtr = decisionXConditions.atrBuffer[1]; + iAtr *= 2; + + // + 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.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + // Cleanup ... + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionState.Clean(); + decisionConditions.Clean(); + decisionXConditions.Clean(); + + // + return result; + } + + // + // Detect Guards ... + bool DetectGuards( + // + X121SMCGuard &guards[], + const XPosition &positions[], + // + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // + ) + { + // + bool result = false; + + // + Clean(guards); + + // + bool isCycleHelpersValid = + // + visionCycleHelper != NULL && + analyseCycleHelper != NULL && + decisionCycleHelper != NULL && + consolidationCycleHelper != NULL + // + ; + + // + // TODO: Implement Guards ... + return false; + + // + result = isCycleHelpersValid; + if (!result) + { + return result; + } + + // + int count = ArraySize(positions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + string symbol = decisionCycleHelper.GetSymbol(); + ENUM_TIMEFRAMES period = decisionCycleHelper.GetPeriod(); + string provider = ToString(X_121_SMC_PROVIDER_XWZ); + + // + XPosition ownPositions[]; + XPosition ownLongPositions[]; + XPosition ownShortPositions[]; + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = positions[i]; + bool isOwn = iPosition + .IsFiltersPassed( + symbol, + provider, + NULL, + X_POSITION_TYPE_ALL, + iPosition.magic // + ); + if (isOwn) + { + // + AddRef( + iPosition, + ownPositions // + ); + + // + bool isLong = IsLong(positions[i].type); + if (isLong) + { + // + AddRef( + iPosition, + ownLongPositions // + ); + } + else + { + // + AddRef( + iPosition, + ownShortPositions // + ); + } + } + } + + // + count = ArraySize(ownPositions); + + // + int longsCount = ArraySize(ownLongPositions); + bool hasLongs = IsValidSize(longsCount); + + // + int shortsCount = ArraySize(ownShortPositions); + bool hasShorts = IsValidSize(shortsCount); + + // + result = IsValidSize(count); + if (!result) + { + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + return result; + } + + // + // + // + + // + // Get Global and Common Guards ... + + // + ENUM_X_121_SMC_GUARD_ACTIONS ignoreGuards[1] = { + X_121_SMC_GUARD_ACTION_TRAIL_STOP}; + result = DetectX121SMCGuards( + provider, + guards, + positions, + decisionCycleHelper, + analyseCycleHelper, + consolidationCycleHelper, + visionCycleHelper, + // + ignoreGuards + // + ); + + // + // + // + + // + // Get Custom Implemented Guards ... + + // + // Here we Are Sure there is Positions to Guard ... + // based on Current Provider ... + + // + // Detect Required Data for Analyse Market to Guard Positions ... + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + // + result = HasChild(guards); + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + // + zBar.Clean(); + result = HasChild(guards); + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + result = HasChild(guards); + return result; + } + + // + XOHCL ppBar; + result = ppBar.Init( + symbol, + period, + ppIndex // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + result = HasChild(guards); + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + + // + // Cycles Conditions ... + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + result = HasChild(guards); + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + + // + analyseConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(decisionPoiEvents); + Clean(decisionCycleEvents); + + // + decisionConditions.Clean(); + + // + Clean(analysePoiEvents); + Clean(analyseCycleEvents); + + // + analyseConditions.Clean(); + + // + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + consolidationConditions.Clean(); + + // + result = HasChild(guards); + return result; + } + + // + // Cycles POI States ... + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Cycle X121Conditions ... + X121Conditions decisionXConditions = decisionConditions.x121Conditions; + X121Conditions analyseXConditions = analyseConditions.x121Conditions; + X121Conditions consolidationXConditions = consolidationConditions.x121Conditions; + X121Conditions visionXConditions = visionConditions.x121Conditions; + + // + // + // + + // + // Detect Consolidation Zone ... + + // + XBoxZone lastBullishBox; + XBoxZone prevLastBullishBox; + bool hasLastBullishBox = false; + bool hasPrevLastBullishBox = false; + XConsolidationZone lastBullishZone; + bool isLastBullishAbovePrev = false; + bool isLastBullishBelowPrev = false; + XConsolidationZone prevLastBullishZone; + + // + XBoxZone lastBearishBox; + XBoxZone prevLastBearishBox; + bool hasLastBearishBox = false; + bool hasPrevLastBearishBox = false; + XConsolidationZone lastBearishZone; + bool isLastBearishAbovePrev = false; + bool isLastBearishBelowPrev = false; + XConsolidationZone prevLastBearishZone; + + // + int bullishConsolidationZonesCount = 0; + int bearishConsolidationZonesCount = 0; + bool hasBullishConsolidationZones = false; + bool hasBearishConsolidationZones = false; + XConsolidationZone bullishConsolidationZones[]; + XConsolidationZone bearishConsolidationZones[]; + bool hasConsolidationZones = decisionCycleHelper.HasConsolidationZones(); + int consolidationZonesCount = decisionCycleHelper.CountConsolidationZones(); + if (hasConsolidationZones) + { + // + bullishConsolidationZonesCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BULLISH, + bullishConsolidationZones // + ); + hasBullishConsolidationZones = IsValidSize(bullishConsolidationZonesCount); + + // + bearishConsolidationZonesCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BEARISH, + bearishConsolidationZones // + ); + hasBearishConsolidationZones = IsValidSize(bearishConsolidationZonesCount); + + // + // + // + + // + if (hasBullishConsolidationZones && + bullishConsolidationZonesCount >= 2) + { + // + lastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 1]; + prevLastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 2]; + + // + hasLastBullishBox = ToBox( + lastBullishBox, + lastBullishZone // + ); + hasPrevLastBullishBox = ToBox( + prevLastBullishBox, + prevLastBullishZone // + ); + + // + isLastBullishAbovePrev = hasLastBullishBox && + hasPrevLastBullishBox && + IsBoxAbove( + lastBullishBox, + prevLastBullishBox // + ); + + // + isLastBullishBelowPrev = hasLastBullishBox && + hasPrevLastBullishBox && + IsBoxBelow( + lastBullishBox, + prevLastBullishBox // + ); + } + + // + if (hasBearishConsolidationZones && + bearishConsolidationZonesCount >= 2) + { + // + lastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 1]; + prevLastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 2]; + + // + hasLastBearishBox = ToBox( + lastBearishBox, + lastBearishZone // + ); + hasPrevLastBearishBox = ToBox( + prevLastBearishBox, + prevLastBearishZone // + ); + + // + isLastBearishAbovePrev = hasLastBearishBox && + hasPrevLastBearishBox && + IsBoxAbove( + lastBearishBox, + prevLastBearishBox // + ); + + // + isLastBearishBelowPrev = hasLastBearishBox && + hasPrevLastBearishBox && + IsBoxBelow( + lastBearishBox, + prevLastBearishBox // + ); + } + + // + } + + // + // Detect High Probability Swings ... + bool isSwingLow = + // + cBar.low > pBar.low && + ppBar.low > pBar.low && + // + zBar.low > pBar.low + // + ; + bool isSwingHigh = + // + cBar.high < pBar.high && + ppBar.high < pBar.high && + // + zBar.high < pBar.high + // + ; + bool isStrongSwingLow = + pBar.IsBullish() && + pBar.GetLowShadow() >= pBar.GetBody() * 2; + bool isStrongSwingHigh = + pBar.IsBearish() && + pBar.GetHighShadow() >= pBar.GetBody() * 2; + + // + bool isStrongSwingLowAboveLastBullishBox = + isStrongSwingLow && + hasLastBullishBox && + pBar.low > lastBullishBox.upper; + + // + bool isStrongSwingHighBelowLastBearishBox = + isStrongSwingHigh && + hasLastBearishBox && + pBar.high < lastBearishBox.lower; + + // + // Here We Have all Requirements for Guarding Positions ... + + // + // Available Guards: + // X_121_SMC_GUARD_ACTION_NONE + // X_121_SMC_GUARD_ACTION_CLOSE + // X_121_SMC_GUARD_ACTION_CLOSE_ALL + // X_121_SMC_GUARD_ACTION_CLOSE_LONGS + // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS + // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE + // X_121_SMC_GUARD_ACTION_TRAIL_STOP + // X_121_SMC_GUARD_ACTION_TRAIL_TARGET + // X_121_SMC_GUARD_ACTION_HEDGE + + // + // X_121_SMC_GUARD_ACTION_CLOSE: + // Close Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_ALL: + // Close All Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_LONGS: + // Close All Long Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS: + // Close All Short Positions on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE: + // Partial Close Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_TRAIL_STOP: + // Trail Stop Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_TRAIL_TARGET: + // Trail Target Specified Position on Specified Conditions ... + + // + // X_121_SMC_GUARD_ACTION_HEDGE: + // Hedge all Positions on Specified Conditions ... + + // + // Cleanup Collections ... + + // + Clean(ownPositions); + Clean(ownLongPositions); + Clean(ownShortPositions); + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + + // + Clean(visionPoiEvents); + Clean(analysePoiEvents); + Clean(visionCycleEvents); + Clean(decisionPoiEvents); + Clean(analyseCycleEvents); + Clean(decisionCycleEvents); + Clean(consolidationPoiEvents); + Clean(consolidationCycleEvents); + + // + visionState.Clean(); + analyseState.Clean(); + decisionState.Clean(); + visionConditions.Clean(); + analyseConditions.Clean(); + visionXConditions.Clean(); + decisionConditions.Clean(); + consolidationState.Clean(); + analyseXConditions.Clean(); + decisionXConditions.Clean(); + consolidationConditions.Clean(); + consolidationXConditions.Clean(); + + // + lastBullishBox.Clean(); + lastBearishBox.Clean(); + lastBullishZone.Clean(); + lastBearishZone.Clean(); + prevLastBullishBox.Clean(); + prevLastBearishBox.Clean(); + prevLastBullishZone.Clean(); + prevLastBearishZone.Clean(); + + // + count = ArraySize(guards); + result = IsValidSize(count); + + // + return result; + } + + // + // + // + + // + // Add Conditions to Conditions Collection ... + int AddConditionsIfNotExists( + int maxAllowed = 10 // + ) + { + // + int result = 0; + + // + bool isSetuped = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!isSetuped) + { + return result; + } + + // + int count = ArraySize(mConditionsCollection); + if (IsValidSize(count)) + { + // + // Copy Original Items ... + X121SMCStrategyXWZSignalConditions tmpItems[]; + Copy( + mConditionsCollection, + tmpItems // + ); + + // + // Prese Item Data ... + bool isBullish = IsBullish(mConditions.dir); + + // + for (int i = 0; i < count; i++) + { + // + X121SMCStrategyXWZSignalConditions iItem = tmpItems[i]; + + // + bool canRemove = mConditions.dir == iItem.dir && + mConditions.pivot == iItem.pivot; + if (canRemove) + { + // + ArrayRemove( + mConditionsCollection, + i, + 1 // + ); + } + } + + // + Clean(tmpItems); + } + + // + AddRef( + mConditions, + mConditionsCollection // + ); + + // + // Remove Olds ... + CleanupArray( + mConditionsCollection, + maxAllowed // + ); + + // + result = ArraySize(mConditionsCollection); + + // + return result; + } + + // + // Draw Functions ... + // + + // + void RemoveDraws() + { + mObjects.Clear(); + } + + // + void RemoveWorkingZoneDraws() + { + mWorkingZoneObjects.Clear(); + } + + // + void DrawOrderBlock( + XCOrderBlock *ob, + XCPOIDrawer *drawer, + bool forWorkingZone = false // + ) + { + // + 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) + { + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.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); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.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); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } + } + } + } + + // + void DrawFairValueGap( + XCFVG *fvg, + XCPOIDrawer *drawer, + bool forWorkingZone = false // + ) + { + // + if (fvg == NULL || + drawer == NULL) + { + return; + } + + // + ENUM_X_DIRECTION forDir = fvg.GetDirection(); + + // + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + color forColor = IsBullish(forDir) + ? bullishColor + : bearishColor; + + // + // Draw Order Block ... + XCBaseObject *obj; + bool isCreated = drawer.CreateFairValueGap( + fvg, + obj // + ); + if (isCreated) + { + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = fvg.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); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } + } + + // + string startVLineName = "Start_" + fvg.GetTag(); + + // + CChartObjectVLine *startVLine; + startVLine = new CChartObjectVLine(); + isCreated = startVLine.Create( + chartID, + startVLineName, + subWindow, + startedBar.time // + ); + if (isCreated) + { + // + startVLine.Color(forColor); + + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } + } + } + } + + // + void DrawWorkingZone( + X121SMCStrategyXWZSignalConditions &conditions, + XCPOIDrawer *drawer // + ) + { + // + if (drawer == NULL) + { + return; + } + + // + bool hasWorkingZone = conditions.HasWorkingZone(); + if (!hasWorkingZone) + { + return; + } + + // + string prefix = "WKZ_" + conditions.workingZone.symbol + ToString(conditions.workingZone.period) + "_"; + string tag = prefix + ToString(conditions.workingZone.upper) + "_" + ToString(conditions.workingZone.lower); + string suffix = ToMD5(tag); + + // + string upperName = prefix + "_Upper_" + suffix; + string lowerName = prefix + "_Lower_" + suffix; + string zoneUpperName = prefix + "_ZoneUpper_" + suffix; + string zoneLowerName = prefix + "_ZoneLower_" + suffix; + + // + string q1Name = prefix + "_Q1_" + suffix; + string q2Name = prefix + "_Q2_" + suffix; + string q3Name = prefix + "_Q3_" + suffix; + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + + // + bool isCreated = false; + + // + // Check For Trend Approced ... + bool isTrendApproved = conditions.HasOrderBlock() && + conditions.HasFairValueGap(); + if (isTrendApproved) + { + // + DrawOrderBlock( + conditions.orderBlock, + drawer, + true // + ); + + // + DrawFairValueGap( + conditions.fairValueGap, + drawer, + true // + ); + } + + // + XCSupplyZoneObject *iSupObj; + isCreated = drawer.CreateSupplyZone( + conditions.supplyZone, + iSupObj // + ); + if (isCreated) + { + mWorkingZoneObjects.Add(iSupObj); + } + + // + XCDemandZoneObject *iDemObj; + isCreated = drawer.CreateDemandZone( + conditions.demandZone, + iDemObj // + ); + if (isCreated) + { + mWorkingZoneObjects.Add(iDemObj); + } + + // + // Lower ... + CChartObjectTrend *lowerHLine; + lowerHLine = new CChartObjectTrend(); + isCreated = lowerHLine.Create( + chartID, + lowerName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.lower, + conditions.workingZone.to, + conditions.workingZone.lower // + ); + if (isCreated) + { + // + lowerHLine.Color(clrLime); + mWorkingZoneObjects.Add(lowerHLine); + } + + // + CChartObjectTrend *upperHLine; + upperHLine = new CChartObjectTrend(); + isCreated = upperHLine.Create( + chartID, + upperName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.upper, + conditions.workingZone.to, + conditions.workingZone.upper // + ); + if (isCreated) + { + // + upperHLine.Color(clrLime); + mWorkingZoneObjects.Add(upperHLine); + } + + // + CChartObjectTrend *zoneLowerHLine; + zoneLowerHLine = new CChartObjectTrend(); + isCreated = zoneLowerHLine.Create( + chartID, + zoneLowerName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.zoneLower, + conditions.workingZone.to, + conditions.workingZone.zoneLower // + ); + if (isCreated) + { + // + zoneLowerHLine.Color(clrRed); + mWorkingZoneObjects.Add(zoneLowerHLine); + } + + // + CChartObjectTrend *zoneUpperHLine; + zoneUpperHLine = new CChartObjectTrend(); + isCreated = zoneUpperHLine.Create( + chartID, + zoneUpperName, + subWindow, + conditions.workingZone.from, + conditions.workingZone.zoneUpper, + conditions.workingZone.to, + conditions.workingZone.zoneUpper // + ); + if (isCreated) + { + // + zoneUpperHLine.Color(clrRed); + mWorkingZoneObjects.Add(zoneUpperHLine); + } + + // + CChartObjectTrend *quarter1HLine; + quarter1HLine = new CChartObjectTrend(); + isCreated = quarter1HLine.Create( + chartID, + q1Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter1, + conditions.workingZone.to, + conditions.workingZone.quarter1 // + ); + if (isCreated) + { + // + quarter1HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter1HLine); + } + + // + CChartObjectTrend *quarter2HLine; + quarter2HLine = new CChartObjectTrend(); + isCreated = quarter2HLine.Create( + chartID, + q2Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter2, + conditions.workingZone.to, + conditions.workingZone.quarter2 // + ); + if (isCreated) + { + // + quarter2HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter2HLine); + } + + // + CChartObjectTrend *quarter3HLine; + quarter3HLine = new CChartObjectTrend(); + isCreated = quarter3HLine.Create( + chartID, + q3Name, + subWindow, + conditions.workingZone.from, + conditions.workingZone.quarter3, + conditions.workingZone.to, + conditions.workingZone.quarter3 // + ); + if (isCreated) + { + // + quarter3HLine.Color(clrYellow); + mWorkingZoneObjects.Add(quarter3HLine); + } + + // + } + + // + void DrawConditions( + X121SMCStrategyXWZSignalConditions &conditions, + XCPOIDrawer *drawer, + bool forceClean = false // + ) + { + // + if (drawer == NULL) + { + return; + } + + // + if (forceClean) + { + mObjects.Clear(); + } + + // + bool isCreated = false; + + // + ulong chartID = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + color bullishColor = drawer.BarBullishColor(); + color bearishColor = drawer.BarBearishColor(); + + // + // Start Zone ... + bool hasStartZone = conditions.HasStartZone(); + if (hasStartZone) + { + // + bool isBullish = conditions.startZone.IsBullish(); + + // + bool hasOB = conditions.startZone.HasOB(); + if (hasOB) + { + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateOrderBlock( + // conditions.startZone.ob, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + + // + DrawOrderBlock( + conditions.startZone.ob, + drawer // + ); + } + + // + bool hasFVG = conditions.startZone.HasFVG(); + if (hasFVG) + { + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateFairValueGap( + // conditions.startZone.fvg, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + + // + DrawFairValueGap( + conditions.startZone.fvg, + drawer // + ); + } + + // + bool hasSupply = conditions.startZone.HasSupply(); + if (hasSupply) + { + // + XCSupplyZoneObject *iObj; + isCreated = drawer.CreateSupplyZone( + conditions.startZone.supply, + iObj // + ); + + // + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + bool hasDemand = conditions.startZone.HasDemand(); + if (hasDemand) + { + // + XCDemandZoneObject *iObj; + isCreated = drawer.CreateDemandZone( + conditions.startZone.demand, + iObj // + ); + + // + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + bool hasSupport = conditions.startZone.HasSupport(); + if (hasSupport) + { + // + XCSupportZoneObject *iObj; + isCreated = drawer.CreateSupportZone( + conditions.startZone.support, + iObj // + ); + + // + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + bool hasResistance = conditions.startZone.HasResistance(); + if (hasResistance) + { + // + XCResistanceZoneObject *iObj; + isCreated = drawer.CreateResistanceZone( + conditions.startZone.resistance, + iObj // + ); + + // + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + bool hasBullishCZone = conditions.startZone.HasBullishConsolidationZone(); + if (hasBullishCZone) + { + // + XCConsolidationZoneObject *iObj; + isCreated = drawer.CreateConsolidationZone( + conditions.startZone.bullishConsolidationZone, + iObj // + ); + + // + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + bool hasBearishCZone = conditions.startZone.HasBearishConsolidationZone(); + if (hasBearishCZone) + { + // + XCConsolidationZoneObject *iObj; + isCreated = drawer.CreateConsolidationZone( + conditions.startZone.bearishConsolidationZone, + iObj // + ); + + // + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + // + // + + // + string bName = ""; + int arrowCode = 0; + string bSuffix = ""; + color arrowColor = clrNONE; + ENUM_X_PRICE bPrice = X_PRICE_CLOSE; + + // + bool hasSwingBar = conditions.startZone.swingBar.IsValid(); + if (hasSwingBar) + { + // + bSuffix = ToMD5(conditions.startZone.swingBar.GetTag()); + bName = + (isBullish + ? "SWING_LOW" + : "SWING_HIGH") + + "_" + bSuffix; + arrowCode = 159; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZone.swingBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasBreakerBar = conditions.startZone.breakerBar.IsValid(); + if (hasBreakerBar) + { + // + bSuffix = ToMD5(conditions.startZone.breakerBar.GetTag()); + bName = + (isBullish + ? "BULL_BREAKER" + : "BEAR_BREAKER") + + "_" + bSuffix; + arrowCode = + isBullish + ? 71 + : 72; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZone.breakerBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasMomentumBar = conditions.startZone.momentumBar.IsValid(); + if (hasMomentumBar) + { + // + bSuffix = ToMD5(conditions.startZone.momentumBar.GetTag()); + bName = + (isBullish + ? "BULL_MOMENTUM" + : "BEAR_MOMENTUM") + + "_" + bSuffix; + arrowCode = + isBullish + ? 233 + : 234; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZone.momentumBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasRejectionBar = conditions.startZone.rejectionBar.IsValid(); + if (hasRejectionBar) + { + // + bSuffix = ToMD5(conditions.startZone.rejectionBar.GetTag()); + bName = + (isBullish + ? "BULL_REJECTION" + : "BEAR_REJECTION") + + "_" + bSuffix; + arrowCode = + isBullish + ? 241 + : 242; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZone.rejectionBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasAppliedBox = conditions.startZone.appliedBox.IsValid(); + if (hasAppliedBox) + { + // + arrowColor = + IsBullish(conditions.startZone.appliedBox.dir) + ? bullishColor + : bearishColor; + + // + XCBoxObject *iObj; + isCreated = drawer.CreateBox( + conditions.startZone.appliedBox, + iObj // + ); + + // + if (isCreated) + { + // + iObj.BoxWidth(2); + iObj.BoxColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + } + } + + // + protected: + // + + // + private: + // + // Props ... + CArrayObj mObjects; + CArrayObj mWorkingZoneObjects; + + /** + * Initialize ... + */ + void Init() + { + } + + /** + * DeInitialize ... + */ + void DeInit() + { + // + RemoveDraws(); + mConditions.Clean(); + RemoveWorkingZoneDraws(); + Clean(mConditionsCollection); + } + + // + // Helpers ... + + // + bool CalculateRiskReward( + ENUM_X121SMC_XWZ_PRIORITY priority, + double &reward, + double &amountPercent // + ) + { + // + bool result = false; + + // + reward = 0; + amountPercent = 0; + + // + result = priority != X121SMC_XWZ_PRIORITY_NONE; + if (!result) + { + return result; + } + + // + switch (priority) + { + // + case X121SMC_XWZ_PRIORITY_STRONG_HIGH: + // + reward = 6; + amountPercent = 2; + break; + + // + case X121SMC_XWZ_PRIORITY_HIGH: + // + reward = 4; + amountPercent = 2; + break; + + // + case X121SMC_XWZ_PRIORITY_REGULAR: + // + reward = 3; + amountPercent = 1.5; + break; + + // + case X121SMC_XWZ_PRIORITY_LOW: + // + reward = 2; + amountPercent = 1; + break; + + // + case X121SMC_XWZ_PRIORITY_WEAK: + // + reward = 1; + amountPercent = 0.5; + break; + } + + // + result = + // + reward > 0 && + amountPercent > 0 + // + ; + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/xsupdem/x-121.smc.xwz.signal.lib.mq5 b/Documents/BKP/xsupdem/x-121.smc.xwz.signal.lib.mq5 new file mode 100644 index 00000000..23b7f262 --- /dev/null +++ b/Documents/BKP/xsupdem/x-121.smc.xwz.signal.lib.mq5 @@ -0,0 +1,3283 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 SMC Signal Class +// ------------------------------------------------- +// Name: XWZ +// 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_XWZ_PRIORITY +{ + X121SMC_XWZ_PRIORITY_NONE, + X121SMC_XWZ_PRIORITY_WEAK, + X121SMC_XWZ_PRIORITY_LOW, + X121SMC_XWZ_PRIORITY_REGULAR, + X121SMC_XWZ_PRIORITY_HIGH, + X121SMC_XWZ_PRIORITY_STRONG_HIGH, +}; + +// +struct X121SMCXWZZone +{ + // + // Props ... + XCFVG *fvg; + XCOrderBlock *ob; + XCSupplyZone *supply; + XCDemandZone *demand; + XCSupportZone *support; + XCResistanceZone *resistance; + XConsolidationZone bullishConsolidationZone; + XConsolidationZone bearishConsolidationZone; + + // + XOHCL swingBar; + XOHCL breakerBar; + XOHCL momentumBar; + XOHCL rejectionBar; + XBoxZone appliedBox; + + // + // Constructor ... + X121SMCXWZZone() + { + Clean(); + } + + // + // Tools ... + + // + void Clean() + { + // + ZeroMemory(ob); + ZeroMemory(fvg); + ZeroMemory(supply); + ZeroMemory(demand); + ZeroMemory(support); + ZeroMemory(resistance); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + bullishConsolidationZone.Clean(); + bearishConsolidationZone.Clean(); + } + + // + bool IsValid() + { + // + return HasOB() && + HasFVG() && + HasDirection(); + } + + // + bool AsBox(XBoxZone &box) + { + // + bool result = false; + + // + box.Clean(); + + // + result = IsValid() && + HasDirection(); + if (!result) + { + return result; + } + + // + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + ob // + ); + result = hasOBBox; + if (!result) + { + // + box.Clean(); + obBox.Clean(); + return result; + } + + // + box = obBox; + + // + obBox.Clean(); + + // + bool hasOB = HasOB(); + bool hasFVG = HasFVG(); + bool hasSupply = HasSupply(); + bool hasDemand = HasDemand(); + bool hasSupport = HasSupport(); + bool hasResistance = HasResistance(); + + // + // OB Compared since box used obBox ... + + // + if (hasFVG) + { + // + if (fvg.Upper() > box.upper) + { + box.upper = fvg.Upper(); + } + + // + if (fvg.Lower() < box.lower) + { + box.lower = fvg.Lower(); + } + } + + // + result = box.IsValid(); + + // + return result; + } + + // + bool HasOB() + { + return ob != NULL && + ob.IsValid(); + } + + // + bool HasFVG() + { + return fvg != NULL && + fvg.IsValid(); + } + + // + bool HasSupply() + { + return supply != NULL && + supply.IsValid(); + } + + // + bool HasDemand() + { + return demand != NULL && + demand.IsValid(); + } + + // + bool HasSupport() + { + return support != NULL && + support.IsValid(); + } + + // + bool HasResistance() + { + return resistance != NULL && + resistance.IsValid(); + } + + // + bool HasBullishConsolidationZone() + { + return bullishConsolidationZone.IsValid() && + bullishConsolidationZone.IsBreaked() && + IsBullish(bullishConsolidationZone.breakDir); + } + + // + bool HasBearishConsolidationZone() + { + return bearishConsolidationZone.IsValid() && + bearishConsolidationZone.IsBreaked() && + IsBullish(bearishConsolidationZone.breakDir); + } + + // + bool IsBullish() + { + // + return HasOB() && + ob.IsBullish() && + HasFVG() && + fvg.IsBullish() && + HasSupport() && + HasDemand(); + } + + // + bool IsBearish() + { + // + return HasOB() && + ob.IsBearish() && + HasFVG() && + fvg.IsBearish() && + HasSupply() && + HasResistance(); + } + + // + bool HasDirection() + { + return IsBullish() || + IsBearish(); + } + + // + ENUM_X_DIRECTION GetDirection() + { + // + ENUM_X_DIRECTION result = X_DIRECTION_NONE; + + // + bool hasDirection = HasDirection(); + if (!hasDirection) + { + return result; + } + + // + bool isBullish = IsBullish(); + + // + result = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + // + bool HasCondition( + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + result = IsValid() && + HasDirection() && + state.IsValid() && + state.HasChild(); + if (!result) + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + string symbol = ob.GetSymbol(); + if (!IsValid(forPeriod)) + { + forPeriod = ob.GetPeriod(); + } + datetime cTime = iTime( + symbol, + forPeriod, + barIndex // + ); + + // + bool isInside = IsPriceInside( + barIndex, + forPeriod // + ); + result = isInside; + if (!result) + { + return result; + } + + // + XBoxZone box; + result = AsBox(box); + if (!result) + { + // + box.Clean(); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + bool isBullish = IsBullish(); + ENUM_X_DIRECTION forDir = box.dir; + + // + int supportsCount = 0; + bool hasSupports = false; + XCSupportZone *supports[]; + + // + int resistancesCount = 0; + bool hasResistances = false; + XCResistanceZone *resistances[]; + + // + XBoxZone supResBoxes[]; + int supresBoxesCount = 0; + bool hasSupResBoxes = false; + + // + int count = 0; + bool has = false; + + // + has = state.HasSupportZones(); + if (has) + { + // + count = state.CountSupportZones(); + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = state.supportZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + box // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + Add( + iZone, + supports // + ); + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + } + + // + supportsCount = ArraySize(supports); + hasSupports = IsValidSize(supportsCount); + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + has = state.HasResistanceZones(); + if (has) + { + // + count = state.CountResistanceZones(); + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = state.resistanceZones[i]; + + // + iZone.To(cTime); + + // + XBoxZone iBox; + bool hasBox = ToBox( + iBox, + iZone // + ); + if (!hasBox) + { + // + iBox.Clean(); + continue; + } + + // + // Check From ... + bool isInside = IsBoxInside( + iBox, + box // + ); + if (!isInside) + { + // + iBox.Clean(); + continue; + } + + // + Add( + iZone, + resistances // + ); + + // + AddRef( + iBox, + supResBoxes // + ); + + // + iBox.Clean(); + } + + // + resistancesCount = ArraySize(resistances); + hasResistances = IsValidSize(resistancesCount); + + // + supresBoxesCount = ArraySize(supResBoxes); + hasSupResBoxes = IsValidSize(supresBoxesCount); + } + + // + result = hasSupResBoxes; + if (!result) + { + // + box.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + // Detect Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + + // + return result; + } + + // + // Check Conditions ... + + // + // Detect Start Senario ... + + // + double fiboPressureLevel = GetFiboLevelValue(X_FIBO_LEVEL_382); + + // + double fiboUpDown = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BEARISH // + ); + double fiboDownUp = GetFibonacciLevel( + pBar.high, + pBar.low, + X_FIBO_LEVEL_382, + X_DIRECTION_BULLISH // + ); + + // + bool hasFiboToUpPressure = + fiboDownUp > 0 && + fiboDownUp <= pBar.GetDown(); + bool hasFiboToDownPressure = + fiboUpDown > 0 && + fiboUpDown >= pBar.GetUp(); + + // + int selectedBoxIDX = -1; + for (int j = 0; j < supresBoxesCount; j++) + { + // + double appliedPrice = + isBullish + ? supResBoxes[j].lower + : supResBoxes[j].upper; + + // + // Check Swing Low ... + bool isSwingLow = + // + pBar.low < ppBar.low && + pBar.low < cBar.low && + zBar.open > pBar.low && + // + appliedPrice > pBar.low && + appliedPrice < pBar.GetDown() + // + ; + bool isPressuredSwingLow = + isSwingLow && + hasFiboToUpPressure; + bool isPressuredStrongSwingLow = + pBar.IsBullish() && + isPressuredSwingLow; + + // + bool isSwingHigh = + // + pBar.high > ppBar.high && + pBar.high > cBar.high && + zBar.open < pBar.high && + // + appliedPrice < pBar.high && + appliedPrice > pBar.GetUp() + // + ; + bool isPressuredSwingHigh = + isSwingHigh && + hasFiboToDownPressure; + bool isPressuredStrongSwingHigh = + pBar.IsBearish() && + isPressuredSwingHigh; + + // + bool hasValidSwing = + isBullish + ? isSwingLow + : isSwingHigh; + bool hasValidPressuredSwing = + isBullish + ? isPressuredSwingLow + : isPressuredSwingHigh; + bool hasValidPressuredStrongSwing = + isBullish + ? isPressuredStrongSwingLow + : isPressuredStrongSwingHigh; + if (hasValidSwing) + { + swingBar = pBar; + } + if (hasValidPressuredSwing) + { + swingBar = pBar; + } + if (hasValidPressuredStrongSwing) + { + swingBar = pBar; + } + + // + bool isCBarBreaked = IsBarBreak( + appliedPrice, + forDir, + cBar // + ); + if (isCBarBreaked) + { + breakerBar = cBar; + } + bool isPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarBreaked && isPBarBreaked) + { + breakerBar = pBar; + } + else + { + isPBarBreaked = false; + } + bool isPPBarBreaked = IsBarBreak( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarBreaked && + !isPBarBreaked && + isPPBarBreaked) + { + breakerBar = ppBar; + } + else + { + isPPBarBreaked = false; + } + bool isBoxBreaked = isCBarBreaked || + isPBarBreaked || + isPPBarBreaked; + + // + bool isCBarRejected = IsBarReject( + appliedPrice, + forDir, + cBar // + ); + if (isCBarRejected) + { + rejectionBar = cBar; + } + bool isPBarRejected = IsBarReject( + appliedPrice, + forDir, + pBar // + ); + if (!isCBarRejected && isPBarRejected) + { + rejectionBar = pBar; + } + else + { + isPBarRejected = false; + } + bool isPPBarRejected = IsBarReject( + appliedPrice, + forDir, + ppBar // + ); + if (!isCBarRejected && + !isPBarRejected && + isPPBarRejected) + { + rejectionBar = ppBar; + } + else + { + isPPBarRejected = false; + } + bool isBoxRejected = isCBarRejected || + isPBarRejected || + isPPBarRejected; + + // + bool hasRejectionBar = false; + if (isBullish) + { + // + count = state.CountBullishRejectionBars(); + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iZone = state.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasRejectionBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasRejectionBar) + { + // + if (!rejectionBar.IsValid()) + { + rejectionBar = iBar; + } + + // + break; + } + } + } + else + { + // + count = state.CountBearishRejectionBars(); + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iZone = state.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasRejectionBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasRejectionBar) + { + // + if (!rejectionBar.IsValid()) + { + rejectionBar = iBar; + } + + // + break; + } + } + } + + // + bool hasMomentumBar = false; + if (isBullish) + { + // + count = state.CountBullishMomentumBars(); + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iZone = state.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasMomentumBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasMomentumBar) + { + // + if (!momentumBar.IsValid()) + { + momentumBar = iBar; + } + + // + break; + } + } + } + else + { + // + count = state.CountBearishMomentumBars(); + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iZone = state.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasMomentumBar = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasMomentumBar) + { + // + if (!momentumBar.IsValid()) + { + momentumBar = iBar; + } + + // + break; + } + } + } + + // + bool hasSwing = false; + if (isBullish) + { + // + count = state.CountSwingLows(); + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = state.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasSwing = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasSwing) + { + // + if (!swingBar.IsValid()) + { + swingBar = iBar; + } + + // + break; + } + } + } + else + { + // + count = state.CountSwingHighs(); + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = state.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + int iBarIndex = iBar.Index(); + + // + hasSwing = + // + (iBarIndex == cBar.Index() || + iBarIndex == pBar.Index()) + // + ; + if (hasSwing) + { + // + if (!swingBar.IsValid()) + { + swingBar = iBar; + } + + // + break; + } + } + } + + // + bool hasRequiredValidations = + // + (hasRejectionBar || + hasMomentumBar) + // + || + // + (hasRejectionBar || + hasSwing) + // + || + // + (hasMomentumBar || + hasSwing) + // + ; + + // + result = + // + (isBoxBreaked && + (hasRequiredValidations || + hasValidPressuredSwing)) + // + || + // + (isBoxRejected && + (hasRequiredValidations || + hasValidPressuredSwing)) + // + ; + if (result) + { + // + selectedBoxIDX = j; + break; + } + } + + // + result = + result && + (isBullish + ? zBar.open > box.upper + : zBar.open < box.lower) && + IsValidIndex(selectedBoxIDX); + if (result) + { + appliedBox = supResBoxes[selectedBoxIDX]; + } + + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + ppBar.Clean(); + Clean(supports); + Clean(resistances); + Clean(supResBoxes); + + // + return result; + } + + // + bool IsPriceInside( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = IsValid() && + HasOB() && + HasFVG() && + HasDirection(); + if (!result) + { + return result; + } + + // + string symbol = ob.GetSymbol(); + if (forPeriod == NULL) + { + forPeriod = ob.GetPeriod(); + } + + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + bool isBullish = IsBullish(forDir); + + // + // Check Start Bars ... + + // + XOHCL obStartedBar; + ENUM_X_DIRECTION obStartedDir; + bool isOBStarted = ob.IsStarted( + forDir, + obStartedBar, + obStartedDir // + ); + result = isOBStarted; + if (!result) + { + return result; + } + + // + XOHCL fvgStartedBar; + ENUM_X_DIRECTION fvgStartedDir; + bool isFVGStarted = fvg.IsStarted( + forDir, + fvgStartedBar, + fvgStartedDir // + ); + result = isFVGStarted; + if (!result) + { + return result; + } + + // + // Get Zone Box ... + XBoxZone box; + bool hasBox = AsBox(box); + result = hasBox; + if (!result) + { + // + box.Clean(); + + // + return result; + } + + // + // Retrieve Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + result = + // + isBullish + ? ( + // + pBar.low > box.upper && + cBar.low <= box.upper && + zBar.open <= box.upper + // + ) + : ( + // + pBar.high < box.lower && + cBar.high >= box.lower && + zBar.open >= box.lower + // + ) + // + ; + + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // +}; + +// +struct X121SMCXWZWorkingZone +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + double zoneUpper; + double zoneLower; + + // + double quarter1; + double quarter2; + double quarter3; + + // + datetime to; + datetime from; + + // + XOHCL swingBar; + XOHCL breakerBar; + XOHCL momentumBar; + XOHCL rejectionBar; + XBoxZone appliedBox; + + // + X121SMCXWZWorkingZone() + { + Clean(); + } + + // + void Clean() + { + // + upper = 0; + lower = 0; + quarter1 = 0; + quarter2 = 0; + quarter3 = 0; + zoneLower = 0; + zoneUpper = 0; + + // + from = NULL; + symbol = NULL; + period = NULL; + + // + CleanConditionBars(); + + // + ZeroMemory(this); + } + + // + void CleanConditionBars() + { + // + swingBar.Clean(); + breakerBar.Clean(); + appliedBox.Clean(); + momentumBar.Clean(); + rejectionBar.Clean(); + } + + // + 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 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 X121SMCStrategyXWZSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + double reward; + double amountPercent; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double pivot; + double point; + + // + ENUM_X121SMC_XWZ_PRIORITY priority; + + // + // Working Zone ... + XCFVG *fairValueGap; + XCOrderBlock *orderBlock; + XCSupplyZone *supplyZone; + XCDemandZone *demandZone; + X121SMCXWZWorkingZone workingZone; + + // + X121SMCXWZZone startZone; + + // + // Constructor ... + X121SMCStrategyXWZSignalConditions() + { + 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; + + // + target = 0; + reward = 0; + amountPercent = 0; + + // + ZeroMemory(supplyZone); + + // + ZeroMemory(demandZone); + + // + ZeroMemory(orderBlock); + + // + ZeroMemory(fairValueGap); + + // + startZone.Clean(); + + // + workingZone.Clean(); + } + + // + // + // + + // + bool HasWorkingZone() + { + return workingZone.IsValid(); + } + + // + bool HasOrderBlock() + { + return orderBlock != NULL && + orderBlock.IsValid(); + } + + // + bool HasFairValueGap() + { + return fairValueGap != NULL && + fairValueGap.IsValid(); + } + + // + bool HasSupplyZone() + { + return supplyZone != NULL && + supplyZone.IsValid(); + } + + // + bool HasDemandZone() + { + return demandZone != NULL && + demandZone.IsValid(); + } + + // + bool HasStartZone() + { + return startZone.IsValid(); + } + + // + void UpdateTo(datetime value = NULL) + { + // + value = NormalizeTime(value); + + // + bool hasSupplyZone = HasSupplyZone(); + if (hasSupplyZone) + { + supplyZone.To(value); + } + + // + bool hasDemandZone = HasDemandZone(); + if (hasDemandZone) + { + demandZone.To(value); + } + + // + bool hasOrderBlock = HasOrderBlock(); + if (hasOrderBlock) + { + orderBlock.To(value); + } + + // + bool hasFairValueGap = HasFairValueGap(); + if (hasFairValueGap) + { + fairValueGap.To(value); + } + + // + // Working Zone ... + bool hasWorkingZone = HasWorkingZone(); + if (hasWorkingZone) + { + workingZone.to = value; + } + + // + // Start Zone ... + bool hasStartZone = HasStartZone(); + if (hasStartZone) + { + // + bool hasOB = startZone.HasOB(); + if (hasOB) + { + startZone.ob.To(value); + } + + // + bool hasFVG = startZone.HasFVG(); + if (hasFVG) + { + startZone.fvg.To(value); + } + + // + bool hasSupply = startZone.HasSupply(); + if (hasSupply) + { + startZone.supply.To(value); + } + + // + bool hasDemand = startZone.HasDemand(); + if (hasDemand) + { + startZone.demand.To(value); + } + + // + bool hasSupport = startZone.HasSupport(); + if (hasSupport) + { + startZone.support.To(value); + } + + // + bool hasResistance = startZone.HasResistance(); + if (hasResistance) + { + startZone.resistance.To(value); + } + + // + bool hasBullishCZone = startZone.HasBullishConsolidationZone(); + if (hasBullishCZone) + { + // startZone.bullishConsolidationZone.to = cTime; + } + + // + bool hasBearishCZone = startZone.HasBearishConsolidationZone(); + if (hasBearishCZone) + { + // startZone.bearishConsolidationZone.to = cTime; + } + } + } + + // + // + // + + // + // Working Zone is an Area which + // we decide to trade inside it ... + bool ExtractWorkingZone( + XPOIState &htfState, + XPOIState &mtfState, + XPOIState &stfState, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + int zIndex = barIndex; + + // + result = !HasWorkingZone(); + if (!result) + { + return result; + } + + // + result = IsValid(symbol) && + IsValid(period); + if (!result) + { + // + Clean(); + return result; + } + + // + datetime cTime = iTime( + symbol, + period, + zIndex // + ); + + // + result = + // + htfState.IsValid() && + htfState.HasChild() && + htfState.HasSupplyZones() && + htfState.HasDemandZones() && + // + mtfState.IsValid() && + mtfState.HasChild() && + mtfState.HasSupplyZones() && + mtfState.HasDemandZones() && + // + stfState.IsValid() && + stfState.HasChild() + // + ; + if (!result) + { + return result; + } + + // + // Retrieve Highest Supply Zone ... + int hSupplyIDX = GetHighest(htfState.supplyZones); + int lDemandIDX = GetLowest(htfState.demandZones); + + // + result = + // + IsValidIndex(hSupplyIDX) && + IsValidIndex(lDemandIDX) + // + ; + if (!result) + { + return result; + } + + // + supplyZone = htfState.supplyZones[hSupplyIDX]; + demandZone = htfState.demandZones[lDemandIDX]; + + // + result = + // + supplyZone != NULL && + demandZone != NULL && + supplyZone.IsValid() && + demandZone.IsValid() + // + ; + if (!result) + { + // + Clean(); + return result; + } + + // + // Check Validation of Supply and Demand Zones ... + lDemandIDX = GetLowest(mtfState.demandZones); + hSupplyIDX = GetHighest(mtfState.supplyZones); + result = IsValidIndex(lDemandIDX) && + IsValidIndex(hSupplyIDX); + if (!result) + { + // + Clean(); + return result; + } + + // + // Validate Supply and Demand ... + bool isMTFHSupplyInside = + IsInside( + mtfState.supplyZones[hSupplyIDX], + supplyZone); + bool isMTFLDemandInside = + IsInside( + mtfState.demandZones[lDemandIDX], + demandZone // + ); + if (isMTFHSupplyInside && + !isMTFLDemandInside) + { + demandZone = mtfState.demandZones[lDemandIDX]; + } + else if (!isMTFHSupplyInside && + isMTFLDemandInside) + { + supplyZone = mtfState.supplyZones[hSupplyIDX]; + } + else if (isMTFHSupplyInside && + isMTFLDemandInside) + { + // + supplyZone = mtfState.supplyZones[hSupplyIDX]; + demandZone = mtfState.demandZones[lDemandIDX]; + } + + // + // Check Zones Validation ... + bool hasTrend = + supplyZone != NULL && + supplyZone.IsValid() && + demandZone != NULL && + demandZone.IsValid(); + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + datetime from = MathMax( + supplyZone.From(), + demandZone.From()); + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + // Detect Trend ... + ENUM_X_DIRECTION trend = X_DIRECTION_NONE; + datetime supplyTouch = NULL; + datetime demandTouch = NULL; + for (int i = zIndex; i < fromIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + period, + i // + ); + if (!isInited) + { + continue; + } + + // + bool isTouchSupplyZone = + // + iBar.low < supplyZone.Lower() && + iBar.GetUp() > supplyZone.Lower() + // + ; + if (isTouchSupplyZone && + !IsValid(supplyTouch)) + { + supplyTouch = iBar.time; + } + + // + bool isTouchDemandZone = + // + iBar.high > demandZone.Upper() && + iBar.GetDown() < demandZone.Upper() + // + ; + if (isTouchDemandZone && + !IsValid(demandTouch)) + { + demandTouch = iBar.time; + } + + // + bool canBreak = + IsValid(supplyTouch) && + IsValid(demandTouch); + + // + iBar.Clean(); + + // + if (canBreak) + { + break; + } + } + + // + hasTrend = + // + IsValid(supplyTouch) || + IsValid(demandTouch) + // + ; + if (hasTrend) + { + // + trend = + // + supplyTouch > demandTouch + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH + // + ; + } + + // + // Check Trend ... + result = hasTrend; + if (!result) + { + // + Clean(); + return result; + } + + // + bool hasBullishTrend = IsBullish(trend); + bool hasBearishTrend = IsBearish(trend); + + // + // Find Order Block and FVG for Trend Approve ... + + // + bool isBullishTrendApproved = false; + bool isBearishTrendApproved = false; + + // + // Now We Have to Detect at least One OrderBlock with FVG ... + // for Trend Approvement ... + bool hasOrderBlock = HasOrderBlock(); + bool hasFairValueGap = HasFairValueGap(); + if (!hasOrderBlock && + !hasFairValueGap) + { + // + int count = 0; + bool has = false; + + // + XCFVG *fvg = NULL; + XCOrderBlock *ob = NULL; + + // + has = mtfState.HasBullishOrderBlocks(); + count = mtfState.CountBullishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bullishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > demandZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + demandZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBullishFairValueGaps(); + count = stfState.CountBullishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bullishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BULLISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + + // + if (ob != NULL && + fvg != NULL) + { + // + orderBlock = ob; + fairValueGap = fvg; + } + + // + hasOrderBlock = HasOrderBlock(); + hasFairValueGap = HasFairValueGap(); + isBullishTrendApproved = hasOrderBlock && + hasFairValueGap; + } + + // + if (!isBullishTrendApproved) + { + // + has = mtfState.HasBearishOrderBlocks(); + count = mtfState.CountBearishOrderBlocks(); + + // + if (has) + { + // + // Check Order Block ... + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = mtfState.bearishOrderBlocks[i]; + + // + iOB.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iOB.From() > supplyZone.From(); + if (!isFromPassed) + { + continue; + } + + // + // Must inside DemandZone ... + bool isInsideDemand = IsInsideDiff( + iOB, + supplyZone // + ); + if (!isInsideDemand) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone obBox; + bool hasOBBox = ToBox( + obBox, + iOB // + ); + if (!hasOBBox) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Zone Must not Used before ... + bool isUsed = IsBoxUsed( + obBox, + startedBar.Index() - 1, + zIndex // + ); + if (isUsed) + { + // + obBox.Clean(); + startedBar.Clean(); + continue; + } + + // + ob = iOB; + + // + obBox.Clean(); + startedBar.Clean(); + + // + break; + } + + // + // Detect Fair Value Gap ... + if (ob != NULL && + ob.IsValid()) + { + // + has = stfState.HasBearishFairValueGaps(); + count = stfState.CountBearishFairValueGaps(); + if (has) + { + // + // Check Fir Value Gap ... + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = stfState.bearishFairValueGaps[i]; + + // + iFVG.To(cTime); + + // + // Check From Passes ... + bool isFromPassed = iFVG.From() > ob.From(); + if (!isFromPassed) + { + continue; + } + + // + // Check Started ... + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iFVG.IsStarted( + X_DIRECTION_BEARISH, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + startedBar.Clean(); + continue; + } + + // + // Converts to Box ... + XBoxZone fvgBox; + bool hasFVGBox = ToBox( + fvgBox, + iFVG // + ); + if (!hasFVGBox) + { + // + fvgBox.Clean(); + startedBar.Clean(); + continue; + } + + // + // Check Inside Order Block ... + bool isInside = IsInsideDiff( + iFVG, + ob, + true // Force Side Out ... + ); + if (!isInside) + { + continue; + } + + // + fvg = iFVG; + + // + fvgBox.Clean(); + startedBar.Clean(); + + // + break; + } + } + else + { + // + ob = NULL; + } + } + + // + if (ob != NULL && + fvg != NULL) + { + // + orderBlock = ob; + fairValueGap = fvg; + } + + // + hasOrderBlock = HasOrderBlock(); + hasFairValueGap = HasFairValueGap(); + isBearishTrendApproved = hasOrderBlock && + hasFairValueGap; + } + } + } + + // + // Check Trend Approved ... + bool isTrendApproved = + hasOrderBlock && + hasFairValueGap && + (isBullishTrendApproved || + isBearishTrendApproved); + result = isTrendApproved; + if (!result) + { + // + Clean(); + return result; + } + + // + // Prepare Working Zone ... + workingZone.symbol = symbol; + workingZone.period = period; + + // + workingZone.upper = supplyZone.Lower(); + workingZone.zoneUpper = supplyZone.Upper(); + + // + workingZone.lower = demandZone.Upper(); + workingZone.zoneLower = demandZone.Lower(); + + // + workingZone.from = from; + + // + double upper = workingZone.upper; + double range = + workingZone.upper - workingZone.lower; + double ranegPercent = range / 100; + double quarterValue = ranegPercent * 25; + + // + workingZone.quarter1 = upper - (quarterValue * 1); + workingZone.quarter2 = upper - (quarterValue * 2); + workingZone.quarter3 = upper - (quarterValue * 3); + + // + result = workingZone.IsValid(); + if (!result) + { + Clean(); + } + + // + 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 DetectTrend( + ENUM_X_DIRECTION &trend, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (forPeriod == NULL) + { + forPeriod = period; + } + + // + trend = X_DIRECTION_NONE; + + // + result = HasWorkingZone(); + if (!result) + { + return result; + } + + // + int FromIndex = iBarShift( + symbol, + forPeriod, + workingZone.from // + ); + + // + datetime supplyTouch = NULL; + datetime demandTouch = NULL; + for (int i = barIndex; i < FromIndex; i++) + { + // + XOHCL iBar; + bool isInited = iBar.Init( + symbol, + forPeriod, + i // + ); + if (!isInited) + { + continue; + } + + // + bool isTouchSupplyZone = + // + iBar.low < supplyZone.Lower() && + iBar.GetUp() > supplyZone.Lower() + // + ; + if (isTouchSupplyZone && + !IsValid(supplyTouch)) + { + supplyTouch = iBar.time; + } + + // + bool isTouchDemandZone = + // + iBar.high > demandZone.Upper() && + iBar.GetDown() < demandZone.Upper() + // + ; + if (isTouchDemandZone && + !IsValid(demandTouch)) + { + demandTouch = iBar.time; + } + + // + bool canBreak = + IsValid(supplyTouch) && + IsValid(demandTouch); + + // + iBar.Clean(); + + // + if (canBreak) + { + break; + } + } + + // + result = + // + IsValid(supplyTouch) || + IsValid(demandTouch) + // + ; + if (result) + { + // + trend = + // + supplyTouch > demandTouch + ? X_DIRECTION_BEARISH + : X_DIRECTION_BULLISH + // + ; + } + + // + return result; + } + + // + bool DetectStartZone( + ENUM_X_DIRECTION forDir, + XPOIState &state, + XC121SMCCycleHelper *cycleHelper // + ) + { + // + bool result = false; + + // + result = state.IsValid() && + state.HasChild() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + + // + int idx = -1; + int count = 0; + int has = false; + + // + // Supply Zones ... + has = state.HasSupplyZones(); + if (has) + { + // + idx = GetYoungest(state.supplyZones); + if (IsValidIndex(idx)) + { + startZone.supply = state.supplyZones[idx]; + } + } + + // + // Demand Zones ... + has = state.HasDemandZones(); + if (has) + { + // + idx = GetYoungest(state.demandZones); + if (IsValidIndex(idx)) + { + startZone.demand = state.demandZones[idx]; + } + } + + // + // Support Zones ... + has = state.HasSupportZones(); + if (has) + { + // + idx = GetYoungest(state.supportZones); + if (IsValidIndex(idx)) + { + startZone.support = state.supportZones[idx]; + } + } + + // + // Resistance Zones ... + has = state.HasResistanceZones(); + if (has) + { + // + idx = GetYoungest(state.resistanceZones); + if (IsValidIndex(idx)) + { + startZone.resistance = state.resistanceZones[idx]; + } + } + + // + // Other Zones ... + if (isBullish) + { + // + // Order Block ... + has = state.HasBullishOrderBlocks(); + if (has) + { + // + idx = GetYoungest(state.bullishOrderBlocks); + if (IsValidIndex(idx)) + { + startZone.ob = state.bullishOrderBlocks[idx]; + } + } + + // + // Fair Value Gap ... + has = state.HasBullishFairValueGaps(); + if (has) + { + // + idx = GetYoungest(state.bullishFairValueGaps); + if (IsValidIndex(idx)) + { + startZone.fvg = state.bullishFairValueGaps[idx]; + } + } + } + else + { + // + // Order Block ... + has = state.HasBearishOrderBlocks(); + if (has) + { + // + idx = GetYoungest(state.bearishOrderBlocks); + if (IsValidIndex(idx)) + { + startZone.ob = state.bearishOrderBlocks[idx]; + } + } + + // + // Fair Value Gap ... + has = state.HasBearishFairValueGaps(); + if (has) + { + // + idx = GetYoungest(state.bearishFairValueGaps); + if (IsValidIndex(idx)) + { + startZone.fvg = state.bearishFairValueGaps[idx]; + } + } + } + + // + bool hasOBFVG = startZone.HasOB() && + startZone.HasFVG(); + bool isOBStarted = false; + bool isFVGStarted = false; + bool isOBActivated = false; + bool isFVGActivated = false; + bool isOBInsideFVG = false; + bool isFVGInsideOB = false; + if (hasOBFVG) + { + // + ENUM_X_DIRECTION forDir = startZone.ob.GetDirection(); + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + + // + isOBStarted = startZone.ob.IsStarted( + forDir, + startedBar, + startedDir // + ); + + // + isOBActivated = startZone.ob.IsActivated( + forDir, + startedBar, + startedDir // + ); + + // + forDir = startZone.fvg.GetDirection(); + + // + isFVGStarted = startZone.fvg.IsStarted( + forDir, + startedBar, + startedDir // + ); + + // + isFVGActivated = startZone.fvg.IsActivated( + forDir, + startedBar, + startedDir // + ); + + // + isOBInsideFVG = + IsInsideDiff( + startZone.ob, + startZone.fvg // + ) || + (isBullish + ? IsAboveDiff( + startZone.ob, + startZone.fvg, + true // IgnoreInside + ) + : IsBelowDiff( + startZone.ob, + startZone.fvg, + true // IgnoreInside + )); + // + isFVGInsideOB = + IsInsideDiff( + startZone.fvg, + startZone.ob // + ) || + (isBullish + ? IsAboveDiff( + startZone.fvg, + startZone.ob, + true // IgnoreInside + ) + : IsBelowDiff( + startZone.fvg, + startZone.ob, + true // IgnoreInside + )); + + // + startedBar.Clean(); + } + + // + result = + isOBStarted && + isFVGStarted && + !isOBActivated && + !isFVGActivated && + startZone.IsValid() && + (isOBInsideFVG || + isFVGInsideOB) && + (isBullish + ? startZone.IsBullish() + : startZone.IsBearish()); + if (!result) + { + // + startZone.Clean(); + + // + return result; + } + + // + return result; + } + + // + void DetectPriority( + ENUM_X121SMC_XWZ_PRIORITY &bullish, + ENUM_X121SMC_XWZ_PRIORITY &bearish, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bullish = X121SMC_XWZ_PRIORITY_NONE; + bearish = X121SMC_XWZ_PRIORITY_NONE; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + bool hasWorkingZone = HasWorkingZone(); + if (!hasWorkingZone) + { + return; + } + + // + XOHCL zBar; + bool isInited = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!isInited) + { + // + zBar.Clean(); + return; + } + + // + XOHCL cBar; + isInited = zBar.GetPreviousBar(cBar); + if (!isInited) + { + // + zBar.Clean(); + cBar.Clean(); + return; + } + + // + // ZoneUpper, Upper ... + if (cBar.low > workingZone.upper && + cBar.high < workingZone.zoneUpper && + zBar.low > workingZone.upper && + zBar.high < workingZone.zoneUpper) + { + // + bullish = X121SMC_XWZ_PRIORITY_NONE; + bearish = X121SMC_XWZ_PRIORITY_STRONG_HIGH; + } + // + // Upper, Quarter1 ... + else if (cBar.low > workingZone.quarter1 && + cBar.high < workingZone.upper && + zBar.low > workingZone.quarter1 && + zBar.high < workingZone.upper) + { + // + bullish = X121SMC_XWZ_PRIORITY_WEAK; + bearish = X121SMC_XWZ_PRIORITY_HIGH; + } + // + // Quarter1, Quarter2 ... + else if (cBar.low > workingZone.quarter2 && + cBar.high < workingZone.quarter1 && + zBar.low > workingZone.quarter2 && + zBar.high < workingZone.quarter1) + { + // + bullish = X121SMC_XWZ_PRIORITY_LOW; + bearish = X121SMC_XWZ_PRIORITY_REGULAR; + } + // + // Quarter2, Quarter3 ... + else if (cBar.low > workingZone.quarter3 && + cBar.high < workingZone.quarter2 && + zBar.low > workingZone.quarter3 && + zBar.high < workingZone.quarter2) + { + // + bullish = X121SMC_XWZ_PRIORITY_REGULAR; + bearish = X121SMC_XWZ_PRIORITY_LOW; + } + // + // Quarter3, Lower ... + else if (cBar.low > workingZone.lower && + cBar.high < workingZone.quarter3 && + zBar.low > workingZone.lower && + zBar.high < workingZone.quarter3) + { + // + bullish = X121SMC_XWZ_PRIORITY_HIGH; + bearish = X121SMC_XWZ_PRIORITY_WEAK; + } + // + // Lower, ZoneLower ... + else if (cBar.low > workingZone.zoneLower && + cBar.high < workingZone.lower && + zBar.low > workingZone.zoneLower && + zBar.high < workingZone.lower) + { + // + bullish = X121SMC_XWZ_PRIORITY_STRONG_HIGH; + bearish = X121SMC_XWZ_PRIORITY_NONE; + } + + // + zBar.Clean(); + cBar.Clean(); + } + + // + bool HasWorkingZoneConditions( + ENUM_X_DIRECTION &conditionsDir, + XPOIState &state, + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + conditionsDir = X_DIRECTION_NONE; + + // + result = HasWorkingZone(); + if (!result) + { + return result; + } + + // + XBoxZone appliedBox; + + // + // Clean Condition Bars ... + workingZone.CleanConditionBars(); + + // + // Validate ... + result = state.IsValid() && + state.HasChild(); + if (!result) + { + // + workingZone.CleanConditionBars(); + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + datetime cTime = iTime( + symbol, + forPeriod, + barIndex // + ); + + // + // Check Supply Zone ... + + // + XBoxZone supplyBox; + bool hasSupplyBox = + supplyZone != NULL && + supplyZone.IsValid() && + ToBox( + supplyBox, + supplyZone // + ); + if (hasSupplyBox) + { + // + result = CheckBoxForTradeConditions( + supplyBox, + appliedBox, + workingZone.swingBar, + workingZone.breakerBar, + workingZone.rejectionBar, + workingZone.momentumBar, + state, + barIndex, + forPeriod // + ); + + // + if (result) + { + conditionsDir = X_DIRECTION_BEARISH; + } + } + + // + // Check Demand Zone ... + XBoxZone demandBox; + bool hasDemandBox = false; + if (!result) + { + // + hasDemandBox = + demandZone != NULL && + demandZone.IsValid() && + ToBox( + demandBox, + demandZone // + ); + if (hasDemandBox) + { + // + result = CheckBoxForTradeConditions( + demandBox, + appliedBox, + workingZone.swingBar, + workingZone.breakerBar, + workingZone.rejectionBar, + workingZone.momentumBar, + state, + barIndex, + forPeriod // + ); + + // + if (result) + { + conditionsDir = X_DIRECTION_BULLISH; + } + } + } + + // + if (!result) + { + workingZone.CleanConditionBars(); + } + + // + supplyBox.Clean(); + demandBox.Clean(); + appliedBox.Clean(); + + // + return result; + } + + // + double GetSpread() + { + // + double result = 0; + + // + if (!IsValid(symbol)) + { + return result; + } + + // + result = GetSpread( + symbol // + ); + + // + return result; + } + + // +}; diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 19ae990e..77092d08 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -5943,7 +5943,7 @@ struct XConsolidationZone // string result = // - GetTypeName(this) + "_" + + "ConsolidationZone" + "_" + symbol + "_" + ToString(period) + "_" + ToString(upper) + "_" + @@ -7357,13 +7357,15 @@ bool IsBoxAbove( * @param source: XBoxZone instance Reference ... * @param dest: XBoxZone instance Reference ... * @param forceSideOut: bool, force check Box has One Side Out ... + * @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ... * * @return ( bool ) */ bool IsBoxInside( XBoxZone &source, XBoxZone &dest, - bool forceSideOut = false // + bool forceSideOut = false, // + bool ignoreSideOut = true // ) { // @@ -7385,8 +7387,17 @@ bool IsBoxInside( if (!forceSideOut) { // - result = source.lower >= dest.lower && - source.upper <= dest.upper; + if (ignoreSideOut) + { + // + result = source.lower >= dest.lower && + source.upper <= dest.upper; + } + else + { + result = source.lower >= dest.lower || + source.upper <= dest.upper; + } } else { diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 index 7e0ff31d..257ad2dd 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 @@ -527,15 +527,26 @@ class XCX121SMCXWZSignalDetector : public XCBase // // Detect Start Zones ... - bool hasStartZone = mConditions.HasStartZone(); + bool hasStartZone = mConditions.HasStartZones(); if (!hasStartZone) { // - hasStartZone = mConditions.DetectStartZone( + hasStartZone = mConditions.DetectStartZones( trend, analyseState, decisionCycleHelper // ); + + // + if (hasStartZone) + { + // + mConditions.UpdateTo(cTime); + DrawConditions( + mConditions, + visionCycleHelper.mPOIDrawer // + ); + } } // @@ -563,55 +574,104 @@ class XCX121SMCXWZSignalDetector : public XCBase : false; // + DrawWorkingZone( + mConditions, + visionCycleHelper.mPOIDrawer // + ); + + // + // Here we are Make sure we have Correct: + // - WorkSpace ... + // - Trend ... + // - What we looking for: Long or Short ... + // - Priority ... + + // + DrawConditions( + mConditions, + visionCycleHelper.mPOIDrawer // + ); + + // + double pivot = 0; + double point = 0; bool hasCondition = false; ENUM_X_DIRECTION conditionsDir = X_DIRECTION_NONE; - // - // Detect Start Zone Based Conditions ... - if (hasStartZone) + // Detect Start Zone Conditions ... + hasCondition = mConditions + .HasConditions( + conditionsDir, + decisionState, + zIndex, + decisionState.period // + ); + if (hasCondition) { - // - // Detect Start Zone Conditions ... - hasCondition = mConditions - .startZone - .HasCondition( - decisionState, - zIndex, - NULL // period // - ); - conditionsDir = mConditions - .startZone - .GetDirection(); + // // + // XBoxZone startZoneBox; + // bool hasBox = mConditions.startZone.AsBox(startZoneBox); + // if (hasBox) + // { + // // + // bool isBullish = IsBullish(conditionsDir); + + // // + // pivot = + // isBullish + // ? startZoneBox.lower + // : startZoneBox.upper; + + // // + // point = + // isBullish + // ? startZoneBox.upper + // : startZoneBox.lower; + // } } - // - RemoveWorkingZoneDraws(); - DrawWorkingZone(mConditions, visionCycleHelper.mPOIDrawer); + // // + // // Detect Supply and Deman Zone Based Conditions ... + // if (!hasCondition) + // { + // // + // bool isPriceInsideSupplyZone = + // bearishPriority == X121SMC_XWZ_PRIORITY_STRONG_HIGH; - // - // Detect Supply and Deman Zone Based Conditions ... - if (!hasCondition) - { - // - bool isPriceInsideSupplyZone = - bearishPriority == X121SMC_XWZ_PRIORITY_STRONG_HIGH; + // // + // bool isPriceInsideDemandZone = + // bullishPriority == X121SMC_XWZ_PRIORITY_STRONG_HIGH; - // - bool isPriceInsideDemandZone = - bullishPriority == X121SMC_XWZ_PRIORITY_STRONG_HIGH; + // // + // bool isPriceInsideSupDem = isPriceInsideSupplyZone || + // isPriceInsideDemandZone; + // if (isPriceInsideSupDem) + // { + // // + // hasCondition = mConditions.HasWorkingZoneConditions( + // conditionsDir, + // decisionState // + // ); - // - bool isPriceInsideSupDem = isPriceInsideSupplyZone || - isPriceInsideDemandZone; - if (isPriceInsideSupDem) - { - // - hasCondition = mConditions.HasWorkingZoneConditions( - conditionsDir, - decisionState // - ); - } - } + // // + // if (hasCondition) + // { + // // + // if (IsBullish(conditionsDir)) + // { + // // + // pivot = mConditions.demandZone.Lower(); + // point = mConditions.demandZone.Upper(); + // } + // else if (IsBearish(conditionsDir)) + // { + // // + // pivot = mConditions.supplyZone.Upper(); + // point = mConditions.supplyZone.Lower(); + // } + // } + // } + // } // isBullish = IsBullish(conditionsDir); @@ -630,11 +690,152 @@ class XCX121SMCXWZSignalDetector : public XCBase amountPercent // ); + // + bool hasLastBullishConsolidationZone = false; + bool hasLastBearishConsolidationZone = false; + bool hasPrevBullishConsolidationZone = false; + bool hasPrevBearishConsolidationZone = false; + XConsolidationZone lastBullishConsolidationZone; + XConsolidationZone lastBearishConsolidationZone; + XConsolidationZone prevBullishConsolidationZone; + XConsolidationZone prevBearishConsolidationZone; + bool hasConsolidationZones = decisionCycleHelper.HasConsolidationZones(); + if (hasConsolidationZones) + { + // + int cZCount = 0; + XConsolidationZone tmp[]; + + // + cZCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BULLISH, + tmp // + ); + if (IsValidSize(cZCount)) + { + // + lastBullishConsolidationZone = tmp[cZCount - 1]; + if (cZCount >= 2) + { + prevBullishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + cZCount = decisionCycleHelper + .FillConsolidationZones( + X_DIRECTION_BEARISH, + tmp // + ); + if (IsValidSize(cZCount)) + { + // + lastBearishConsolidationZone = tmp[cZCount - 1]; + if (cZCount >= 2) + { + prevBearishConsolidationZone = tmp[cZCount - 2]; + } + } + + // + Clean(tmp); + + // + hasLastBullishConsolidationZone = lastBullishConsolidationZone.IsValid(); + hasLastBearishConsolidationZone = lastBearishConsolidationZone.IsValid(); + hasPrevBullishConsolidationZone = prevBullishConsolidationZone.IsValid(); + hasPrevBearishConsolidationZone = prevBearishConsolidationZone.IsValid(); + } + + // + RemoveDraws(); + + // + if (hasLastBullishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + lastBullishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + if (hasLastBearishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + lastBearishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + if (hasPrevBullishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + prevBullishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + if (hasPrevBearishConsolidationZone) + { + // + XCConsolidationZoneObject *iObj; + bool isCreated = visionCycleHelper + .mPOIDrawer + .CreateConsolidationZone( + prevBearishConsolidationZone, + iObj // + ); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + bool isConsolidationZonePassed = + isBullish + ? (point > 0 && + hasPrevBullishConsolidationZone && + point >= prevBullishConsolidationZone.upper) + : (point > 0 && + hasPrevBearishConsolidationZone && + point <= prevBearishConsolidationZone.lower); + // result = hasCondition && hasRewardAmount && isPriorityPassed && - trend == conditionsDir; + trend == conditionsDir && + isConsolidationZonePassed; if (!result) { // @@ -664,6 +865,12 @@ class XCX121SMCXWZSignalDetector : public XCBase consolidationConditions.Clean(); consolidationXConditions.Clean(); + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + // mConditions.Clean(); @@ -718,18 +925,24 @@ class XCX121SMCXWZSignalDetector : public XCBase } // + mConditions.pivot = pivot; + mConditions.point = point; mConditions.reward = reward; mConditions.target = target; mConditions.setupTime = cTime; mConditions.priority = priority; mConditions.dir = conditionsDir; mConditions.amountPercent = amountPercent; - mConditions.pivot = mConditions.GetExit(); - mConditions.point = mConditions.GetPoint(); // mConditions.UpdateTo(cTime); + // + DrawConditions( + mConditions, + visionCycleHelper.mPOIDrawer // + ); + // Clean(visionPoiEvents); Clean(analysePoiEvents); @@ -757,6 +970,12 @@ class XCX121SMCXWZSignalDetector : public XCBase consolidationConditions.Clean(); consolidationXConditions.Clean(); + // + lastBullishConsolidationZone.Clean(); + lastBearishConsolidationZone.Clean(); + prevBullishConsolidationZone.Clean(); + prevBearishConsolidationZone.Clean(); + // return result; } @@ -929,16 +1148,18 @@ class XCX121SMCXWZSignalDetector : public XCBase // isBullish = // - isBullish && - isPointBreaked + isBullish + // && + // isPointBreaked // ; // isBearish = // - isBearish && - isPointBreaked + isBearish + // && + // isPointBreaked // ; @@ -2293,371 +2514,352 @@ class XCX121SMCXWZSignalDetector : public XCBase color bearishColor = drawer.BarBearishColor(); // - // Start Zone ... - bool hasStartZone = conditions.HasStartZone(); - if (hasStartZone) + // Start Zones ... + bool hasStartZones = conditions.HasStartZones(); + if (hasStartZones) { // - bool isBullish = conditions.startZone.IsBullish(); - - // - bool hasOB = conditions.startZone.HasOB(); - if (hasOB) + int count = conditions.CountStartZones(); + for (int i = 0; i < count; i++) { // - XCBaseObject *iObj; - isCreated = drawer.CreateOrderBlock( - conditions.startZone.ob, - iObj // - ); + bool isBullish = conditions.startZones[i].IsBullish(); // - if (isCreated) + bool hasOB = conditions.startZones[i].HasOB(); + if (hasOB) { - mObjects.Add(iObj); - } - } + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateOrderBlock( + // conditions.startZones[i].ob, + // iObj // + // ); - // - bool hasFVG = conditions.startZone.HasFVG(); - if (hasFVG) - { - // - XCBaseObject *iObj; - isCreated = drawer.CreateFairValueGap( - conditions.startZone.fvg, - iObj // - ); - - // - if (isCreated) - { - mObjects.Add(iObj); - } - } - - // - bool hasSupply = conditions.startZone.HasSupply(); - if (hasSupply) - { - // - XCSupplyZoneObject *iObj; - isCreated = drawer.CreateSupplyZone( - conditions.startZone.supply, - iObj // - ); - - // - if (isCreated) - { - mObjects.Add(iObj); - } - } - - // - bool hasDemand = conditions.startZone.HasDemand(); - if (hasDemand) - { - // - XCDemandZoneObject *iObj; - isCreated = drawer.CreateDemandZone( - conditions.startZone.demand, - iObj // - ); - - // - if (isCreated) - { - mObjects.Add(iObj); - } - } - - // - bool hasSupport = conditions.startZone.HasSupport(); - if (hasSupport) - { - // - XCSupportZoneObject *iObj; - isCreated = drawer.CreateSupportZone( - conditions.startZone.support, - iObj // - ); - - // - if (isCreated) - { - mObjects.Add(iObj); - } - } - - // - bool hasResistance = conditions.startZone.HasResistance(); - if (hasResistance) - { - // - XCResistanceZoneObject *iObj; - isCreated = drawer.CreateResistanceZone( - conditions.startZone.resistance, - iObj // - ); - - // - if (isCreated) - { - mObjects.Add(iObj); - } - } - - // - bool hasBullishCZone = conditions.startZone.HasBullishConsolidationZone(); - if (hasBullishCZone) - { - // - XCConsolidationZoneObject *iObj; - isCreated = drawer.CreateConsolidationZone( - conditions.startZone.bullishConsolidationZone, - iObj // - ); - - // - if (isCreated) - { - mObjects.Add(iObj); - } - } - - // - bool hasBearishCZone = conditions.startZone.HasBearishConsolidationZone(); - if (hasBearishCZone) - { - // - XCConsolidationZoneObject *iObj; - isCreated = drawer.CreateConsolidationZone( - conditions.startZone.bearishConsolidationZone, - iObj // - ); - - // - if (isCreated) - { - mObjects.Add(iObj); - } - } - - // - // - // - - // - string bName = ""; - int arrowCode = 0; - string bSuffix = ""; - color arrowColor = clrNONE; - ENUM_X_PRICE bPrice = X_PRICE_CLOSE; - - // - bool hasSwingBar = conditions.startZone.swingBar.IsValid(); - if (hasSwingBar) - { - // - bSuffix = ToMD5(conditions.startZone.swingBar.GetTag()); - bName = - (isBullish - ? "SWING_LOW" - : "SWING_HIGH") + - "_" + bSuffix; - arrowCode = 159; - arrowColor = - isBullish - ? bullishColor - : bearishColor; - bPrice = - isBullish - ? X_PRICE_LOW - : X_PRICE_HIGH; - - // - XCBarArrowObject *iObj; - iObj = new XCBarArrowObject(); - isCreated = iObj.CreateByBar( - chartID, - bName, - subWindow, - arrowCode, - conditions.startZone.swingBar, - bPrice // - ); - if (isCreated) - { - // - iObj.ArrowColor(arrowColor); + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } // - mObjects.Add(iObj); + DrawOrderBlock( + conditions.startZones[i].ob, + drawer // + ); } - } - - // - bool hasBreakerBar = conditions.startZone.breakerBar.IsValid(); - if (hasBreakerBar) - { - // - bSuffix = ToMD5(conditions.startZone.breakerBar.GetTag()); - bName = - (isBullish - ? "BULL_BREAKER" - : "BEAR_BREAKER") + - "_" + bSuffix; - arrowCode = - isBullish - ? 71 - : 72; - arrowColor = - isBullish - ? bullishColor - : bearishColor; - bPrice = - isBullish - ? X_PRICE_LOW - : X_PRICE_HIGH; // - XCBarArrowObject *iObj; - iObj = new XCBarArrowObject(); - isCreated = iObj.CreateByBar( - chartID, - bName, - subWindow, - arrowCode, - conditions.startZone.breakerBar, - bPrice // - ); - if (isCreated) + bool hasFVG = conditions.startZones[i].HasFVG(); + if (hasFVG) + { + // // + // XCBaseObject *iObj; + // isCreated = drawer.CreateFairValueGap( + // conditions.startZones[i].fvg, + // iObj // + // ); + + // // + // if (isCreated) + // { + // mObjects.Add(iObj); + // } + + // + DrawFairValueGap( + conditions.startZones[i].fvg, + drawer // + ); + } + + // + bool hasSupply = conditions.startZones[i].HasSupply(); + if (hasSupply) { // - iObj.ArrowColor(arrowColor); + XCSupplyZoneObject *iObj; + isCreated = drawer.CreateSupplyZone( + conditions.startZones[i].supply, + iObj // + ); // - mObjects.Add(iObj); + if (isCreated) + { + mObjects.Add(iObj); + } } - } - - // - bool hasMomentumBar = conditions.startZone.momentumBar.IsValid(); - if (hasMomentumBar) - { - // - bSuffix = ToMD5(conditions.startZone.momentumBar.GetTag()); - bName = - (isBullish - ? "BULL_MOMENTUM" - : "BEAR_MOMENTUM") + - "_" + bSuffix; - arrowCode = - isBullish - ? 233 - : 234; - arrowColor = - isBullish - ? bullishColor - : bearishColor; - bPrice = - isBullish - ? X_PRICE_LOW - : X_PRICE_HIGH; // - XCBarArrowObject *iObj; - iObj = new XCBarArrowObject(); - isCreated = iObj.CreateByBar( - chartID, - bName, - subWindow, - arrowCode, - conditions.startZone.momentumBar, - bPrice // - ); - if (isCreated) + bool hasDemand = conditions.startZones[i].HasDemand(); + if (hasDemand) { // - iObj.ArrowColor(arrowColor); + XCDemandZoneObject *iObj; + isCreated = drawer.CreateDemandZone( + conditions.startZones[i].demand, + iObj // + ); // - mObjects.Add(iObj); + if (isCreated) + { + mObjects.Add(iObj); + } } - } - - // - bool hasRejectionBar = conditions.startZone.rejectionBar.IsValid(); - if (hasRejectionBar) - { - // - bSuffix = ToMD5(conditions.startZone.rejectionBar.GetTag()); - bName = - (isBullish - ? "BULL_REJECTION" - : "BEAR_REJECTION") + - "_" + bSuffix; - arrowCode = - isBullish - ? 241 - : 242; - arrowColor = - isBullish - ? bullishColor - : bearishColor; - bPrice = - isBullish - ? X_PRICE_LOW - : X_PRICE_HIGH; // - XCBarArrowObject *iObj; - iObj = new XCBarArrowObject(); - isCreated = iObj.CreateByBar( - chartID, - bName, - subWindow, - arrowCode, - conditions.startZone.rejectionBar, - bPrice // - ); - if (isCreated) + bool hasSupport = conditions.startZones[i].HasSupport(); + if (hasSupport) { // - iObj.ArrowColor(arrowColor); + XCSupportZoneObject *iObj; + isCreated = drawer.CreateSupportZone( + conditions.startZones[i].support, + iObj // + ); // - mObjects.Add(iObj); + if (isCreated) + { + mObjects.Add(iObj); + } } - } - - // - bool hasAppliedBox = conditions.startZone.appliedBox.IsValid(); - if (hasAppliedBox) - { - // - arrowColor = - IsBullish(conditions.startZone.appliedBox.dir) - ? bullishColor - : bearishColor; // - XCBoxObject *iObj; - isCreated = drawer.CreateBox( - conditions.startZone.appliedBox, - iObj // - ); - - // - if (isCreated) + bool hasResistance = conditions.startZones[i].HasResistance(); + if (hasResistance) { // - iObj.BoxWidth(2); - iObj.BoxColor(arrowColor); + XCResistanceZoneObject *iObj; + isCreated = drawer.CreateResistanceZone( + conditions.startZones[i].resistance, + iObj // + ); // - mObjects.Add(iObj); + if (isCreated) + { + mObjects.Add(iObj); + } + } + + // + // + // + + // + string bName = ""; + int arrowCode = 0; + string bSuffix = ""; + color arrowColor = clrNONE; + ENUM_X_PRICE bPrice = X_PRICE_CLOSE; + + // + bool hasSwingBar = conditions.startZones[i].swingBar.IsValid(); + if (hasSwingBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].swingBar.GetTag()); + bName = + (isBullish + ? "SWING_LOW" + : "SWING_HIGH") + + "_" + bSuffix; + arrowCode = 159; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].swingBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasBreakerBar = conditions.startZones[i].breakerBar.IsValid(); + if (hasBreakerBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].breakerBar.GetTag()); + bName = + (isBullish + ? "BULL_BREAKER" + : "BEAR_BREAKER") + + "_" + bSuffix; + arrowCode = + isBullish + ? 71 + : 72; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].breakerBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasMomentumBar = conditions.startZones[i].momentumBar.IsValid(); + if (hasMomentumBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].momentumBar.GetTag()); + bName = + (isBullish + ? "BULL_MOMENTUM" + : "BEAR_MOMENTUM") + + "_" + bSuffix; + arrowCode = + isBullish + ? 233 + : 234; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].momentumBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasRejectionBar = conditions.startZones[i].rejectionBar.IsValid(); + if (hasRejectionBar) + { + // + bSuffix = ToMD5(conditions.startZones[i].rejectionBar.GetTag()); + bName = + (isBullish + ? "BULL_REJECTION" + : "BEAR_REJECTION") + + "_" + bSuffix; + arrowCode = + isBullish + ? 241 + : 242; + arrowColor = + isBullish + ? bullishColor + : bearishColor; + bPrice = + isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *iObj; + iObj = new XCBarArrowObject(); + isCreated = iObj.CreateByBar( + chartID, + bName, + subWindow, + arrowCode, + conditions.startZones[i].rejectionBar, + bPrice // + ); + if (isCreated) + { + // + iObj.ArrowColor(arrowColor); + + // + mObjects.Add(iObj); + } + } + + // + bool hasAppliedBox = conditions.startZones[i].appliedBox.IsValid(); + if (hasAppliedBox) + { + // + arrowColor = + IsBullish(conditions.startZones[i].appliedBox.dir) + ? bullishColor + : bearishColor; + + // + XCBoxObject *iObj; + isCreated = drawer.CreateBox( + conditions.startZones[i].appliedBox, + iObj // + ); + + // + if (isCreated) + { + // + iObj.BoxWidth(2); + iObj.BoxColor(arrowColor); + + // + mObjects.Add(iObj); + } } } } @@ -2696,44 +2898,6 @@ class XCX121SMCXWZSignalDetector : public XCBase // // Helpers ... - // - bool CheckPriceInside( - XOHCL &zBar, - XOHCL &cBar, - double upper, - double lower // - ) - { - // - bool result = false; - - // - result = zBar.IsValid() && - cBar.IsValid() && - upper > 0 && - lower > 0 && - upper > lower && - zBar.time > cBar.time; - if (!result) - { - return result; - } - - // - result = - // - zBar.high < upper && - cBar.high < upper && - // - zBar.low > lower && - cBar.low > lower - // - ; - - // - return result; - } - // bool CalculateRiskReward( ENUM_X121SMC_XWZ_PRIORITY priority, diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 index c68def31..00cd98e9 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 @@ -48,8 +48,6 @@ struct X121SMCXWZZone XCDemandZone *demand; XCSupportZone *support; XCResistanceZone *resistance; - XConsolidationZone bullishConsolidationZone; - XConsolidationZone bearishConsolidationZone; // XOHCL swingBar; @@ -85,10 +83,6 @@ struct X121SMCXWZZone appliedBox.Clean(); momentumBar.Clean(); rejectionBar.Clean(); - - // - bullishConsolidationZone.Clean(); - bearishConsolidationZone.Clean(); } // @@ -214,22 +208,6 @@ struct X121SMCXWZZone resistance.IsValid(); } - // - bool HasBullishConsolidationZone() - { - return bullishConsolidationZone.IsValid() && - bullishConsolidationZone.IsBreaked() && - IsBullish(bullishConsolidationZone.breakDir); - } - - // - bool HasBearishConsolidationZone() - { - return bearishConsolidationZone.IsValid() && - bearishConsolidationZone.IsBreaked() && - IsBullish(bearishConsolidationZone.breakDir); - } - // bool IsBullish() { @@ -237,9 +215,7 @@ struct X121SMCXWZZone return HasOB() && ob.IsBullish() && HasFVG() && - fvg.IsBullish() && - HasSupport() && - HasDemand(); + fvg.IsBullish(); } // @@ -249,9 +225,7 @@ struct X121SMCXWZZone return HasOB() && ob.IsBearish() && HasFVG() && - fvg.IsBearish() && - HasSupply() && - HasResistance(); + fvg.IsBearish(); } // @@ -340,6 +314,17 @@ struct X121SMCXWZZone barIndex // ); + // + bool isInside = IsPriceInside( + barIndex, + forPeriod // + ); + result = isInside; + if (!result) + { + return result; + } + // XBoxZone box; result = AsBox(box); @@ -1141,6 +1126,167 @@ struct X121SMCXWZZone return result; } + // + bool IsPriceInside( + int barIndex = 0, + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = IsValid() && + HasOB() && + HasFVG() && + HasDirection(); + if (!result) + { + return result; + } + + // + string symbol = ob.GetSymbol(); + if (forPeriod == NULL) + { + forPeriod = ob.GetPeriod(); + } + + // + ENUM_X_DIRECTION forDir = ob.GetDirection(); + bool isBullish = IsBullish(forDir); + + // + // Check Start Bars ... + + // + XOHCL obStartedBar; + ENUM_X_DIRECTION obStartedDir; + bool isOBStarted = ob.IsStarted( + forDir, + obStartedBar, + obStartedDir // + ); + result = isOBStarted; + if (!result) + { + return result; + } + + // + XOHCL fvgStartedBar; + ENUM_X_DIRECTION fvgStartedDir; + bool isFVGStarted = fvg.IsStarted( + forDir, + fvgStartedBar, + fvgStartedDir // + ); + result = isFVGStarted; + if (!result) + { + return result; + } + + // + // Get Zone Box ... + XBoxZone box; + bool hasBox = AsBox(box); + result = hasBox; + if (!result) + { + // + box.Clean(); + + // + return result; + } + + // + // Retrieve Bars ... + + // + XOHCL zBar; + result = zBar.Init( + symbol, + forPeriod, + barIndex // + ); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + + // + return result; + } + + // + XOHCL cBar; + result = zBar.GetPreviousBar(cBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + + // + return result; + } + + // + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + result = + // + isBullish + ? ( + // + pBar.low > box.upper && + cBar.low <= box.upper && + zBar.open <= box.upper + // + ) + : ( + // + pBar.high < box.lower && + cBar.high >= box.lower && + zBar.open >= box.lower + // + ) + // + ; + + // + box.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + // }; @@ -1242,140 +1388,6 @@ struct X121SMCXWZWorkingZone 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, @@ -1491,7 +1503,8 @@ struct X121SMCStrategyXWZSignalConditions X121SMCXWZWorkingZone workingZone; // - X121SMCXWZZone startZone; + // X121SMCXWZZone startZone; + X121SMCXWZZone startZones[]; // // Constructor ... @@ -1632,7 +1645,8 @@ struct X121SMCStrategyXWZSignalConditions ZeroMemory(fairValueGap); // - startZone.Clean(); + // startZone.Clean(); + Clean(startZones); // workingZone.Clean(); @@ -1677,9 +1691,15 @@ struct X121SMCStrategyXWZSignalConditions } // - bool HasStartZone() + bool HasStartZones() { - return startZone.IsValid(); + return HasChild(startZones); + } + + // + int CountStartZones() + { + return ArraySize(startZones); } // @@ -1726,63 +1746,54 @@ struct X121SMCStrategyXWZSignalConditions // // Start Zone ... - bool hasStartZone = HasStartZone(); - if (hasStartZone) + bool hasStartZones = HasStartZones(); + if (hasStartZones) { // - bool hasOB = startZone.HasOB(); - if (hasOB) + int count = CountStartZones(); + for (int i = 0; i < count; i++) { - startZone.ob.To(value); - } + // + bool hasOB = startZones[i].HasOB(); + if (hasOB) + { + startZones[i].ob.To(value); + } - // - bool hasFVG = startZone.HasFVG(); - if (hasFVG) - { - startZone.fvg.To(value); - } + // + bool hasFVG = startZones[i].HasFVG(); + if (hasFVG) + { + startZones[i].fvg.To(value); + } - // - bool hasSupply = startZone.HasSupply(); - if (hasSupply) - { - startZone.supply.To(value); - } + // + bool hasSupply = startZones[i].HasSupply(); + if (hasSupply) + { + startZones[i].supply.To(value); + } - // - bool hasDemand = startZone.HasDemand(); - if (hasDemand) - { - startZone.demand.To(value); - } + // + bool hasDemand = startZones[i].HasDemand(); + if (hasDemand) + { + startZones[i].demand.To(value); + } - // - bool hasSupport = startZone.HasSupport(); - if (hasSupport) - { - startZone.support.To(value); - } + // + bool hasSupport = startZones[i].HasSupport(); + if (hasSupport) + { + startZones[i].support.To(value); + } - // - bool hasResistance = startZone.HasResistance(); - if (hasResistance) - { - startZone.resistance.To(value); - } - - // - bool hasBullishCZone = startZone.HasBullishConsolidationZone(); - if (hasBullishCZone) - { - // startZone.bullishConsolidationZone.to = cTime; - } - - // - bool hasBearishCZone = startZone.HasBearishConsolidationZone(); - if (hasBearishCZone) - { - // startZone.bearishConsolidationZone.to = cTime; + // + bool hasResistance = startZones[i].HasResistance(); + if (hasResistance) + { + startZones[i].resistance.To(value); + } } } } @@ -2698,7 +2709,7 @@ struct X121SMCStrategyXWZSignalConditions } // - bool DetectStartZone( + bool DetectStartZones( ENUM_X_DIRECTION forDir, XPOIState &state, XC121SMCCycleHelper *cycleHelper // @@ -2725,136 +2736,340 @@ struct X121SMCStrategyXWZSignalConditions int has = false; // - bool hasBullishCZone = false; - bool hasBearishCZone = false; - - // - // Supply Zones ... - has = state.HasSupplyZones(); - if (has) + X121SMCXWZZone startZone; + X121SMCXWZZone lastStartZone; + bool hasLastStartZone = HasStartZones(); + if (hasLastStartZone) { // - idx = GetYoungest(state.supplyZones); - if (IsValidIndex(idx)) - { - startZone.supply = state.supplyZones[idx]; - } + int startZonesCount = CountStartZones(); + lastStartZone = startZones[startZonesCount - 1]; } // - // Demand Zones ... - has = state.HasDemandZones(); - if (has) - { - // - idx = GetYoungest(state.demandZones); - if (IsValidIndex(idx)) - { - startZone.demand = state.demandZones[idx]; - } - } - - // - // Support Zones ... - has = state.HasSupportZones(); - if (has) - { - // - idx = GetYoungest(state.supportZones); - if (IsValidIndex(idx)) - { - startZone.support = state.supportZones[idx]; - } - } - - // - // Resistance Zones ... - has = state.HasResistanceZones(); - if (has) - { - // - idx = GetYoungest(state.resistanceZones); - if (IsValidIndex(idx)) - { - startZone.resistance = state.resistanceZones[idx]; - } - } - - // - // Consolidation Zones ... - has = cycleHelper.HasConsolidationZones(); - if (has) - { - // - hasBullishCZone = cycleHelper - .GetLastDirectionalConsolidationZone( - X_DIRECTION_BULLISH, - startZone.bullishConsolidationZone // - ); - - // - hasBearishCZone = cycleHelper - .GetLastDirectionalConsolidationZone( - X_DIRECTION_BEARISH, - startZone.bearishConsolidationZone // - ); - } - - // - // Other Zones ... if (isBullish) { // - // Order Block ... has = state.HasBullishOrderBlocks(); if (has) { // - idx = GetYoungest(state.bullishOrderBlocks); - if (IsValidIndex(idx)) + count = state.CountBullishOrderBlocks(); + for (int i = 0; i < count; i++) { - startZone.ob = state.bullishOrderBlocks[idx]; - } - } + // + XCOrderBlock *iOB = state.bullishOrderBlocks[i]; - // - // Fair Value Gap ... - has = state.HasBullishFairValueGaps(); - if (has) - { - // - idx = GetYoungest(state.bullishFairValueGaps); - if (IsValidIndex(idx)) - { - startZone.fvg = state.bullishFairValueGaps[idx]; + // + bool isFromPassed = + !hasLastStartZone + ? true + : iOB.From() > lastStartZone.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(iOB); + continue; + } + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + continue; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = iOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + bool isPlacePassed = + !hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsAbove( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsAbove( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + ); + if (!isPlacePassed) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Attache OB ... + startZone.ob = iOB; + + // + // Now we Have to Find Specified FVG ... + has = state.HasBullishFairValueGaps(); + if (has) + { + // + int jCount = state.CountBullishFairValueGaps(); + for (int j = 0; j < jCount; j++) + { + // + XCFVG *jFVG = state.bullishFairValueGaps[j]; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + isStarted = jFVG.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + continue; + } + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + isActivated = jFVG.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + isPlacePassed = + // + IsAboveDiff( + jFVG, + iOB, + true // Ignore Inside ... + ) + // + ; + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + } + + // + startZone.fvg = jFVG; + } + } + + // + startedBar.Clean(); + activatedBar.Clean(); } } } else { // - // Order Block ... has = state.HasBearishOrderBlocks(); if (has) { // - idx = GetYoungest(state.bearishOrderBlocks); - if (IsValidIndex(idx)) + count = state.CountBearishOrderBlocks(); + for (int i = 0; i < count; i++) { - startZone.ob = state.bearishOrderBlocks[idx]; - } - } + // + XCOrderBlock *iOB = state.bearishOrderBlocks[i]; - // - // Fair Value Gap ... - has = state.HasBearishFairValueGaps(); - if (has) - { - // - idx = GetYoungest(state.bearishFairValueGaps); - if (IsValidIndex(idx)) - { - startZone.fvg = state.bearishFairValueGaps[idx]; + // + bool isFromPassed = + !hasLastStartZone + ? true + : iOB.From() > lastStartZone.ob.From(); + if (!isFromPassed) + { + // + ZeroMemory(iOB); + continue; + } + + // + XOHCL startedBar; + ENUM_X_DIRECTION startedDir; + bool isStarted = iOB.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + continue; + } + + // + XOHCL activatedBar; + ENUM_X_DIRECTION activatedDir; + bool isActivated = iOB.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + bool isPlacePassed = + !hasLastStartZone + ? workingZone.IsValid() && + HasOrderBlock() && + forDir == orderBlock.GetDirection() + ? IsBelow( + iOB, + orderBlock, + true // Ignore Inside ... + ) + : true + : lastStartZone.HasOB() && + IsBelow( + iOB, + lastStartZone.ob, + true // Ignore Inside ... + ); + if (!isPlacePassed) + { + // + ZeroMemory(iOB); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + // Attache OB ... + startZone.ob = iOB; + + // + // Now we Have to Find Specified FVG ... + has = state.HasBearishFairValueGaps(); + if (has) + { + // + int jCount = state.CountBearishFairValueGaps(); + for (int j = 0; j < jCount; j++) + { + // + XCFVG *jFVG = state.bearishFairValueGaps[j]; + + // + startedBar.Clean(); + startedDir = X_DIRECTION_NONE; + isStarted = jFVG.IsStarted( + forDir, + startedBar, + startedDir // + ); + if (!isStarted) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + continue; + } + + // + activatedBar.Clean(); + activatedDir = X_DIRECTION_NONE; + isActivated = jFVG.IsActivated( + forDir, + activatedBar, + activatedDir // + ); + if (isActivated) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + continue; + } + + // + isPlacePassed = + // + IsBelowDiff( + jFVG, + iOB, + true // Ignore Inside ... + ) + // + ; + if (!isPlacePassed) + { + // + ZeroMemory(jFVG); + startedBar.Clean(); + activatedBar.Clean(); + } + + // + startZone.fvg = jFVG; + } + } + + // + startedBar.Clean(); + activatedBar.Clean(); } } } @@ -2862,114 +3077,253 @@ struct X121SMCStrategyXWZSignalConditions // bool hasOBFVG = startZone.HasOB() && startZone.HasFVG(); - bool isOBStarted = false; - bool isFVGStarted = false; - bool isOBActivated = false; - bool isFVGActivated = false; - bool isOBInsideFVG = false; - bool isFVGInsideOB = false; - if (hasOBFVG) - { - // - - // - ENUM_X_DIRECTION forDir = startZone.ob.GetDirection(); - - // - XOHCL startedBar; - ENUM_X_DIRECTION startedDir; - - // - isOBStarted = startZone.ob.IsStarted( - forDir, - startedBar, - startedDir // - ); - - // - isOBActivated = startZone.ob.IsActivated( - forDir, - startedBar, - startedDir // - ); - - // - forDir = startZone.fvg.GetDirection(); - - // - isFVGStarted = startZone.fvg.IsStarted( - forDir, - startedBar, - startedDir // - ); - - // - isFVGActivated = startZone.fvg.IsActivated( - forDir, - startedBar, - startedDir // - ); - - // - isOBInsideFVG = - IsInsideDiff( - startZone.ob, - startZone.fvg // - ) || - (isBullish - ? IsAboveDiff( - startZone.ob, - startZone.fvg, - true // IgnoreInside - ) - : IsBelowDiff( - startZone.ob, - startZone.fvg, - true // IgnoreInside - )); - // - isFVGInsideOB = - IsInsideDiff( - startZone.fvg, - startZone.ob // - ) || - (isBullish - ? IsAboveDiff( - startZone.fvg, - startZone.ob, - true // IgnoreInside - ) - : IsBelowDiff( - startZone.fvg, - startZone.ob, - true // IgnoreInside - )); - - // - startedBar.Clean(); - } - - // - result = - isOBStarted && - isFVGStarted && - isOBActivated && - isFVGActivated && - startZone.IsValid() && - (isOBInsideFVG || - isFVGInsideOB) && - (isBullish - ? startZone.IsBullish() - : startZone.IsBearish()); + result = hasOBFVG; if (!result) { // startZone.Clean(); + lastStartZone.Clean(); // return result; } + // + XBoxZone startBox; + bool hasStartBox = startZone.AsBox(startBox); + result = hasStartBox; + if (!result) + { + // + startBox.Clean(); + startZone.Clean(); + lastStartZone.Clean(); + + // + return result; + } + + // + // Detect Other Zones Inside Box ... + XBoxZone tmpBoxes[]; + + // + // Supply Zones ... + has = state.HasSupplyZones(); + if (has) + { + // + count = ToBox( + state.supplyZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.supply = state.supplyZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Demand Zones ... + Clean(tmpBoxes); + has = state.HasDemandZones(); + if (has) + { + // + count = ToBox( + state.demandZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.demand = state.demandZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Support Zones ... + Clean(tmpBoxes); + has = state.HasSupportZones(); + if (has) + { + // + count = ToBox( + state.supportZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.support = state.supportZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + // Resistance Zones ... + Clean(tmpBoxes); + has = state.HasResistanceZones(); + if (has) + { + // + count = ToBox( + state.resistanceZones, + tmpBoxes // + ); + + // + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + bool isPlacePassed = + // + IsBoxInside( + iBox, + startBox, + false, + false // + ) + // + ; + if (!isPlacePassed) + { + // + iBox.Clean(); + continue; + } + + // + startZone.resistance = state.resistanceZones[i]; + + // + iBox.Clean(); + break; + } + } + } + + // + result = startZone.IsValid() && + startZone.HasDirection(); + if (result) + { + // + AddRef( + startZone, + startZones // + ); + } + + // + Clean(tmpBoxes); + startBox.Clean(); + startZone.Clean(); + lastStartZone.Clean(); + // return result; } @@ -3103,7 +3457,7 @@ struct X121SMCStrategyXWZSignalConditions } // - bool HasWorkingZoneConditions( + bool HasConditions( ENUM_X_DIRECTION &conditionsDir, XPOIState &state, int barIndex = 0, @@ -3113,6 +3467,9 @@ struct X121SMCStrategyXWZSignalConditions // bool result = false; + // + conditionsDir = X_DIRECTION_NONE; + // if (barIndex < 0) { @@ -3120,244 +3477,79 @@ struct X121SMCStrategyXWZSignalConditions } // - conditionsDir = X_DIRECTION_NONE; - - // - result = HasWorkingZone(); - if (!result) - { - return result; - } - - // - XBoxZone appliedBox; - - // - // Clean Condition Bars ... - workingZone.CleanConditionBars(); - - // - // Validate ... - result = state.IsValid() && - state.HasChild(); - if (!result) - { - // - workingZone.CleanConditionBars(); - return result; - } - - // - if (!IsValid(forPeriod)) + if (forPeriod == NULL) { forPeriod = period; } // - datetime cTime = iTime( - symbol, - forPeriod, - barIndex // - ); - - // - // Check Supply Zone ... - - // - XBoxZone supplyBox; - bool hasSupplyBox = - supplyZone != NULL && - supplyZone.IsValid() && - ToBox( - supplyBox, - supplyZone // - ); - if (hasSupplyBox) + result = + // + IsValid(symbol) && + IsValid(period) && + state.IsValid() && + HasWorkingZone() && + state.HasChild() + // + ; + if (!result) { - // - result = CheckBoxForTradeConditions( - supplyBox, - appliedBox, - workingZone.swingBar, - workingZone.breakerBar, - workingZone.rejectionBar, - workingZone.momentumBar, - state, - barIndex, - forPeriod // - ); - - // - if (result) - { - conditionsDir = X_DIRECTION_BEARISH; - } + return result; } // - // Check Demand Zone ... - XBoxZone demandBox; - bool hasDemandBox = false; - if (!result) + // Detect Conditions Based On Start Zones ... + bool hasStartZones = HasStartZones(); + if (hasStartZones) { // - hasDemandBox = - demandZone != NULL && - demandZone.IsValid() && - ToBox( - demandBox, - demandZone // - ); - if (hasDemandBox) + int count = CountStartZones(); + for (int i = 0; i < count; i++) { // - result = CheckBoxForTradeConditions( - demandBox, - appliedBox, - workingZone.swingBar, - workingZone.breakerBar, - workingZone.rejectionBar, - workingZone.momentumBar, + X121SMCXWZZone iStartZone = startZones[i]; + + // + bool isPriceInside = iStartZone.IsPriceInside( + barIndex, + forPeriod // + ); + if (!isPriceInside) + { + // + iStartZone.Clean(); + continue; + } + + // + Print("PriceInside ..."); + + // + bool hasConditions = iStartZone.HasCondition( state, barIndex, forPeriod // ); + if (!hasConditions) + { + // + iStartZone.Clean(); + continue; + } // - if (result) - { - conditionsDir = X_DIRECTION_BULLISH; - } + iStartZone.Clean(); } } // + // Detect Conditions Based On Working Zones ... if (!result) { - workingZone.CleanConditionBars(); + // + // Detect Result Based On WorkingZone ... } - // - supplyBox.Clean(); - demandBox.Clean(); - appliedBox.Clean(); - - // - return result; - } - - // - double GetEntry() - { - // - double result = 0; - - // - if (!IsValid(symbol) || - !HasDirection(dir)) - { - return result; - } - - // - result = GetEntry( - symbol, - dir // - ); - - // - return result; - } - - // - double GetSpread() - { - // - double result = 0; - - // - if (!IsValid(symbol)) - { - return result; - } - - // - result = GetSpread( - symbol // - ); - - // - return result; - } - - // - double GetPoint() - { - // - double result = 0; - - // - if (!IsValid(symbol) || - !HasDirection(dir) || - !HasStartZone()) - { - return result; - } - - // - bool isBullish = IsBullish(dir); - XBoxZone asBox; - bool hasBox = startZone.AsBox(asBox); - if (!hasBox) - { - return result; - } - - // - result = - isBullish - ? asBox.upper - : asBox.lower; - - // - asBox.Clean(); - - // - return result; - } - - // - double GetExit() - { - // - double result = 0; - - // - if (!IsValid(symbol) || - !HasDirection(dir) || - !HasStartZone()) - { - return result; - } - - // - bool isBullish = IsBullish(dir); - XBoxZone asBox; - bool hasBox = startZone.AsBox(asBox); - if (!hasBox) - { - return result; - } - - // - result = - isBullish - ? asBox.lower - : asBox.upper; - - // - asBox.Clean(); - // return result; }