/////////////////////////////////////////////////////// // // 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_PROVIDERS { X121SMC_XWZ_PROVIDER_NONE, X121SMC_XWZ_PROVIDER_ACTIVATED_ZONE, X121SMC_XWZ_PROVIDER_ACTIVATED_CHOCH, X121SMC_XWZ_PROVIDER_PRICE_INSIDE_ZONE, }; // 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 X121SMCStrategyXWZWorkingZone { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // double quarter1; double quarter2; double quarter3; // XCSupplyZone *supplyZone; XCDemandZone *demandZone; // XCSupplyZone *supplyZones[]; XCDemandZone *demandZones[]; // XCSupportZone *supportZones[]; XCResistanceZone *resistanceZones[]; // XConsolidationZone consolidationZones[]; // XOBFVG insideZones[]; XOBFVG breakedZones[]; XOBFVG waitingZones[]; // CArrayObj mInsideZoneObjects; CArrayObj mBreakedZoneObjects; CArrayObj mWaitingZoneObjects; CArrayObj mWorkingZoneObjects; // // Constructor ... X121SMCStrategyXWZWorkingZone() { Clean(); } // // Tools ... // void Clean() { // quarter1 = 0; quarter2 = 0; quarter3 = 0; // symbol = NULL; period = NULL; // Clean(supplyZones); Clean(demandZones); // Clean(insideZones); Clean(waitingZones); Clean(breakedZones); // Clean(supportZones); Clean(resistanceZones); // ZeroMemory(supplyZone); ZeroMemory(demandZone); // mInsideZoneObjects.Clear(); mBreakedZoneObjects.Clear(); mWaitingZoneObjects.Clear(); mWorkingZoneObjects.Clear(); } // bool IsValid() { // bool result = false; // result = // quarter1 > 0 && quarter2 > 0 && quarter3 > 0 && HasSupplyZone() && HasDemandZone() && quarter1 > quarter2 && quarter2 > quarter3 // ; // return result; } // bool Init( string _symbol, ENUM_TIMEFRAMES _period, int barIndex, XPOIState &htfState, XPOIState &mtfState, XPOIState &stfState, // XPOIState &ttfState // ) { // bool result = false; // if (barIndex < 0) { barIndex = 0; } // result = // IsValid(_symbol) && IsValid(_period) && // htfState.IsValid() && mtfState.IsValid() && stfState.IsValid() && ttfState.IsValid() && // htfState.HasChild() && mtfState.HasChild() && stfState.HasChild() && ttfState.HasChild() // ; if (!result) { return result; } // symbol = _symbol; period = _period; // int idx = -1; int count = 0; bool has = false; // XOHCL zBar; has = zBar.Init( symbol, period, barIndex // ); result = has; if (!result) { zBar.Clean(); return result; } double ll5 = zBar.FindLowest(5, MODE_LOW); double hh5 = zBar.FindHighest(5, MODE_HIGH); zBar.Clean(); // // Supply Zone ... has = HasSupplyZone(); if (!has) { // idx = GetHighest(htfState.supplyZones); has = IsValidIndex(idx); if (has) { // supplyZone = htfState.supplyZones[idx]; has = hh5 < supplyZone.Lower(); if (!has) { supplyZone = NULL; } } } // // Demand Zone ... has = HasDemandZone(); if (!has) { // idx = GetLowest(htfState.demandZones); has = IsValidIndex(idx); if (has) { // demandZone = htfState.demandZones[idx]; has = ll5 > demandZone.Upper(); if (!has) { demandZone = NULL; } } } // // Supply Zones ... has = HasSupplyZones(); if (!has) { // count = mtfState.FilterSupplyZones( supplyZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); } // // Demand Zones ... has = HasDemandZones(); if (!has) { // count = mtfState.FilterDemandZones( demandZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); } // // Support Zones ... has = HasSupportZones(); if (!has) { // count = stfState.FilterSupportZones( supportZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); } // // Resistance Zones ... has = HasResistanceZones(); if (!has) { // count = stfState.FilterResistanceZones( resistanceZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); } // has = ttfState.HasConsolidationZones(); if (has) { // Copy( ttfState.consolidationZones, consolidationZones // ); CleanupArray( consolidationZones, 50 // ); } // if (supplyZone != NULL && demandZone != NULL && supplyZone.IsValid() && demandZone.IsValid()) { // double upper = supplyZone.Lower(); double lower = demandZone.Upper(); // double delta = ((upper - lower) / 100) * 25; // quarter1 = upper - (1 * delta); quarter2 = upper - (2 * delta); quarter3 = upper - (3 * delta); } // // Detect OBFVG(s) ... ExtractOBFVGs( waitingZones, mtfState, stfState // ); // // Detect Waiting Zones based on STF and TTF ... XOBFVG tmpWaitingZones[]; count = ExtractOBFVGs( tmpWaitingZones, stfState, ttfState // ); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { // XOBFVG iOBFVG = tmpWaitingZones[i]; // idx = FindIndex( iOBFVG, waitingZones // ); has = IsValidIndex(idx); if (has) { // iOBFVG.Clean(); continue; } // AddRef( iOBFVG, waitingZones // ); // iOBFVG.Clean(); } } // result = IsValid(); if (!result) { Clean(); } // return result; } // void Update( int barIndex, XPOIState &htfState, XPOIState &mtfState, XPOIState &stfState, XPOIState &ttfState // ) { // int idx = -1; int count = 0; bool has = false; // if (barIndex < 0) { barIndex = 0; } // has = // IsValid() && // htfState.IsValid() && mtfState.IsValid() && stfState.IsValid() && // htfState.HasChild() && mtfState.HasChild() && stfState.HasChild() // ; if (!has) { return; } // XOHCL zBar; has = zBar.Init( symbol, period, barIndex // ); if (!has) { // zBar.Clean(); return; } // XOHCL cBar; has = zBar.GetPreviousBar(cBar); if (!has) { // zBar.Clean(); cBar.Clean(); // return; } // // Supply Zones ... count = mtfState.FilterSupplyZones( supplyZones, NULL, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); // // Demand Zones ... count = mtfState.FilterDemandZones( demandZones, NULL, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); // // Support Zones ... count = stfState.FilterSupportZones( supportZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); // // Resistance Zones ... count = stfState.FilterResistanceZones( resistanceZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); // // Support Zones ... count = stfState.FilterSupportZones( supportZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); // // Resistance Zones ... count = stfState.FilterResistanceZones( resistanceZones, period, XZONE_STATE_PASSED, false, XZONE_STATE_FAILED, false, XZONE_STATE_FAILED, false, XZONE_STATE_IGNORED, false // ); // // Consolidation Zones ... has = ttfState.HasConsolidationZones(); if (has) { // Copy( ttfState.consolidationZones, consolidationZones // ); CleanupArray( consolidationZones, 50 // ); } // // // // // Detect Price Inside Zones ... has = HasWaitingZones(); if (has) { // int mustRemove[]; count = CountWaitingZones(); for (int i = 0; i < count; i++) { // XOBFVG iOBFVG = waitingZones[i]; // bool isInside = // zBar.high < iOBFVG.ob.Upper() && zBar.low > iOBFVG.ob.Lower() && // cBar.high < iOBFVG.ob.Upper() && cBar.low > iOBFVG.ob.Lower() // ; if (isInside) { // idx = FindIndex( iOBFVG, insideZones // ); has = IsValidSize(idx); if (!has) { // Add( i, mustRemove // ); // AddRef( iOBFVG, insideZones // ); } } } // has = HasChild(mustRemove); if (has) { // count = ArraySize(mustRemove); for (int i = 0; i < count; i++) { // ArrayRemove( waitingZones, mustRemove[i], 1 // ); } } // Clean(mustRemove); } // // Detect Inside Zones ... has = HasInsideZones(); if (has) { // int mustRemove[]; count = CountInsideZones(); for (int i = 0; i < count; i++) { // XOBFVG iOBFVG = insideZones[i]; ENUM_X_DIRECTION iDir = iOBFVG.GetDirection(); bool isBullish = IsBullish(iDir); // bool isBullishBreaked = // zBar.high < iOBFVG.ob.Lower() && cBar.high < iOBFVG.ob.Lower() // ; // bool isBearishBreaked = // zBar.low > iOBFVG.ob.Upper() && cBar.low > iOBFVG.ob.Upper() // ; // bool isBreaked = isBullish ? isBullishBreaked : isBearishBreaked; // if (isBreaked) { // idx = FindIndex( iOBFVG, breakedZones // ); has = IsValidIndex(idx); if (!has) { // Add( i, mustRemove // ); // AddRef( iOBFVG, breakedZones // ); } } } // has = HasChild(mustRemove); if (has) { // count = ArraySize(mustRemove); for (int i = 0; i < count; i++) { // ArrayRemove( insideZones, mustRemove[i], 1 // ); } } // Clean(mustRemove); } // // Adding New OBFVG to Waiting Zones if not Exists ... XOBFVG tmpWaitingZones[]; count = ExtractOBFVGs( tmpWaitingZones, mtfState, stfState // ); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { // XOBFVG iOBFVG = tmpWaitingZones[i]; // idx = FindIndex( iOBFVG, waitingZones // ); has = IsValidIndex(idx); if (has) { // iOBFVG.Clean(); continue; } // AddRef( iOBFVG, waitingZones // ); // iOBFVG.Clean(); } } // // Detect Waiting Zones based on STF and TTF ... Clean(tmpWaitingZones); count = ExtractOBFVGs( tmpWaitingZones, stfState, ttfState // ); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { // XOBFVG iOBFVG = tmpWaitingZones[i]; // idx = FindIndex( iOBFVG, waitingZones // ); has = IsValidIndex(idx); if (has) { // iOBFVG.Clean(); continue; } // AddRef( iOBFVG, waitingZones // ); // iOBFVG.Clean(); } } // zBar.Clean(); cBar.Clean(); } // bool HasSupplyZone() { return supplyZone != NULL && supplyZone.IsValid(); } // bool HasDemandZone() { return demandZone != NULL && demandZone.IsValid(); } // bool HasSupplyZones() { return HasChild(supplyZones); } // int CountSupplyZones() { return ArraySize(supplyZones); } // bool HasDemandZones() { return HasChild(demandZones); } // int CountDemandZones() { return ArraySize(demandZones); } // bool HasSupportZones() { return HasChild(supportZones); } // int CountSupportZones() { return ArraySize(supportZones); } // bool HasResistanceZones() { return HasChild(resistanceZones); } // int CountResistanceZones() { return ArraySize(resistanceZones); } // bool HasWaitingZones() { return HasChild(waitingZones); } // int CountWaitingZones() { return ArraySize(waitingZones); } // bool HasInsideZones() { return HasChild(insideZones); } // int CountInsideZones() { return ArraySize(insideZones); } // bool HasBreakedZones() { return HasChild(breakedZones); } // int CountBreakedZones() { return ArraySize(breakedZones); } // bool HasConsolidationZones() { return HasChild(consolidationZones); } // int CountConsolidationZones() { return ArraySize(consolidationZones); } // // // // bool IsDestroyed( int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = period; } // result = IsValid(); if (!result) { return result; } // XOHCL bar; result = bar.Init( symbol, period, barIndex // ); if (!result) { // bar.Clean(); return result; } // XOHCL cBar; result = bar.GetPreviousBar(cBar); if (!result) { // bar.Clean(); cBar.Clean(); // return result; } // bool isSupplyZoneBreaked = // bar.low > supplyZone.Upper() && cBar.low > supplyZone.Upper() // ; // bool isDemandZoneBreaked = // bar.high < demandZone.Lower() && cBar.high < demandZone.Lower() // ; // bar.Clean(); cBar.Clean(); // result = isSupplyZoneBreaked || isDemandZoneBreaked; // return result; } // bool DetectPriority( ENUM_X121SMC_XWZ_PRIORITY &priority, ENUM_X_DIRECTION forDir, int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // priority = X121SMC_XWZ_PRIORITY_NONE; // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = period; } // result = IsValid() && HasDirection(forDir); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // XOHCL bar; result = bar.Init( symbol, forPeriod, barIndex // ); if (!result) { // bar.Clean(); return result; } // if (bar.high < supplyZone.Upper() && bar.low > supplyZone.Lower()) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_NONE : X121SMC_XWZ_PRIORITY_STRONG_HIGH; } else if (bar.high < supplyZone.Lower() && bar.low > quarter1) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_WEAK : X121SMC_XWZ_PRIORITY_HIGH; } else if (bar.high < quarter1 && bar.low > quarter2) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_LOW : X121SMC_XWZ_PRIORITY_REGULAR; } else if (bar.high < quarter2 && bar.low > quarter3) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_REGULAR : X121SMC_XWZ_PRIORITY_LOW; } else if (bar.high < quarter3 && bar.low > demandZone.Upper()) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_HIGH : X121SMC_XWZ_PRIORITY_WEAK; } else if (bar.high < demandZone.Upper() && bar.low > demandZone.Lower()) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_STRONG_HIGH : X121SMC_XWZ_PRIORITY_NONE; } // result = priority != X121SMC_XWZ_PRIORITY_NONE && priority != X121SMC_XWZ_PRIORITY_WEAK; // bar.Clean(); // return result; } // // // // void UpdateTo(datetime value = NULL) { // value = NormalizeTime(value); // int count = 0; bool has = false; // has = HasSupplyZone(); if (has) { supplyZone.To(value); } // has = HasDemandZone(); if (has) { demandZone.To(value); } // has = HasSupplyZones(); if (has) { // count = CountSupplyZones(); for (int i = 0; i < count; i++) { supplyZones[i].To(value); } } // has = HasDemandZones(); if (has) { // count = CountDemandZones(); for (int i = 0; i < count; i++) { demandZones[i].To(value); } } // has = HasSupportZones(); if (has) { // count = CountSupportZones(); for (int i = 0; i < count; i++) { supportZones[i].To(value); } } // has = HasResistanceZones(); if (has) { // count = CountResistanceZones(); for (int i = 0; i < count; i++) { resistanceZones[i].To(value); } } // has = HasWaitingZones(); if (has) { // count = CountWaitingZones(); for (int i = 0; i < count; i++) { waitingZones[i].UpdateTo(value); } } // has = HasInsideZones(); if (has) { // count = CountInsideZones(); for (int i = 0; i < count; i++) { insideZones[i].UpdateTo(value); } } // has = HasBreakedZones(); if (has) { // count = CountBreakedZones(); for (int i = 0; i < count; i++) { breakedZones[i].UpdateTo(value); } } // } // void Draw( XCPOIDrawer *drawer, bool drawWaitingZones = true, bool drawInsideZones = false, bool drawBreakedZones = false, bool drawSupplyZone = false, bool drawDemandZone = false, bool drawSupplyZones = false, bool drawDemandZones = false, bool drawSupportZones = false, bool drawResistanceZones = false // ) { // if (drawer == NULL) { return; } // int count = 0; bool has = false; bool isCreated = false; // ulong chartID = drawer.ChartIdentification(); int subWindow = drawer.SubWindowIdentification(); color bullishColor = drawer.BarBullishColor(); color bearishColor = drawer.BarBearishColor(); // // Supply Zone ... if (drawSupplyZone) { // has = HasSupplyZone(); if (has) { // XCSupplyZoneObject *iObj; isCreated = drawer.CreateSupplyZone( supplyZone, iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } // // Supply Zones ... if (drawSupplyZones) { // has = HasSupplyZones(); if (has) { // count = CountSupplyZones(); for (int i = 0; i < count; i++) { // XCSupplyZoneObject *iObj; isCreated = drawer.CreateSupplyZone( supplyZones[i], iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } } // // Demand Zone ... if (drawDemandZone) { // has = HasDemandZone(); if (has) { // XCDemandZoneObject *iObj; isCreated = drawer.CreateDemandZone( demandZone, iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } // // Demand Zones ... if (drawDemandZones) { // has = HasDemandZones(); if (has) { // count = CountDemandZones(); for (int i = 0; i < count; i++) { // XCDemandZoneObject *iObj; isCreated = drawer.CreateDemandZone( demandZones[i], iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } } // // Support Zones ... if (drawSupportZones) { // has = HasSupportZones(); if (has) { // count = CountSupportZones(); for (int i = 0; i < count; i++) { // XCSupportZoneObject *iObj; isCreated = drawer.CreateSupportZone( supportZones[i], iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } } // // Resistance Zones ... if (drawResistanceZones) { // has = HasResistanceZones(); if (has) { // count = CountResistanceZones(); for (int i = 0; i < count; i++) { // XCResistanceZoneObject *iObj; isCreated = drawer.CreateResistanceZone( resistanceZones[i], iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } } // // Waiting Zones ... if (drawWaitingZones) { // has = HasWaitingZones(); if (has) { // count = CountWaitingZones(); for (int i = 0; i < count; i++) { // XCBaseObject *objects[]; int objectsCount = drawer.DrawOBFVG( waitingZones[i], objects // ); has = IsValidSize(objectsCount); if (has) { // for (int j = 0; j < objectsCount; j++) { mWaitingZoneObjects.Add(objects[j]); } } } } } // // Inside Zones ... if (drawInsideZones) { // has = HasInsideZones(); if (has) { // count = CountInsideZones(); for (int i = 0; i < count; i++) { // XCBaseObject *objects[]; int objectsCount = drawer.DrawOBFVG( insideZones[i], objects // ); // has = IsValidSize(objectsCount); if (has) { // for (int i = 0; i < objectsCount; i++) { mInsideZoneObjects.Add(objects[i]); } } } } } // // Breaked Zones ... if (drawBreakedZones) { // has = HasBreakedZones(); if (has) { // count = CountBreakedZones(); for (int i = 0; i < count; i++) { // XCBaseObject *objects[]; int objectsCount = drawer.DrawOBFVG( breakedZones[i], objects // ); // has = IsValidSize(objectsCount); if (has) { // for (int i = 0; i < objectsCount; i++) { mBreakedZoneObjects.Add(objects[i]); } } } } } // // Quarters ... has = IsValid(); if (has) { // double zoneUpper = supplyZone.Upper(); double upper = supplyZone.Lower(); // double lower = demandZone.Upper(); double zoneLower = demandZone.Lower(); // string prefix = "X121WZone_" + symbol + "_" + ToString(period); // // Zone Upper ... CChartObjectHLine *zoneUpperLine; zoneUpperLine = new CChartObjectHLine(); isCreated = zoneUpperLine.Create( chartID, prefix + "_ZoneTop", subWindow, zoneUpper // ); if (isCreated) { // zoneUpperLine.Color(clrRed); // mWaitingZoneObjects.Add(zoneUpperLine); } // // Zone Lower ... CChartObjectHLine *zoneLowerLine; zoneLowerLine = new CChartObjectHLine(); isCreated = zoneLowerLine.Create( chartID, prefix + "_ZoneDown", subWindow, zoneLower // ); if (isCreated) { // zoneLowerLine.Color(clrRed); // mWaitingZoneObjects.Add(zoneLowerLine); } // // Upper ... CChartObjectHLine *upperLine; upperLine = new CChartObjectHLine(); isCreated = upperLine.Create( chartID, prefix + "_Upper", subWindow, upper // ); if (isCreated) { // upperLine.Color(clrLime); // mWaitingZoneObjects.Add(upperLine); } // // Lower ... CChartObjectHLine *lowerLine; lowerLine = new CChartObjectHLine(); isCreated = lowerLine.Create( chartID, prefix + "_Lower", subWindow, lower // ); if (isCreated) { // lowerLine.Color(clrLime); // mWaitingZoneObjects.Add(lowerLine); } // // Quarters ... // // Quarter 1 ... CChartObjectHLine *q1Line; q1Line = new CChartObjectHLine(); isCreated = q1Line.Create( chartID, prefix + "_Q1", subWindow, quarter1 // ); if (isCreated) { // q1Line.Color(clrYellow); // mWaitingZoneObjects.Add(q1Line); } // // Quarter 2 ... CChartObjectHLine *q2Line; q2Line = new CChartObjectHLine(); isCreated = q2Line.Create( chartID, prefix + "_Q2", subWindow, quarter2 // ); if (isCreated) { // q2Line.Color(clrYellow); // mWaitingZoneObjects.Add(q2Line); } // // Quarter 3 ... CChartObjectHLine *q3Line; q3Line = new CChartObjectHLine(); isCreated = q3Line.Create( chartID, prefix + "_Q3", subWindow, quarter3 // ); if (isCreated) { // q3Line.Color(clrYellow); // mWaitingZoneObjects.Add(q3Line); } } } // }; // // Definitions ... struct X121SMCStrategyXWZSignalConditions { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // double sl; double reward; double amountPercent; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; // // Setup Props ... // datetime setupTime; datetime triggerTime; // double pivot; double point; double sls[]; double targets[]; // XOBFVG signalZone; // ENUM_X121SMC_XWZ_PRIORITY priority; ENUM_X121SMC_XWZ_PROVIDERS provider; // // Constructor ... X121SMCStrategyXWZSignalConditions() { Clean(); } // // Tools ... /** * Cleaning Up ... */ void Clean() { // sl = 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; // reward = 0; amountPercent = 0; // Clean(sls); Clean(targets); signalZone.Clean(); // provider = X121SMC_XWZ_PROVIDER_NONE; } // // // // void UpdateTo(datetime value = NULL) { // value = NormalizeTime(value); // int count = 0; bool has = false; } // }; // // Extension Functions ... /** * Check an XOBFVG instance has Required Conditions ... * * @param zone: XOBFVG instance ... * @param state: XPOIState instance ... * @param conditions: X121Conditions instance ... * * @return ( bool ) */ bool DetectSelectedZoneConditions( bool &isReversal, XOBFVG &zone, XPOIState &state, X121Conditions &conditions // ) { // bool result = false; // isReversal = false; // result = zone.IsValid() && state.IsValid() && state.HasChild(); if (!result) { return result; } // bool isBullish = zone.IsBullish(); bool isBearish = zone.IsBearish(); // bool isBullishTrend = conditions.isTrendBullish || conditions.isTrendSwitchedToBullish; bool isBearishTrend = conditions.isTrendBearish || conditions.isTrendSwitchedToBearish; // double bullishScore = 0; double bearishScore = 0; double scoreMultiplier = 1.5; conditions.GenerateScore( bullishScore, bearishScore // ); // bool isBullishScorePassed = bullishScore > 0 && bearishScore >= 0 && bullishScore > bearishScore * scoreMultiplier; // bool isBearishScorePassed = bearishScore > 0 && bullishScore >= 0 && bearishScore > bullishScore * scoreMultiplier; // // VWap ... // double vwapFast = conditions.vwapFastBuffer[0]; double vwapMid = conditions.vwapMidBuffer[0]; double vwapSlow = conditions.vwapSlowBuffer[0]; // bool isVWapInside = // vwapFast > zone.ob.Lower() && vwapFast < zone.ob.Upper() // && vwapMid > zone.ob.Lower() && vwapMid < zone.ob.Upper() // ; // bool isVWapBullish = // (conditions.isVWapBullishState && conditions.isVWapSwitchedToBullishOrdered) // || // (conditions.isVWapBullishOrdered && conditions.isVWapSwitchedToBullishState) // ; // bool isVWapBearish = // (conditions.isVWapBearishState && conditions.isVWapSwitchedToBearishOrdered) // || // (conditions.isVWapBearishOrdered && conditions.isVWapSwitchedToBearishState) // ; // // X3Ma ... // double x3maFast = conditions.x3maFastBuffer[0]; double x3maMid = conditions.x3maMidBuffer[0]; double x3maSlow = conditions.x3maSlowBuffer[0]; // bool isX3MaInside = // x3maFast > zone.ob.Lower() && x3maFast < zone.ob.Upper() // && x3maMid > zone.ob.Lower() && x3maMid < zone.ob.Upper() // ; // bool isX3MaBullish = // (conditions.isX3MaBullishState && conditions.isX3MaSwitchedToBullishOrdered) // || // (conditions.isX3MaBullishOrdered && conditions.isX3MaSwitchedToBullishState) // ; // bool isX3MaBearish = // (conditions.isX3MaBearishState && conditions.isX3MaSwitchedToBearishOrdered) // || // (conditions.isX3MaBearishOrdered && conditions.isX3MaSwitchedToBearishState) // ; // // // // bool isInside = // isVWapInside || isX3MaInside // ; // bool isVWap3MaBullish = isVWapBullish || isX3MaBullish; // bool isVWap3MaBearish = isVWapBearish || isX3MaBearish; // // // // bool isDirectionalBullishPassed = // isInside && isBullish && isBullishTrend && isVWap3MaBullish && isBullishScorePassed // ; // bool isDirectionalBearishPassed = // isInside && isBearish && isBearishTrend && isVWap3MaBearish && isBearishScorePassed // ; // bool isDirectionalPassed = isDirectionalBullishPassed || isDirectionalBearishPassed; // bool isReversalBullishPassed = // isInside && isBullish && isBearishTrend && isVWap3MaBearish && isBearishScorePassed // ; // bool isReversalBearishPassed = // isInside && isBearish && isBullishTrend && isVWap3MaBullish && isBullishScorePassed // ; // bool isReversalPassed = isReversalBullishPassed || isReversalBearishPassed; // result = isReversalPassed || isDirectionalPassed; // if (result) { isReversal = isReversalPassed; } // return result; } /** * Detect Targets Based on Selected Zone for Specified type of Directions ... * * @param targets: double Collection ... * @param selectedZone: XOBFVG instance, selected Zone ... * @param forDir: ENUM_X_DIRECTION specified Position Direction ... * @param workingone: X121SMCStrategyXWZWorkingZone instance, Specified Working Zone ... * @param barIndex: int Specified Bar Index ... * * @return ( bool ) */ bool DetectSelectedZonesTargets( double &targets[], XOBFVG &selectedZone, ENUM_X_DIRECTION forDir, ENUM_X121SMC_XWZ_PRIORITY forPriority, X121SMCStrategyXWZWorkingZone &workingZone, int barIndex = 0 // ) { // bool result = false; // Clean(targets); // if (barIndex < 0) { barIndex = 0; } // if (barIndex == 0) { barIndex++; } // result = // selectedZone.IsValid() && HasDirection(forDir) && workingZone.IsValid() && forPriority != X121SMC_XWZ_PRIORITY_NONE // ; if (!result) { return result; } // bool isBullish = IsBullish(forDir); // XOHCL cBar; result = cBar.Init( workingZone.symbol, workingZone.period, barIndex // ); if (!result) { // cBar.Clean(); return result; } // int idx = -1; bool has = false; XOBFVG tmpZones[]; // // Based On Waiting Zones ... has = workingZone.HasWaitingZones(); if (has) { // Copy( workingZone.waitingZones, tmpZones // ); // while (HasChild(tmpZones)) { // XOBFVG iOBFVG; // idx = GetYoungest(tmpZones); if (!IsValidIndex(idx)) { // iOBFVG.Clean(); break; } // iOBFVG = tmpZones[idx]; ArrayRemove( tmpZones, idx, 1 // ); // double iTarget = isBullish ? iOBFVG.ob.Lower() : iOBFVG.ob.Upper(); // has = isBullish ? cBar.high < iTarget : cBar.low > iTarget; // if (has) { // Add( iTarget, targets // ); } // iOBFVG.Clean(); } // Clean(tmpZones); } // // Based On Breaked Zones ... has = workingZone.HasBreakedZones(); if (has) { Copy( workingZone.breakedZones, tmpZones // ); // while (HasChild(tmpZones)) { // XOBFVG iOBFVG; // idx = GetYoungest(tmpZones); if (!IsValidIndex(idx)) { // iOBFVG.Clean(); break; } // iOBFVG = tmpZones[idx]; ArrayRemove( tmpZones, idx, 1 // ); // double iTarget = isBullish ? iOBFVG.ob.Lower() : iOBFVG.ob.Upper(); // has = isBullish ? cBar.high < iTarget : cBar.low > iTarget; // if (has) { // Add( iTarget, targets // ); } // iOBFVG.Clean(); } // Clean(tmpZones); } // // Based On Priority ... has = forPriority != X121SMC_XWZ_PRIORITY_NONE; if (has) { // switch (forPriority) { // case X121SMC_XWZ_PRIORITY_WEAK: // if (isBullish) { // // Weak ... Add( workingZone.supplyZone.Lower(), targets // ); } else { // // Weak ... Add( workingZone.demandZone.Upper(), targets // ); } break; // case X121SMC_XWZ_PRIORITY_LOW: // if (isBullish) { // // Weak ... Add( workingZone.supplyZone.Lower(), targets // ); // // Low ... Add( workingZone.quarter1, targets // ); } else { // // Weak ... Add( workingZone.demandZone.Upper(), targets // ); // // Low ... Add( workingZone.quarter3, targets // ); } break; // case X121SMC_XWZ_PRIORITY_REGULAR: // if (isBullish) { // // Weak ... Add( workingZone.supplyZone.Lower(), targets // ); // // Low ... Add( workingZone.quarter1, targets // ); // // Regular ... Add( workingZone.quarter2, targets // ); } else { // // Weak ... Add( workingZone.demandZone.Upper(), targets // ); // // Low ... Add( workingZone.quarter3, targets // ); // // Regular ... Add( workingZone.quarter2, targets // ); } break; // case X121SMC_XWZ_PRIORITY_HIGH: // if (isBullish) { // // Weak ... Add( workingZone.supplyZone.Lower(), targets // ); // // Low ... Add( workingZone.quarter1, targets // ); // // Regular ... Add( workingZone.quarter2, targets // ); // // High ... Add( workingZone.quarter3, targets // ); } else { // // Weak ... Add( workingZone.demandZone.Upper(), targets // ); // // Low ... Add( workingZone.quarter3, targets // ); // // Regular ... Add( workingZone.quarter2, targets // ); // // High ... Add( workingZone.quarter1, targets // ); } break; // case X121SMC_XWZ_PRIORITY_STRONG_HIGH: // if (isBullish) { // // Weak ... Add( workingZone.supplyZone.Lower(), targets // ); // // Low ... Add( workingZone.quarter1, targets // ); // // Regular ... Add( workingZone.quarter2, targets // ); // // High ... Add( workingZone.quarter3, targets // ); // // Strong High ... Add( workingZone.demandZone.Upper(), targets // ); } else { // // Weak ... Add( workingZone.demandZone.Upper(), targets // ); // // Low ... Add( workingZone.quarter3, targets // ); // // Regular ... Add( workingZone.quarter2, targets // ); // // High ... Add( workingZone.quarter1, targets // ); // // Strong High ... Add( workingZone.supplyZone.Lower(), targets // ); } break; } } // result = HasChild(targets); // // Cleanup ... cBar.Clean(); Clean(tmpZones); // return result; } /** * Detect SL Candidates Based on Selected Zone for Specified type of Directions ... * * @param sls: double Collection ... * @param selectedZone: XOBFVG instance, selected Zone ... * @param forDir: ENUM_X_DIRECTION specified Position Direction ... * @param workingZone: X121SMCStrategyXWZWorkingZone instance, Specified Working Zone ... * @param barIndex: int Specified Bar Index ... * @param maxAllowedSLDistanceInPoint: doube max Allowe SL distance ... * * @return ( bool ) */ bool DetectSelectedZoneSLCandidates( double &sls[], XOBFVG &selectedZone, ENUM_X_DIRECTION forDir, X121SMCStrategyXWZWorkingZone &workingZone, int barIndex = 0, double maxAllowedSLDistanceInPoint = 300 // ) { // bool result = false; // Clean(sls); // if (barIndex < 0) { barIndex = 0; } // if (barIndex == 0) { barIndex++; } // result = // selectedZone.IsValid() && HasDirection(forDir) && workingZone.IsValid() // ; if (!result) { return result; } // bool isBullish = IsBullish(forDir); // double pivot = isBullish ? selectedZone.ob.Lower() : selectedZone.ob.Upper(); double points = GetPoints(workingZone.symbol); // XOHCL cBar; result = cBar.Init( workingZone.symbol, workingZone.period, barIndex // ); if (!result) { // cBar.Clean(); return result; } // int idx = -1; bool has = false; // // Based On Passed Bars ... XOHCL passedBar; bool isPassed = false; bool isBodyState = false; ENUM_X_DIRECTION passedDir = selectedZone.GetDirection(); // // Started Bar ... isPassed = selectedZone.ob.IsStarted( passedDir, passedBar, isBodyState // ); if (isPassed) { // double iSL = isBullish ? passedBar.low : passedBar.high; double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // // Activation Bar ... passedBar.Clean(); isPassed = selectedZone.ob.IsActivated( passedDir, passedBar, isBodyState // ); if (isPassed) { // double iSL = isBullish ? passedBar.low : passedBar.high; double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // // Worked Bar ... passedBar.Clean(); isPassed = selectedZone.ob.IsActivated( passedDir, passedBar, isBodyState // ); if (isPassed) { // double iSL = isBullish ? passedBar.low : passedBar.high; double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // // Breaked Bar ... passedBar.Clean(); isPassed = selectedZone.ob.IsActivated( passedDir, passedBar, isBodyState // ); if (isPassed) { // double iSL = isBullish ? passedBar.low : passedBar.high; double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // // Based On Consolidation Zones ... has = workingZone.HasConsolidationZones(); if (has) { // XConsolidationZone tmpZones[]; Copy( workingZone.consolidationZones, tmpZones // ); XConsolidationZone selectedConsolidationZone; // while (HasChild(tmpZones)) { // idx = GetYoungest(tmpZones); if (!IsValidIndex(idx)) { break; } // XConsolidationZone iZone = tmpZones[idx]; // ArrayRemove( tmpZones, idx, 1 // ); // has = !selectedConsolidationZone.IsValid() ? isBullish ? cBar.low < iZone.upper : cBar.high < iZone.lower : isBullish ? selectedConsolidationZone.lower < iZone.lower : selectedConsolidationZone.upper > iZone.upper; if (has) { // selectedConsolidationZone = iZone; iZone.Clean(); break; } // iZone.Clean(); } // Clean(tmpZones); has = selectedConsolidationZone.IsValid(); if (has) { // double iSL = isBullish ? selectedConsolidationZone.lower : selectedConsolidationZone.upper; double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } } // // Based On Supply and Demand Zones ... // // Demand Zones ... has = workingZone.HasDemandZones(); if (has) { // XCDemandZone *tmpZones[]; Copy( workingZone.demandZones, tmpZones // ); XCDemandZone *selectedDemand = NULL; // while (HasChild(tmpZones)) { // idx = GetLowest(tmpZones); has = IsValidIndex(idx); if (!has) { break; } // XCDemandZone *iZone = tmpZones[idx]; ArrayRemove( tmpZones, idx, 1 // ); // // Validate Zone ... has = isBullish ? IsBelowDiff( iZone, selectedZone.ob, true // Ignore Inside ... ) : IsAboveDiff( iZone, selectedZone.ob, true // Ignore Inside ... ); if (!has) { continue; } // has = selectedDemand == NULL ? true : isBullish ? selectedDemand.Lower() < iZone.Lower() : selectedDemand.Upper() > iZone.Upper(); if (!has) { continue; } // selectedDemand = iZone; } // has = selectedDemand != NULL; if (has) { // double iSL = isBullish ? selectedDemand.Lower() : selectedDemand.Upper(); double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // Clean(tmpZones); ZeroMemory(selectedDemand); } // // Support Zones ... has = workingZone.HasSupportZones(); if (has) { // XCSupportZone *tmpZones[]; Copy( workingZone.supportZones, tmpZones // ); XCSupportZone *selectedSupport = NULL; // while (HasChild(tmpZones)) { // idx = GetLowest(tmpZones); has = IsValidIndex(idx); if (!has) { break; } // XCSupportZone *iZone = tmpZones[idx]; ArrayRemove( tmpZones, idx, 1 // ); // // Validate Zone ... has = isBullish ? IsBelowDiff( iZone, selectedZone.ob, true // Ignore Inside ... ) : IsAboveDiff( iZone, selectedZone.ob, true // Ignore Inside ... ); if (!has) { continue; } // has = selectedSupport == NULL ? true : isBullish ? selectedSupport.Lower() < iZone.Lower() : selectedSupport.Upper() > iZone.Upper(); if (!has) { continue; } // selectedSupport = iZone; // } // has = selectedSupport != NULL; if (has) { // double iSL = isBullish ? selectedSupport.Lower() : selectedSupport.Upper(); double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // Clean(tmpZones); ZeroMemory(selectedSupport); } // // Supply Zones ... has = workingZone.HasSupplyZones(); if (has) { // XCSupplyZone *tmpZones[]; Copy( workingZone.supplyZones, tmpZones // ); XCSupplyZone *selectedSupply = NULL; // while (HasChild(tmpZones)) { // idx = GetHighest(tmpZones); has = IsValidIndex(idx); if (!has) { break; } // XCSupplyZone *iZone = tmpZones[idx]; ArrayRemove( tmpZones, idx, 1 // ); // // Validate Zone ... has = !isBullish ? IsAboveDiff( iZone, selectedZone.ob, true // Ignore Inside ... ) : IsBelowDiff( iZone, selectedZone.ob, true // Ignore Inside ... ); if (!has) { continue; } // has = selectedSupply == NULL ? true : !isBullish ? selectedSupply.Upper() > iZone.Upper() : selectedSupply.Lower() < iZone.Lower(); if (!has) { continue; } // selectedSupply = iZone; // } // has = selectedSupply != NULL; if (has) { // double iSL = !isBullish ? selectedSupply.Upper() : selectedSupply.Lower(); double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // Clean(tmpZones); ZeroMemory(selectedSupply); } // // Resistance Zones ... has = workingZone.HasDemandZones(); if (has) { // XCResistanceZone *tmpZones[]; Copy( workingZone.resistanceZones, tmpZones // ); XCResistanceZone *selectedResistance = NULL; // while (HasChild(tmpZones)) { // idx = GetHighest(tmpZones); has = IsValidIndex(idx); if (!has) { break; } // XCResistanceZone *iZone = tmpZones[idx]; ArrayRemove( tmpZones, idx, 1 // ); // // Validate Zone ... has = !isBullish ? IsAboveDiff( iZone, selectedZone.ob, true // Ignore Inside ... ) : IsBelowDiff( iZone, selectedZone.ob, true // Ignore Inside ... ); if (!has) { continue; } // has = selectedResistance == NULL ? true : !isBullish ? selectedResistance.Upper() < iZone.Upper() : selectedResistance.Lower() > iZone.Lower(); if (!has) { continue; } // selectedResistance = iZone; // } // has = selectedResistance != NULL; if (has) { // double iSL = !isBullish ? selectedResistance.Upper() : selectedResistance.Lower(); double iSLDiff = MathAbs(iSL - pivot); has = iSLDiff > 0 && iSLDiff <= maxAllowedSLDistanceInPoint * points; if (has) { // Add( iSL, sls // ); } } // Clean(tmpZones); ZeroMemory(selectedResistance); } // // Cleanp Resources ... // cBar.Clean(); passedBar.Clean(); result = HasChild(sls); // return result; } // // // bool DetectX121Conditions( double &pivot, double &point, double &sls[], double &targets[], ENUM_X_DIRECTION &dir, XPOIState &stfState, XPOIState &ttfState, X121Conditions &conditions, XCPOIDrawer *drawer = NULL // ) { // bool result = false; // bool canDraw = drawer != NULL; // pivot = 0; point = 0; Clean(sls); Clean(targets); dir = X_DIRECTION_NONE; // result = stfState.IsValid() && ttfState.IsValid() && stfState.HasChild() && ttfState.HasChild(); if (!result) { return result; } // int idx = -1; int count = 0; bool has = false; // // Detect Inside STF Order Blocks Zones ... // XOBFVG tmpWaitingZones[]; count = ExtractOBFVGs( tmpWaitingZones, stfState, ttfState // ); has = IsValidSize(count); if (has) { // if (canDraw) { // for (int i = 0; i < count; i++) { // XOBFVG iOBFVG = tmpWaitingZones[i]; // iOBFVG.UpdateTo(); // XCBaseObject *iOBFVGObjects[]; int iOBFVGObjectsCount = drawer.DrawOBFVG( iOBFVG, iOBFVGObjects // ); } } } // // return result; } //