/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 X121 SMC Signal Class // ------------------------------------------------- // Name: XICH // 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" // // Provided Signals Enumeration ... enum ENUM_X121SMC_XIND_PROVIDERS { X121SMC_XIND_PROVIDER_NONE, X121SMC_XIND_PROVIDER_XIND, X121SMC_XIND_PROVIDER_XTKKUMO, }; // // Definitions ... // // XIND Signal Conditions ... struct X121SMCStrategyXINDSignalConditions { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // double sl; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; // // Setup Props ... // datetime setupTime; datetime triggerTime; // double pivot; double point; double sls[]; double targets[]; // XBoxZone signalBox; // ENUM_X121SMC_XIND_PROVIDERS provider; // // Constructor ... X121SMCStrategyXINDSignalConditions() { 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; // Clean(sls); Clean(targets); signalBox.Clean(); // provider = X121SMC_XIND_PROVIDER_NONE; } // // // // void UpdateTo(datetime value = NULL) { // value = NormalizeTime(value); // int count = 0; bool has = false; } // }; // // Extension Functions ... // // Validate FVG BOXes ... // bool IsFVGBoxValid( XBoxZone &box, ENUM_X_CYCLES cycle, X121SMCStrategySignalProviderData &provider // ) { // bool result = false; // result = box.IsValid(); if (!result) { return result; } // // Fil Selected Data ... XPOIState cState; X121Conditions cXConditions; XPOIStateEvents cStateEvents; XC121SMCCycleHelper *cHelper; X121SMCCycleConditions cConditions; result = provider.SelectCycle( cycle, cState, cStateEvents, cXConditions, cHelper, cConditions // ); if (!result) { // cState.Clean(); ZeroMemory(cHelper); cConditions.Clean(); cXConditions.Clean(); cStateEvents.Clean(); // return result; } // bool isBoxBullish = box.IsBullish(); // int count = 0; bool has = false; // XBoxZone tmpBoxes[]; count = cState.FairValueGapsAsBox(tmpBoxes); has = IsValidSize(count); // // Check Must Contains Inner Cycle FVG ... XBoxZone selectedBox; bool hasSelectedBox = false; if (has) { // for (int i = 0; i < count; i++) { // XBoxZone iBox = tmpBoxes[i]; // // Regular Validation of Boxes ... bool isValid = IsBoxValid( iBox, 0, iBox.period // ); bool isTypePassed = iBox.dir == box.dir; bool isFromPssed = iBox.from >= box.from; bool isPlacePassed = IsBoxInsideOr( iBox, box // ) && (isBoxBullish ? iBox.lower >= box.lower : iBox.upper <= box.upper); has = isValid && isFromPssed && isTypePassed && isPlacePassed; if (!has) { // iBox.Clean(); continue; } // has = !hasSelectedBox ? true : isBoxBullish ? selectedBox.upper > iBox.upper : selectedBox.lower < iBox.lower; if (has) { // selectedBox = iBox; hasSelectedBox = selectedBox.IsValid(); } // iBox.Clean(); } } // result = hasSelectedBox; // if (result) { // // // From Index ... int fromIndex = GetBarIndex( selectedBox.symbol, selectedBox.period, selectedBox.from // ) + 1; result = IsValidIndex(fromIndex); // // To Index ... int toIndex = GetBarIndex( selectedBox.symbol, selectedBox.period, selectedBox.to // ); if (toIndex < 1) { toIndex = 1; } result = IsValidIndex(toIndex); // // Now we Have Retrieve X121Conditions between from and to Indexes ... // for Check States ... // bool hasNewValeUnderLast = false; bool isStrSwitchedToBullish = false; bool isSarSwitchedToBullish = false; bool hasValueGoldenZoneBreak = false; bool isSMHKSwitchedToBullish = false; bool isVWapSwitchedToBullishState = false; bool isX3MaSwitchedToBullishState = false; bool isVWapSwitchedToBullishOrdered = false; bool isX3MaSwitchedToBullishOrdered = false; // bool hasNewPeakOverLast = false; bool isStrSwitchedToBearish = false; bool isSarSwitchedToBearish = false; bool hasPeakGoldenZoneBreak = false; bool isSMHKSwitchedToBearish = false; bool isVWapSwitchedToBearishState = false; bool isX3MaSwitchedToBearishState = false; bool isVWapSwitchedToBearishOrdered = false; bool isX3MaSwitchedToBearishOrdered = false; // for (int i = fromIndex; i >= toIndex; i--) { // XOHCL iBar; has = iBar.Init( cState.symbol, cState.period, i // ); X121Conditions iConditions; has = has && cHelper.mX121Helper.GetConditions( iConditions, i // ); if (!has) { continue; } // // Bullish ... // if (!hasNewValeUnderLast) { hasNewValeUnderLast = iConditions.isNewValeUnderLast; } // if (!isStrSwitchedToBullish) { isStrSwitchedToBullish = iConditions.isStrSwitchedToBullish; } // if (!isSarSwitchedToBullish) { isSarSwitchedToBullish = iConditions.isSarSwitchedToBullish; } // if (!hasValueGoldenZoneBreak) { // hasValueGoldenZoneBreak = iBar.IsBullish() && iBar.GetUp() > iConditions.valesGoldenBuffer[1] && iBar.GetDown() < iConditions.valesGoldenBuffer[1]; } // if (!isSMHKSwitchedToBullish) { isSMHKSwitchedToBullish = iConditions.isSMHKSwitchedToBullish; } // if (!isVWapSwitchedToBullishState) { isVWapSwitchedToBullishState = iConditions.isVWapSwitchedToBullishState; } // if (!isX3MaSwitchedToBullishState) { isX3MaSwitchedToBullishState = iConditions.isX3MaSwitchedToBullishState; } // if (!isVWapSwitchedToBullishOrdered) { isVWapSwitchedToBullishOrdered = iConditions.isVWapSwitchedToBullishOrdered; } // if (!isX3MaSwitchedToBullishOrdered) { isX3MaSwitchedToBullishOrdered = iConditions.isX3MaSwitchedToBullishOrdered; } // // Bearish ... // if (!hasNewPeakOverLast) { hasNewPeakOverLast = iConditions.isNewPeakOverLast; } // if (!isStrSwitchedToBearish) { isStrSwitchedToBearish = iConditions.isStrSwitchedToBearish; } // if (!isSarSwitchedToBearish) { isSarSwitchedToBearish = iConditions.isSarSwitchedToBearish; } // if (!hasPeakGoldenZoneBreak) { // hasPeakGoldenZoneBreak = iBar.IsBearish() && iBar.GetUp() > iConditions.peaksGoldenBuffer[1] && iBar.GetDown() < iConditions.peaksGoldenBuffer[1]; } // if (!isSMHKSwitchedToBearish) { isSMHKSwitchedToBearish = iConditions.isSMHKSwitchedToBearish; } // if (!isVWapSwitchedToBearishState) { isVWapSwitchedToBearishState = iConditions.isVWapSwitchedToBearishState; } // if (!isX3MaSwitchedToBearishState) { isX3MaSwitchedToBearishState = iConditions.isX3MaSwitchedToBearishState; } // if (!isVWapSwitchedToBearishOrdered) { isVWapSwitchedToBearishOrdered = iConditions.isVWapSwitchedToBearishOrdered; } // if (!isX3MaSwitchedToBearishOrdered) { isX3MaSwitchedToBearishOrdered = iConditions.isX3MaSwitchedToBearishOrdered; } // iConditions.Clean(); } // // Bullish Conditions Summary ... // bool hasBullishOrConditions = hasNewValeUnderLast || isStrSwitchedToBullish || isSarSwitchedToBullish || hasValueGoldenZoneBreak || isSMHKSwitchedToBullish || isVWapSwitchedToBullishState || isX3MaSwitchedToBullishState || isVWapSwitchedToBullishOrdered || isX3MaSwitchedToBullishOrdered; // bool hasBullishAndConditions = hasNewValeUnderLast && hasValueGoldenZoneBreak && (isStrSwitchedToBullish || isSarSwitchedToBullish || isSMHKSwitchedToBullish || isVWapSwitchedToBullishState || isX3MaSwitchedToBullishState || isVWapSwitchedToBullishOrdered || isX3MaSwitchedToBullishOrdered); // // Bearish Conditions Summary ... // bool hasBearishOrConditions = hasNewPeakOverLast || isStrSwitchedToBearish || isSarSwitchedToBearish || hasPeakGoldenZoneBreak || isSMHKSwitchedToBearish || isVWapSwitchedToBearishState || isX3MaSwitchedToBearishState || isVWapSwitchedToBearishOrdered || isX3MaSwitchedToBearishOrdered; // bool hasBearishAndConditions = hasNewPeakOverLast && hasPeakGoldenZoneBreak && (isStrSwitchedToBearish || isSarSwitchedToBearish || isSMHKSwitchedToBearish || isVWapSwitchedToBearishState || isX3MaSwitchedToBearishState || isVWapSwitchedToBearishOrdered || isX3MaSwitchedToBearishOrdered); // bool isBullish = isBoxBullish && !hasBearishOrConditions && hasBullishAndConditions; // bool isBearish = !isBoxBullish && !hasBullishOrConditions && hasBearishAndConditions; // result = isBullish || isBearish; // if (result) { // XCBoxObject *iBoxObj; XCBoxObject *iInBoxObj; // has = provider .verificationCycleHelper .mPOIDrawer .DrawBox( box, iBoxObj // ); if (has) { // iBoxObj.BoxWidth(2); iBoxObj.BoxStyle(STYLE_SOLID); } // has = provider .verificationCycleHelper .mPOIDrawer .DrawBox( selectedBox, iInBoxObj // ); if (has) { // iInBoxObj.BoxWidth(2); iInBoxObj.BoxStyle(STYLE_DASH); } // Print("Inside Selected Box ..."); } } // // Cleanup Resources ... // cState.Clean(); Clean(tmpBoxes); selectedBox.Clean(); ZeroMemory(cHelper); cConditions.Clean(); cXConditions.Clean(); cStateEvents.Clean(); // return result; } // // Signalling Conditions Parsers ... // // Detect Signals Based On XPV Indicator Golden Zones ... bool HasXINDConditions( XBoxZone &waitingBoxes[], XBoxZone &activatedBoxes[], XBoxZone &breakedBoxes[], ENUM_X_CYCLES cycle, XBoxZone &box, XBoxZone &zone, ENUM_X_DIRECTION &dir, X121SMCStrategySignalProviderData &provider, int barIndex = 0 // ) { // bool result = false; // box.Clean(); zone.Clean(); dir = X_DIRECTION_NONE; // // Checking Required Zone Boxes for Signalling ... int waitingBoxesCount = ArraySize(waitingBoxes); int breakedBoxesCount = ArraySize(breakedBoxes); int activatedBoxesCount = ArraySize(activatedBoxes); // // Fil Selected Data ... XPOIState cState; X121Conditions cXConditions; XPOIStateEvents cStateEvents; XC121SMCCycleHelper *cHelper; X121SMCCycleConditions cConditions; result = provider.SelectCycle( cycle, cState, cStateEvents, cXConditions, cHelper, cConditions // ); if (!result) { // cState.Clean(); ZeroMemory(cHelper); cConditions.Clean(); cXConditions.Clean(); cStateEvents.Clean(); // return result; } // // Normalize Args ... // if (barIndex < 0) { barIndex = 0; } // int idx = -1; int count = 0; bool has = false; // int zIDX = barIndex; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int ppIDX = pIDX + 1; // bool isBullish = false; bool isBearish = false; // XOHCL zBar; XOHCL cBar; XOHCL pBar; XOHCL pPBar; // // Initial Bars ... result = zBar.Init( cState.symbol, cState.period, barIndex // ); result = result && zBar.GetPreviousBar(cBar); result = result && cBar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(pPBar); if (!result) { // zBar.Clean(); cBar.Clean(); pBar.Clean(); cState.Clean(); ZeroMemory(cHelper); cConditions.Clean(); cXConditions.Clean(); // return result; } // // Select Waiting Box ... XBoxZone selectedBox; bool hasSelectedBox = false; bool useWaitingBoxes = false; bool useActivtedBoxes = false; bool useBreakedBoxes = false; if (useWaitingBoxes && IsValidSize(waitingBoxesCount)) { // for (int i = 0; i < waitingBoxesCount; i++) { // XBoxZone iBox = waitingBoxes[i]; // iBox.Clean(); } // hasSelectedBox = selectedBox.IsValid(); if (!hasSelectedBox) { selectedBox.Clean(); } } if (useActivtedBoxes && !hasSelectedBox && IsValidSize(activatedBoxesCount)) { // for (int i = 0; i < activatedBoxesCount; i++) { // XBoxZone iBox = activatedBoxes[i]; // iBox.Clean(); } // hasSelectedBox = selectedBox.IsValid(); if (!hasSelectedBox) { selectedBox.Clean(); } } if (useBreakedBoxes && !hasSelectedBox && IsValidSize(breakedBoxesCount)) { // for (int i = 0; i < breakedBoxesCount; i++) { // XBoxZone iBox = breakedBoxes[i]; // iBox.Clean(); } // hasSelectedBox = selectedBox.IsValid(); if (!hasSelectedBox) { selectedBox.Clean(); } } // XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer; if (hasSelectedBox) { // selectedBox.to = zBar.time; XCBoxObject *iObj; has = drawer.DrawBox( selectedBox, iObj // ); if (has) { // iObj.BoxColor(clrCornflowerBlue); iObj.BoxStyle(STYLE_SOLID); iObj.BoxWidth(2); // Print("Selected Box ..."); } } ZeroMemory(drawer); // // // // // // // // Summarize Conditions ... // isBullish = // false // // ; // isBearish = // false // // ; // // Filling Requirements ... result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // box.dir = dir; box.from = pPBar.time; box.to = TimeCurrent(); box.symbol = cBar.symbol; box.period = cBar.period; // double points = GetPoints(box.symbol); // // Usually is Preffered SL ... double pivot = 0; // // Usually is Current Price or Entry Price ... double point = GetEntry( cBar.symbol, dir // ); // box.upper = isBullish ? point : pivot; // box.lower = isBullish ? pivot : point; // zone = selectedBox; // // XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer; // bool drawBoxes = true; // if (drawBoxes) // { // // // if (box.IsValid()) // { // // // XCBoxObject *iObj; // bool isCreated = drawer.DrawBox( // box, // iObj // // ); // // // if (isCreated) // { // // // // TODO: ... // } // } // } } // // Check All Conditions ... result = box.IsValid() && HasDirection(dir) && (isBullish || isBearish); // // Cleanup Resources ... zBar.Clean(); cBar.Clean(); pBar.Clean(); pPBar.Clean(); cState.Clean(); cConditions.Clean(); cConditions.Clean(); ZeroMemory(cHelper); selectedBox.Clean(); cStateEvents.Clean(); cXConditions.Clean(); // return result; } // // // //