diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index 24ebc11b..dd73d364 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -38,7 +38,7 @@ input string eaLogSuffix = ""; // Log Suffix // // Symbols ... input group "Symbols"; -input bool eaMultiSymbol = false; // Use Multi Symbol +input bool eaMultiSymbol = false; // Use Multi Symbol input string eaSymbols = "EURUSDb,GBPUSDb,USDCHFb,USDJPYb,XAUUSDb"; // Trading Symbols // @@ -58,25 +58,25 @@ input int eaMinRequiredVerificationForSpreadPass = 20; // Minimum Spread Ver // Trade ... input group "Trade"; input bool eaAllowTrade = true; // Allow Open Trade On Signals -input string eaStartTradeAt = "2:00"; // Enable Trade on Signals on Time -input string eaStopTradeAt = "21:00"; // Enable Trade on Signals on Time +input string eaStartTradeAt = ""; // Enable Trade on Signals on Time +input string eaStopTradeAt = ""; // Enable Trade on Signals on Time input string eaCloseAllTradesAt = ""; // Enable Close All Trades on Signals on Time // // Risk Management ... input group "Risk Management"; -input double eaR2R = 4; // Signallers Risk to Reward Ratio -input double eaVolume = 0; // Static Volume -input double eaStaticBalance = 1000; // Static Balance -input double eaBalancePerTrade = 10; // Balance Used in Each Trade -input double eaRiskPercentPerBalance = 0; // Risk Percent Per Balance in Each Trade -input bool eaDynamicRiskManagement = false; // Dynamic Risk Management -input bool eaUseDynamicVolume = false; // Use Dynamic Volume -input double eaDynamicVolumeStep = 0.01; // Increase Volume Step -input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume -input double eaMaxAllowedDrawdownToOpenTrades = 3; // Max Allowed Drawdown for Open Trades -input int eaMaxAllowedSLToPauseSignallingPerSymbol = 2; // Max Allowed SL for Pause Signalling Per Symbol -input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 7200; // Pause Signalling Per Symbol afte Max Allowed SL Reached In Seconds +input double eaR2R = 6; // Signallers Risk to Reward Ratio +input double eaVolume = 0; // Static Volume +input double eaStaticBalance = 1000; // Static Balance +input double eaBalancePerTrade = 10; // Balance Used in Each Trade +input double eaRiskPercentPerBalance = 0; // Risk Percent Per Balance in Each Trade +input bool eaDynamicRiskManagement = false; // Dynamic Risk Management +input bool eaUseDynamicVolume = false; // Use Dynamic Volume +input double eaDynamicVolumeStep = 0.01; // Increase Volume Step +input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume +input double eaMaxAllowedDrawdownToOpenTrades = 3; // Max Allowed Drawdown for Open Trades +input int eaMaxAllowedSLToPauseSignallingPerSymbol = 2; // Max Allowed SL for Pause Signalling Per Symbol +input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 10800; // Pause Signalling Per Symbol afte Max Allowed SL Reached In Seconds // // Protection ... @@ -84,7 +84,7 @@ input group "Protection"; input bool eaAllowHedging = true; // Allow Hedge Positions input int eaMinOpenTradesFroHedging = 4; // Minimum Open Positions for Hedging input double eaHedgingMinVolumeStep = 0.01; // Minimum Volume Step for Hedging -input double eaHedgeingMinRequiredProfitPerVolumeStep = 2.0; // Minimum Required Profit Per Volume Step for Hedging +input double eaHedgeingMinRequiredProfitPerVolumeStep = 4.0; // Minimum Required Profit Per Volume Step for Hedging // // Alert ... @@ -265,7 +265,7 @@ void OnTick() // Handle On Trade Event ... void OnTrade() { - eaExpert.HandleOnTrade(); + eaExpert.HandleOnTrade(); } // diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 8c26e79f..3ff5c464 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -6773,6 +6773,52 @@ double GetFibonacciLevel( return result; } +// +double GetFibonacciLevel( + double mUp, + double mDown, + ENUM_X_FIBO_LEVELS mLevel, + ENUM_X_DIRECTION mForDir // +) +{ + // + double result = 0; + + // + double levelValue = GetFiboLevelValue(mLevel); + + // + bool isValid = + // + mUp > 0 && + mDown > 0 && + levelValue > 0 && + mUp > mDown && + HasDirection(mForDir) + // + ; + if (!isValid) + { + return result; + } + + // + bool isBullish = IsBullish(mForDir); + + // + double ling = mUp - mDown; + double pLevel = (ling / 100) * (levelValue * 100); + + // + result = + isBullish + ? mUp - pLevel + : mDown + pLevel; + + // + return result; +} + // // Method 1 // Normalize between 1 and 0 ... diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 2dacb638..7a06918e 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -6023,7 +6023,7 @@ struct XBoxZone lower > 0 && from < to && IsValid(to) && - upper > lower && + upper >= lower && IsValid(from) && IsValid(symbol) && IsValid(period) diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index 680898ad..71081081 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -992,6 +992,22 @@ class XC121SMCExpert : public XCBaseExpert false // ignore Policies ... ); } + else + { + // + string msg = "Failed To Execute " + + (IsLong(signal.type) + ? "Long" + : "Short") + + " Signal Recieved: (" + + signal.provider + "," + + signal.symbol + "," + + ToString(signal.period) + + ") due Trading offTime ..."; + + // + Alert(msg); + } } else { diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 index 881aa505..b95174ea 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.class.mq5 @@ -84,6 +84,14 @@ class XCX121SMCXWZSignalDetector : public XCBase ; if (!result) { + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // return result; } @@ -134,6 +142,14 @@ class XCX121SMCXWZSignalDetector : public XCBase ); if (!result) { + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // return result; } @@ -151,6 +167,14 @@ class XCX121SMCXWZSignalDetector : public XCBase ); if (!result) { + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // return result; } @@ -168,6 +192,14 @@ class XCX121SMCXWZSignalDetector : public XCBase ); if (!result) { + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // return result; } @@ -185,6 +217,14 @@ class XCX121SMCXWZSignalDetector : public XCBase ); if (!result) { + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + + // return result; } @@ -247,6 +287,13 @@ class XCX121SMCXWZSignalDetector : public XCBase consolidationConditions.Clean(); consolidationXConditions.Clean(); + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + // return result; } @@ -283,6 +330,13 @@ class XCX121SMCXWZSignalDetector : public XCBase consolidationConditions.Clean(); consolidationXConditions.Clean(); + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + // return result; } @@ -319,6 +373,13 @@ class XCX121SMCXWZSignalDetector : public XCBase consolidationConditions.Clean(); consolidationXConditions.Clean(); + // + RemoveDraws(); + RemoveWorkingZoneDraws(); + + // + mConditions.Clean(); + // return result; } @@ -338,7 +399,8 @@ class XCX121SMCXWZSignalDetector : public XCBase hasWorkingZone = mConditions.ExtractWorkingZone( visionState, consolidationState, - analyseState // + analyseState, + zIndex // ); } @@ -346,11 +408,47 @@ class XCX121SMCXWZSignalDetector : public XCBase 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); + // // TODO: Remove ... RemoveWorkingZoneDraws(); @@ -377,14 +475,269 @@ class XCX121SMCXWZSignalDetector : public XCBase 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; } // - Print(""); + // 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; + } // - return false; + // Detect Start Zones ... + bool hasStartZone = mConditions.HasStartZone(); + if (!hasStartZone) + { + // + hasStartZone = mConditions.DetectStartZone( + trend, + analyseState, + decisionCycleHelper // + ); + } + + // + result = hasStartZone; + 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); + + // + // TODO: Remove This ... + RemoveDraws(); + DrawConditions( + mConditions, + visionCycleHelper.mPOIDrawer // + ); + + // + // Detect Start Zone Conditions ... + bool hasCondition = mConditions + .startZone + .HasCondition( + decisionState, + zIndex, + period // + ); + ENUM_X_DIRECTION conditionsDir = mConditions + .startZone + .GetDirection(); + + // + result = hasCondition && + trend == conditionsDir; + 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.setupTime = cTime; + mConditions.dir = conditionsDir; + mConditions.pivot = mConditions.GetExit(); + mConditions.point = mConditions.GetPoint(); + isBullish = mConditions.startZone.IsBullish(); + isBearish = mConditions.startZone.IsBearish(); + result = isBullish || + isBearish; + + // + mConditions.UpdateTo(cTime); + + // + // TODO: Remove This ... + RemoveDraws(); + 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(); + + // + // RemoveDraws(); + // RemoveWorkingZoneDraws(); // return result; @@ -558,16 +911,18 @@ class XCX121SMCXWZSignalDetector : public XCBase // isBullish = // - isBullish && - isPointBreaked + isBullish + // && + // isPointBreaked // ; // isBearish = // - isBearish && - isPointBreaked + isBearish + // && + // isPointBreaked // ; @@ -626,7 +981,7 @@ class XCX121SMCXWZSignalDetector : public XCBase // double iAtr = decisionXConditions.atrBuffer[1]; - iAtr *= 2; + iAtr *= 1.5; // double slsMin = GetMin(sls); @@ -695,6 +1050,10 @@ class XCX121SMCXWZSignalDetector : public XCBase // ; + // + // TODO: Implement Guards ... + return false; + // result = isCycleHelpersValid; if (!result) @@ -1428,7 +1787,8 @@ class XCX121SMCXWZSignalDetector : public XCBase // void DrawOrderBlock( XCOrderBlock *ob, - XCPOIDrawer *drawer // + XCPOIDrawer *drawer, + bool forWorkingZone = false // ) { // @@ -1457,7 +1817,15 @@ class XCX121SMCXWZSignalDetector : public XCBase ); if (isCreated) { - mObjects.Add(obj); + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } } // @@ -1497,7 +1865,14 @@ class XCX121SMCXWZSignalDetector : public XCBase obj.LowShadowStyle(STYLE_SOLID); // - mObjects.Add(obj); + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } } // @@ -1518,7 +1893,14 @@ class XCX121SMCXWZSignalDetector : public XCBase startVLine.Color(forColor); // - mObjects.Add(startVLine); + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } } } } @@ -1526,7 +1908,8 @@ class XCX121SMCXWZSignalDetector : public XCBase // void DrawFairValueGap( XCFVG *fvg, - XCPOIDrawer *drawer // + XCPOIDrawer *drawer, + bool forWorkingZone = false // ) { // @@ -1555,7 +1938,15 @@ class XCX121SMCXWZSignalDetector : public XCBase ); if (isCreated) { - mObjects.Add(obj); + // + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } } // @@ -1595,7 +1986,14 @@ class XCX121SMCXWZSignalDetector : public XCBase obj.LowShadowStyle(STYLE_SOLID); // - mObjects.Add(obj); + if (forWorkingZone) + { + mWorkingZoneObjects.Add(obj); + } + else + { + mObjects.Add(obj); + } } // @@ -1616,7 +2014,14 @@ class XCX121SMCXWZSignalDetector : public XCBase startVLine.Color(forColor); // - mObjects.Add(startVLine); + if (forWorkingZone) + { + mWorkingZoneObjects.Add(startVLine); + } + else + { + mObjects.Add(startVLine); + } } } } @@ -1662,7 +2067,7 @@ class XCX121SMCXWZSignalDetector : public XCBase // bool isCreated = false; - + // // Check For Trend Approced ... bool isTrendApproved = conditions.HasOrderBlock() && @@ -1672,13 +2077,15 @@ class XCX121SMCXWZSignalDetector : public XCBase // DrawOrderBlock( conditions.orderBlock, - drawer // + drawer, + true // ); // DrawFairValueGap( conditions.fairValueGap, - drawer // + drawer, + true // ); } @@ -1706,12 +2113,15 @@ class XCX121SMCXWZSignalDetector : public XCBase // // Lower ... - CChartObjectHLine *lowerHLine; - lowerHLine = new CChartObjectHLine(); + 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) @@ -1722,12 +2132,15 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - CChartObjectHLine *upperHLine; - upperHLine = new CChartObjectHLine(); + 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) @@ -1738,12 +2151,15 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - CChartObjectHLine *zoneLowerHLine; - zoneLowerHLine = new CChartObjectHLine(); + 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) @@ -1754,12 +2170,15 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - CChartObjectHLine *zoneUpperHLine; - zoneUpperHLine = new CChartObjectHLine(); + 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) @@ -1770,12 +2189,15 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - CChartObjectHLine *quarter1HLine; - quarter1HLine = new CChartObjectHLine(); + 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) @@ -1786,12 +2208,15 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - CChartObjectHLine *quarter2HLine; - quarter2HLine = new CChartObjectHLine(); + 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) @@ -1802,12 +2227,15 @@ class XCX121SMCXWZSignalDetector : public XCBase } // - CChartObjectHLine *quarter3HLine; - quarter3HLine = new CChartObjectHLine(); + 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) @@ -1841,6 +2269,382 @@ class XCX121SMCXWZSignalDetector : public XCBase // 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); + } + } + + // + 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); + + // + 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); + } + } + } } // diff --git a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 index 92f526e2..1ed21660 100644 --- a/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5 @@ -37,16 +37,29 @@ enum ENUM_X121SMC_XWZ_PRIORITY }; // -struct X121SMCXWZOBFVG +struct X121SMCXWZZone { // // Props ... - XCOrderBlock *ob; 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 ... - X121SMCXWZOBFVG() + X121SMCXWZZone() { Clean(); } @@ -60,18 +73,1072 @@ struct X121SMCXWZOBFVG // 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 && - fvg != NULL && - ob.IsValid() && + 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 // + ); + + // + 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; + } + // }; @@ -96,6 +1163,7 @@ struct X121SMCXWZWorkingZone double quarter3; // + datetime to; datetime from; // @@ -393,8 +1461,6 @@ struct X121SMCStrategyXWZSignalConditions // // Working Zone ... - - // XCFVG *fairValueGap; XCOrderBlock *orderBlock; XCSupplyZone *supplyZone; @@ -402,7 +1468,7 @@ struct X121SMCStrategyXWZSignalConditions X121SMCXWZWorkingZone workingZone; // - X121SMCXWZOBFVG startZones[]; + X121SMCXWZZone startZone; // // Constructor ... @@ -543,7 +1609,7 @@ struct X121SMCStrategyXWZSignalConditions ZeroMemory(fairValueGap); // - Clean(startZones); + startZone.Clean(); // workingZone.Clean(); @@ -559,6 +1625,149 @@ struct X121SMCStrategyXWZSignalConditions 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 ... @@ -1445,48 +2654,345 @@ struct X121SMCStrategyXWZSignalConditions } // - bool HasOrderBlock() + bool DetectStartZone( + ENUM_X_DIRECTION forDir, + XPOIState &state, + XC121SMCCycleHelper *cycleHelper // + ) { - return orderBlock != NULL && - orderBlock.IsValid(); + // + 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; + + // + bool hasBullishCZone = false; + bool hasBearishCZone = 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]; + } + } + + // + // 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)) + { + 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 isOBInsideFVG = false; + bool isFVGInsideOB = false; + if (hasOBFVG) + { + // + 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 + )); + } + + // + result = + startZone.IsValid() && + (isOBInsideFVG || + isFVGInsideOB) && + (isBullish + ? startZone.IsBullish() + : startZone.IsBearish()); + if (!result) + { + // + startZone.Clean(); + + // + return result; + } + + // + return result; } // - bool HasFairValueGap() + double GetEntry() { - return fairValueGap != NULL && - fairValueGap.IsValid(); + // + double result = 0; + + // + if (!IsValid(symbol) || + !HasDirection(dir)) + { + return result; + } + + // + result = GetEntry( + symbol, + dir // + ); + + // + return result; } // - void UpdateTo(datetime value = NULL) + double GetSpread() { // - value = NormalizeTime(value); + double result = 0; // - if (supplyZone != NULL) + if (!IsValid(symbol)) { - supplyZone.To(value); + return result; } // - if (demandZone != NULL) + result = GetSpread( + symbol // + ); + + // + return result; + } + + // + double GetPoint() + { + // + double result = 0; + + // + if (!IsValid(symbol) || + !HasDirection(dir) || + !HasStartZone()) { - demandZone.To(value); + return result; } // - if (orderBlock != NULL) + bool isBullish = IsBullish(dir); + XBoxZone asBox; + bool hasBox = startZone.AsBox(asBox); + if (!hasBox) { - orderBlock.To(value); + return result; } // - if (fairValueGap != NULL) + result = + isBullish + ? asBox.upper + : asBox.lower; + + // + asBox.Clean(); + + // + return result; + } + + // + double GetExit() + { + // + double result = 0; + + // + if (!IsValid(symbol) || + !HasDirection(dir) || + !HasStartZone()) { - fairValueGap.To(value); + 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; } // diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 6afe6f21..6e50394d 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -583,7 +583,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // XWZ Signal ... bool DetectXWZSignal( X121SMCStrategyConditions &conditions, - X121SMCStrategyXWZSignalConditions &xSupDemOBSConditions // + X121SMCStrategyXWZSignalConditions &xWZConditions // ) { // @@ -804,7 +804,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.target = mConditions.target; // - xSupDemOBSConditions = mConditions; + xWZConditions = mConditions; // mConditions.Clean();