/////////////////////////////////////////////////////// // // 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[]; // XOBFVG insideZones[]; XOBFVG waitingZones[]; // CArrayObj mObjects; // // 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(supportZones); Clean(resistanceZones); // ZeroMemory(supplyZone); ZeroMemory(demandZone); // mObjects.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 // ) { // bool result = false; // if (barIndex < 0) { barIndex = 0; } // result = // IsValid(_symbol) && IsValid(_period) && // htfState.IsValid() && mtfState.IsValid() && stfState.IsValid() && // htfState.HasChild() && mtfState.HasChild() && stfState.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 // ); } // 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); } // ExtractOBFVGs( waitingZones, mtfState, stfState // ); // result = IsValid(); if (!result) { Clean(); } // return result; } // void Update( int barIndex, XPOIState &htfState, XPOIState &mtfState, XPOIState &stfState // ) { // 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 // // ); // // 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) { // 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 // ); } } } // 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(); } } // 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 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); } } // } // void Draw( XCPOIDrawer *drawer, bool forceClean = false, bool drawWaitingZones = true, bool drawSupplyZone = false, bool drawDemandZone = false, bool drawSupplyZones = false, bool drawDemandZones = false, bool drawSupportZones = false, bool drawResistanceZones = false // ) { // if (drawer == NULL) { return; } // if (forceClean) { mObjects.Clear(); } // 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) { mObjects.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) { mObjects.Add(iObj); } } } } // // Demand Zone ... if (drawDemandZone) { // has = HasDemandZone(); if (has) { // XCDemandZoneObject *iObj; isCreated = drawer.CreateDemandZone( demandZone, iObj // ); // if (isCreated) { mObjects.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) { mObjects.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) { mObjects.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) { mObjects.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++) { mObjects.Add(objects[j]); } } } } } // // 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); // mObjects.Add(zoneUpperLine); } // // Zone Lower ... CChartObjectHLine *zoneLowerLine; zoneLowerLine = new CChartObjectHLine(); isCreated = zoneLowerLine.Create( chartID, prefix + "_ZoneDown", subWindow, zoneLower // ); if (isCreated) { // zoneLowerLine.Color(clrRed); // mObjects.Add(zoneLowerLine); } // // Upper ... CChartObjectHLine *upperLine; upperLine = new CChartObjectHLine(); isCreated = upperLine.Create( chartID, prefix + "_Upper", subWindow, upper // ); if (isCreated) { // upperLine.Color(clrLime); // mObjects.Add(upperLine); } // // Lower ... CChartObjectHLine *lowerLine; lowerLine = new CChartObjectHLine(); isCreated = lowerLine.Create( chartID, prefix + "_Lower", subWindow, lower // ); if (isCreated) { // lowerLine.Color(clrLime); // mObjects.Add(lowerLine); } // // Quarters ... // // Quarter 1 ... CChartObjectHLine *q1Line; q1Line = new CChartObjectHLine(); isCreated = q1Line.Create( chartID, prefix + "_Q1", subWindow, quarter1 // ); if (isCreated) { // q1Line.Color(clrYellow); // mObjects.Add(q1Line); } // // Quarter 2 ... CChartObjectHLine *q2Line; q2Line = new CChartObjectHLine(); isCreated = q2Line.Create( chartID, prefix + "_Q2", subWindow, quarter2 // ); if (isCreated) { // q2Line.Color(clrYellow); // mObjects.Add(q2Line); } // // Quarter 3 ... CChartObjectHLine *q3Line; q3Line = new CChartObjectHLine(); isCreated = q3Line.Create( chartID, prefix + "_Q3", subWindow, quarter3 // ); if (isCreated) { // q3Line.Color(clrYellow); // mObjects.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 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(targets); signalZone.Clean(); // provider = X121SMC_XWZ_PROVIDER_NONE; } // // // // void UpdateTo(datetime value = NULL) { // value = NormalizeTime(value); // int count = 0; bool has = false; } // }; //