/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 X121 SMC Signal Class // ------------------------------------------------- // Name: // Description: provide all Signalling functions ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../Classes/x-121.smc.market.cycle.helper.class.mq5" #include "../Libraries/x-121.smc.lib.mq5" // // Definitions ... struct X121SMCStrategyXPVSUPDEMSignalConditions { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // double sl; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; // // Setup Props ... // datetime setupTime; datetime triggerTime; // XCTicksZone *ticksZone; XCSupplyZone *supplyZones[]; XCDemandZone *demandZones[]; datetime activeZoneFoundedAt; XCSupplyZone *activeSupplyZone; XCDemandZone *activeDemandZone; // // Constructor ... X121SMCStrategyXPVSUPDEMSignalConditions() { 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(); } /** * 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() { // ticksZone = NULL; activeSupplyZone = NULL; activeDemandZone = NULL; activeZoneFoundedAt = NULL; // Clean(supplyZones); Clean(demandZones); } /** * Count Supply Zones ... * * @return ( int ) */ int CountSupplyZones() { return ArraySize(supplyZones); } /** * Count Demand Zones ... * * @return ( int ) */ int CountDemandZones() { return ArraySize(demandZones); } /** * Check Has Supply Zones ... * * @return ( bool ) */ bool HasSupplyZones() { return IsValidSize(CountSupplyZones()); } /** * Check Has Demand Zones ... * * @return ( bool ) */ bool HasDemandZones() { return IsValidSize(CountDemandZones()); } /** * Check Has Active Supply or Demand Zone ... * * @param _dir: ENUM_X_DIRECTION member Reference for Specify Active Zone ... * * @return ( bool ) */ bool HasActiveZone(ENUM_X_DIRECTION &_dir) { // bool result = false; // _dir = X_DIRECTION_NONE; // // Check Supplies ... bool hasActiveSupplyZone = activeSupplyZone != NULL && activeSupplyZone.IsValid(); // // Check Demnds ... bool hasActiveDemandZone = activeDemandZone != NULL && activeDemandZone.IsValid(); // result = hasActiveSupplyZone || hasActiveDemandZone; if (!result) { return result; } // _dir = hasActiveDemandZone ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } /** * Retrieve Active Zone Reference if Exists ... * * @return ( bool ) */ bool GetActiveZone(XCBarZone *&activeZone) { // bool result = false; // activeZone = NULL; // ENUM_X_DIRECTION activeZoneDir; result = HasActiveZone(activeZoneDir); if (!result) { return result; } // if (IsBullish(activeZoneDir)) { // activeDemandZone.To(TimeCurrent()); activeZone = activeDemandZone; } else { // activeSupplyZone.To(TimeCurrent()); activeZone = activeSupplyZone; } // return result; } /** * Check Ticks Zone is Initialized or not ... * @return ( bool ) */ bool HasTicksZone() { // bool result = false; // result = // ticksZone != NULL && ticksZone.IsValid() && IsValidSize(ticksZone.Count()) // ; // return result; } // }; // // Extension Functions ... // // Detect Setup Conditions ... bool DetectX121SMCXPVSUPDEMSiganlSetup( string _symbol, ENUM_TIMEFRAMES _period, // X121SMCStrategyXPVSUPDEMSignalConditions &conditions, // XC121SMCCycleHelper *triggerCycleHelper, XC121SMCCycleHelper *decisionCycleHelper, XC121SMCCycleHelper *analyseCycleHelper, XC121SMCCycleHelper *verificationCycleHelper, XC121SMCCycleHelper *consolidationCycleHelper, XC121SMCCycleHelper *visionCycleHelper // ) { // bool result = false; // bool isBullish = false; bool isBearish = false; // int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 1; int ppIndex = pIndex + 1; // int loopback = 10; // string symbol = _symbol; ENUM_TIMEFRAMES period = _period; // conditions.symbol = symbol; conditions.period = period; // XOHCL zBar; result = zBar.Init( symbol, period, zIndex // ); if (!result) { return result; } // XOHCL cBar; result = cBar.Init( symbol, period, cIndex // ); if (!result) { return result; } // double ask = GetAsk(symbol); double bid = GetBid(symbol); datetime cTime = TimeCurrent(); // double ll = cBar.FindLowest(9, MODE_LOW); double hh = cBar.FindHighest(9, MODE_HIGH); // int zoneValidationDivider = 10; int validPivotRepetition = triggerCycleHelper.mX121Helper .GetDonChainLength(); // double selectedSL = 0; // // Cycles Conditions ... // // Trigger ... ENUM_XPOI_EVENTS triggerPoiEvents[]; ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; X121SMCCycleConditions triggerConditions; result = triggerCycleHelper.GetConditions( triggerCycleEvents, triggerPoiEvents, triggerConditions, zIndex, loopback // ); if (!result) { return result; } // // Decision ... ENUM_XPOI_EVENTS decisionPoiEvents[]; ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; X121SMCCycleConditions decisionConditions; result = decisionCycleHelper.GetConditions( decisionCycleEvents, decisionPoiEvents, decisionConditions, zIndex, loopback // ); if (!result) { return result; } // // Analyse ... ENUM_XPOI_EVENTS analysePoiEvents[]; ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; X121SMCCycleConditions analyseConditions; result = analyseCycleHelper.GetConditions( analyseCycleEvents, analysePoiEvents, analyseConditions, zIndex, loopback // ); if (!result) { return result; } // // Verification ... ENUM_XPOI_EVENTS verificationPoiEvents[]; ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; X121SMCCycleConditions verificationConditions; result = verificationCycleHelper.GetConditions( verificationCycleEvents, verificationPoiEvents, verificationConditions, zIndex, loopback // ); if (!result) { return result; } // // Consolidation ... ENUM_XPOI_EVENTS consolidationPoiEvents[]; ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; X121SMCCycleConditions consolidationConditions; result = consolidationCycleHelper.GetConditions( consolidationCycleEvents, consolidationPoiEvents, consolidationConditions, zIndex, loopback // ); if (!result) { return result; } // // Vision ... ENUM_XPOI_EVENTS visionPoiEvents[]; ENUM_X_CYCLE_EVENTS visionCycleEvents[]; X121SMCCycleConditions visionConditions; result = visionCycleHelper.GetConditions( visionCycleEvents, visionPoiEvents, visionConditions, zIndex, loopback // ); if (!result) { return result; } // // Cycles POI States ... XPOIState triggerState = triggerConditions.state; XPOIState decisionState = decisionConditions.state; XPOIState analyseState = analyseConditions.state; XPOIState verificationState = verificationConditions.state; XPOIState consolidationState = consolidationConditions.state; XPOIState visionState = visionConditions.state; // // Setup Conditions ... // // Select Source State ... XPOIState state = consolidationState; // // Detect Supply and Demand Zones ... // // Supply ... bool hasSupplyZones = conditions.HasSupplyZones(); if (!hasSupplyZones) { // int count = state.CountSupplyZones(); for (int i = count - 1; i >= 0; i--) { // XCSupplyZone *iZone = state.supplyZones[i]; // bool isValid = // ask < iZone.Lower() && bid < iZone.Lower() && cBar.high < iZone.Lower() // ; if (isValid) { // Add( iZone, conditions.supplyZones // ); } } // hasSupplyZones = conditions.HasSupplyZones(); result = hasSupplyZones; if (!result) { return result; } } // // Demand ... bool hasDemandZones = conditions.HasDemandZones(); if (!hasDemandZones) { // int count = state.CountDemandZones(); for (int i = count - 1; i >= 0; i--) { // XCDemandZone *iZone = state.demandZones[i]; // bool isValid = // ask > iZone.Upper() && bid > iZone.Upper() && cBar.low > iZone.Upper() // ; if (isValid) { // Add( iZone, conditions.demandZones // ); } } // hasDemandZones = conditions.HasDemandZones(); result = hasDemandZones; if (!result) { return result; } } // // Waits For Price to Go Inside a Zone ... ENUM_X_DIRECTION activeZoneDir = X_DIRECTION_NONE; bool hasActiveZone = conditions.HasActiveZone(activeZoneDir); if (!hasActiveZone) { // // Looking Up For Active Zone ... // // Supply ... if (hasSupplyZones) { // int count = conditions.CountSupplyZones(); for (int i = count - 1; i >= 0; i--) { // XCSupplyZone *iZone = conditions.supplyZones[i]; // bool isValid = // ask <= iZone.Upper() && bid <= iZone.Upper() && ask >= iZone.Lower() && bid >= iZone.Lower() && cBar.high <= iZone.Upper() && cBar.low >= iZone.Lower() // ; if (isValid) { // conditions.activeSupplyZone = iZone; break; } } } // hasActiveZone = conditions.HasActiveZone(activeZoneDir); if (!hasActiveZone) { // // Demand ... if (hasDemandZones) { // int count = conditions.CountDemandZones(); for (int i = count - 1; i >= 0; i--) { // XCDemandZone *iZone = conditions.demandZones[i]; // bool isValid = // ask <= iZone.Upper() && bid <= iZone.Upper() && ask >= iZone.Lower() && bid >= iZone.Lower() && cBar.high <= iZone.Upper() && cBar.low >= iZone.Lower() // ; if (isValid) { // conditions.activeDemandZone = iZone; break; } } } } // hasActiveZone = conditions.HasActiveZone(activeZoneDir); result = hasActiveZone; if (!result) { return result; } // conditions.activeZoneFoundedAt = cTime; } // // Now we Have to Calculate Active Zones Ticks ... // // Select Active Zone ... XCBarZone *activeZone = NULL; result = conditions.GetActiveZone(activeZone); if (!result) { return result; } // // Extract Active Zone Start Bar ... XOHCL fromBar; datetime fromTime = activeZone.BarTime(); result = triggerCycleHelper.GetBar( fromBar, fromTime // ); if (!result) { return result; } // bool hasTicksZone = conditions.HasTicksZone(); if (!hasTicksZone) { // // Istantiate Ticks Zone ... conditions.ticksZone = new XCTicksZone(); conditions.ticksZone.Levels(40); } // // Update Ticks Zone ... result = conditions.ticksZone.Init( fromBar, cBar // ); if (!result) { return result; } // // Regenrate Conditions ... hasTicksZone = conditions.HasTicksZone(); result = hasTicksZone; if (!result) { return result; } // // Make Sure we Have a Direction for Setup ... isBullish = IsBullish(activeZoneDir); isBearish = IsBearish(activeZoneDir); result = isBullish || isBearish; if (!result) { return result; } // // Check New Peaks or Vales Happens inside Zero Tick or Volume Percent Zone and // also Active Zone ... double peak = triggerConditions.x121Conditions.peaksBuffer[1]; double vale = triggerConditions.x121Conditions.valesBuffer[1]; bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; // bool isPeakInsideActiveZone = // peak <= activeZone.Upper() && peak >= activeZone.Lower() // ; bool isValeInsideActiveZone = // vale <= activeZone.Upper() && vale >= activeZone.Lower() // ; // bool isPeakInsideZeroZone = false; bool isValeInsideZeroZone = false; int tzCount = conditions.ticksZone.Count(); if (IsValidSize(tzCount)) { // for (int i = 0; i < tzCount; i++) { // XCTickZone *iTZ = conditions.ticksZone.GetZone(i); // if (isBearish && !isPeakInsideZeroZone) { // isPeakInsideZeroZone = // peak <= iTZ.high && peak >= iTZ.low && (iTZ.percent == 0 || iTZ.volumePercent == 0) // ; } // if (isBullish && !isValeInsideZeroZone) { // isValeInsideZeroZone = // vale <= iTZ.high && vale >= iTZ.low && (iTZ.percent == 0 || iTZ.volumePercent == 0) // ; } // if (isPeakInsideZeroZone || isValeInsideZeroZone) { break; } } } // isBullish = // isBullish && isNewValeUnderLast && isValeInsideZeroZone && isValeInsideActiveZone // ; // isBearish = // isBearish && isNewPeakOverLast && isPeakInsideZeroZone && isPeakInsideActiveZone // ; // result = isBullish || isBearish; if (!result) { // // Clean Conditions for Regenerate ... int activeZoneAge = (int)(cTime - conditions.activeZoneFoundedAt) / PeriodSeconds(conditions.period); if (activeZoneAge >= 200) { conditions.Clean(); } // return result; } // conditions.setupTime = cTime; conditions.dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } // // Detect Trigger Conditions ... bool DetectX121SMCXPVSUPDEMSiganlTrigger( // X121SMCStrategyXPVSUPDEMSignalConditions &conditions, // string _symbol, ENUM_TIMEFRAMES _period, // XC121SMCCycleHelper *triggerCycleHelper, XC121SMCCycleHelper *decisionCycleHelper, XC121SMCCycleHelper *analyseCycleHelper, XC121SMCCycleHelper *verificationCycleHelper, XC121SMCCycleHelper *consolidationCycleHelper, XC121SMCCycleHelper *visionCycleHelper, // int maxAllowedSetupAge = 60 // // ) { // bool result = false; // result = conditions.IsSetuped(); if (!result) { return result; } // datetime setupTime = conditions.setupTime; ENUM_X_DIRECTION setupDir = conditions.dir; // bool isBullish = false; bool isBearish = false; // int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 1; int ppIndex = pIndex + 1; // int loopback = 10; // string symbol = _symbol; ENUM_TIMEFRAMES period = _period; // XOHCL zBar; result = zBar.Init( symbol, period, zIndex // ); if (!result) { return result; } // XOHCL cBar; result = cBar.Init( symbol, period, cIndex // ); if (!result) { return result; } // double ask = GetAsk(symbol); double bid = GetBid(symbol); datetime cTime = TimeCurrent(); // double ll = cBar.FindLowest(9, MODE_LOW); double hh = cBar.FindHighest(9, MODE_HIGH); // int zoneValidationDivider = 10; int validPivotRepetition = triggerCycleHelper.mX121Helper .GetDonChainLength(); // double selectedSL = 0; // // Cycles Conditions ... // // Trigger ... ENUM_XPOI_EVENTS triggerPoiEvents[]; ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; X121SMCCycleConditions triggerConditions; result = triggerCycleHelper.GetConditions( triggerCycleEvents, triggerPoiEvents, triggerConditions, zIndex, loopback // ); if (!result) { return result; } // // Decision ... ENUM_XPOI_EVENTS decisionPoiEvents[]; ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; X121SMCCycleConditions decisionConditions; result = decisionCycleHelper.GetConditions( decisionCycleEvents, decisionPoiEvents, decisionConditions, zIndex, loopback // ); if (!result) { return result; } // // Analyse ... ENUM_XPOI_EVENTS analysePoiEvents[]; ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; X121SMCCycleConditions analyseConditions; result = analyseCycleHelper.GetConditions( analyseCycleEvents, analysePoiEvents, analyseConditions, zIndex, loopback // ); if (!result) { return result; } // // Verification ... ENUM_XPOI_EVENTS verificationPoiEvents[]; ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; X121SMCCycleConditions verificationConditions; result = verificationCycleHelper.GetConditions( verificationCycleEvents, verificationPoiEvents, verificationConditions, zIndex, loopback // ); if (!result) { return result; } // // Consolidation ... ENUM_XPOI_EVENTS consolidationPoiEvents[]; ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; X121SMCCycleConditions consolidationConditions; result = consolidationCycleHelper.GetConditions( consolidationCycleEvents, consolidationPoiEvents, consolidationConditions, zIndex, loopback // ); if (!result) { return result; } // // Vision ... ENUM_XPOI_EVENTS visionPoiEvents[]; ENUM_X_CYCLE_EVENTS visionCycleEvents[]; X121SMCCycleConditions visionConditions; result = visionCycleHelper.GetConditions( visionCycleEvents, visionPoiEvents, visionConditions, zIndex, loopback // ); if (!result) { return result; } // // Cycles POI States ... XPOIState triggerState = triggerConditions.state; XPOIState decisionState = decisionConditions.state; XPOIState analyseState = analyseConditions.state; XPOIState verificationState = verificationConditions.state; XPOIState consolidationState = consolidationConditions.state; XPOIState visionState = visionConditions.state; // // Trigger Conditions ... // // Select Active Zone Class ... XCBarZone *activeZone = NULL; result = conditions.GetActiveZone(activeZone); if (!result) { return result; } // // Check Last Valid Peak or Last Valid Vales Breaks ... // Beak Of Structure ... // // Peak ... double peak = triggerConditions.x121Conditions.peaksBuffer[1]; XPVPivotPoint lastPeakPivot; bool hasLastPeakPivot = triggerCycleHelper .GetLastPeakPivotPoint(lastPeakPivot); bool isLastPeakPivotBreaked = // lastPeakPivot.IsPeak() && lastPeakPivot.IsValid() && peak > lastPeakPivot.value // ; // // Vale ... double vale = triggerConditions.x121Conditions.valesBuffer[1]; XPVPivotPoint lastValePivot; bool hasLastValePivot = triggerCycleHelper .GetLastValePivotPoint(lastValePivot); bool isLastValePivotBreaked = // lastValePivot.IsVale() && lastValePivot.IsValid() && vale < lastValePivot.value // ; // isBullish = // IsBullish(setupDir) && isLastValePivotBreaked // ; // isBearish = // IsBearish(setupDir) && isLastPeakPivotBreaked // ; // result = isBullish || isBearish; if (!result) { // // Cleanup Setup Conditions ... int setupAge = conditions.GetSetupAge(); if (IsValidSize(setupAge) && IsValidSize(maxAllowedSetupAge) && setupAge >= maxAllowedSetupAge) { conditions.Clean(); } // return result; } // conditions.triggerTime = cTime; conditions.sl = isBullish ? activeZone.Lower() : activeZone.Upper(); conditions.type = isBullish ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; // return result; } //