/////////////////////////////////////////////////////// // // 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 X121SMCStrategyXTWPVSignalConditions { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // double sl; double target; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; // // Setup Props ... // datetime setupTime; datetime triggerTime; // XMarketStructure consolidationMarketStructure; XMarketStructure analyseMarketStructure; // datetime newPeakAboveAtrUpperAt; datetime newValeBelowAtrLowerAt; datetime sarSiwtchedToBullishAt; datetime sarSiwtchedToBearishAt; datetime rsiCrossedOverOverSoldAt; datetime rsiCrossedUnderOverBoughtAt; // XPriceZones decisionZone; XPriceZones peakPriceZone; XPriceZones valePriceZone; // // Constructor ... X121SMCStrategyXTWPVSignalConditions() { Clean(); } // // Tools ... /** * Cleaning Up ... */ void Clean() { // sl = 0; target = 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() { // decisionZone.Clean(); peakPriceZone.Clean(); valePriceZone.Clean(); // analyseMarketStructure.Clean(); consolidationMarketStructure.Clean(); // newPeakAboveAtrUpperAt = NULL; newValeBelowAtrLowerAt = NULL; sarSiwtchedToBullishAt = NULL; sarSiwtchedToBearishAt = NULL; rsiCrossedOverOverSoldAt = NULL; rsiCrossedUnderOverBoughtAt = NULL; } /** * Check Required Market Strucutre Exists or not ... * * @return ( bool ) */ bool HasMarketStrucutre() { // bool result = false; // result = // analyseMarketStructure.IsValid() && consolidationMarketStructure.IsValid() // && // analyseMarketStructure.HasTrend() && consolidationMarketStructure.HasTrend() // && // analyseMarketStructure.bias == consolidationMarketStructure.bias // ; // return result; } /** * Check if Conditions Filled ... * * @return ( bool ) */ bool IsFilled() { // bool result = false; // result = HasMarketStrucutre(); if (!result) { return result; } // bool isBullish = IsBullish(analyseMarketStructure.bias); // result = isBullish ? IsValid(newValeBelowAtrLowerAt) && IsValid(sarSiwtchedToBullishAt) && IsValid(rsiCrossedOverOverSoldAt) : IsValid(newPeakAboveAtrUpperAt) && IsValid(sarSiwtchedToBearishAt) && IsValid(rsiCrossedUnderOverBoughtAt); // return result; } /** * Check if Has Price Zones ... * * @return ( bool ) */ bool HasPriceZone() { // bool result = false; // result = HasMarketStrucutre(); if (!result) { return result; } // bool isBullish = IsBullish(analyseMarketStructure.bias); // result = isBullish ? valePriceZone.IsValid() : peakPriceZone.IsValid(); // return result; } /** * Check if Has Decision Zones ... * * @return ( bool ) */ bool HasDecisionZone() { return HasPriceZone() && decisionZone.IsValid(); } // }; // // Extension Functions ... // // Detect Setup Conditions ... bool DetectX121SMCXTWPVSiganlSetup( string _symbol, ENUM_TIMEFRAMES _period, // X121SMCStrategyXTWPVSignalConditions &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; } // XOHCL pBar; result = pBar.Init( symbol, period, pIndex // ); if (!result) { return result; } // double ask = GetAsk(symbol); double bid = GetBid(symbol); datetime cTime = TimeCurrent(); double points = GetPoints(symbol); // int swingLoopback = 9; double ll = cBar.FindLowest(swingLoopback, MODE_LOW); double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); double llDown = cBar.FindLowesttDown(swingLoopback); double hhUp = cBar.FindHighestUp(swingLoopback); // // 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 ... // bool hasMarketStructure = conditions.HasMarketStrucutre(); if (!hasMarketStructure) { // bool hasConsolidationMarketStructure = consolidationCycleHelper .DetectMarketStructure(conditions.consolidationMarketStructure); // bool hasAnalyseMarketStructure = analyseCycleHelper .DetectMarketStructure(conditions.analyseMarketStructure); // hasMarketStructure = conditions.HasMarketStrucutre(); result = hasMarketStructure; if (!result) { return result; } } // // We Are Sure we Have Direct Structure Bias ... isBullish = IsBullish(conditions.analyseMarketStructure.bias); isBearish = IsBearish(conditions.analyseMarketStructure.bias); // // RSI ... double rsi = triggerConditions.x121Conditions.rsiBuffer[1]; // bool isRSICrossedOverOverBought = triggerConditions.x121Conditions.isRSICrossedOverOverBought; bool isRSICrossedUnderOverBought = triggerConditions.x121Conditions.isRSICrossedUnderOverBought; // bool isRSICrossedOverOverSold = triggerConditions.x121Conditions.isRSICrossedOverOverSold; bool isRSICrossedUnderOverSold = triggerConditions.x121Conditions.isRSICrossedUnderOverSold; // // PV ... double peak = triggerConditions.x121Conditions.peaksBuffer[1]; double vale = triggerConditions.x121Conditions.valesBuffer[1]; // bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; bool isNewVale = triggerConditions.x121Conditions.isNewVale; // // ATR ... double atr = triggerConditions.x121Conditions.atrBuffer[1]; double atrUpper = triggerConditions.x121Conditions.atrUpperBuffer[1]; double atrLower = triggerConditions.x121Conditions.atrLowerBuffer[1]; // // SAR ... double sar = triggerConditions.x121Conditions.sarBuffer[1]; // bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; // // Complex Conditions ... // bool isNewPeakAboveAtrUpper = isNewPeak && peak > atrUpper; // bool isNewValeBelowAtrLower = isNewVale && vale < atrLower; // // Fill Conditions ... bool isConditionsFilled = conditions.IsFilled(); if (!isConditionsFilled) { // // Cleanup ... // // Sar ... // // Bullish ... if (isBullish && isSarSwitchedToBearish && IsValid(conditions.sarSiwtchedToBullishAt)) { conditions.sarSiwtchedToBullishAt = NULL; } // // Bearish ... if (isBearish && isSarSwitchedToBullish && IsValid(conditions.sarSiwtchedToBearishAt)) { conditions.sarSiwtchedToBearishAt = NULL; } // // Rsi ... // // Bullish ... if (isBullish && isRSICrossedUnderOverSold && IsValid(conditions.rsiCrossedOverOverSoldAt)) { conditions.rsiCrossedOverOverSoldAt = NULL; } // // Bearish ... if (isBearish && isRSICrossedOverOverBought && IsValid(conditions.rsiCrossedUnderOverBoughtAt)) { conditions.rsiCrossedUnderOverBoughtAt = NULL; } // // Atr Change ... // // Bullish ... if (isBullish && isNewPeak && IsValid(conditions.newValeBelowAtrLowerAt)) { conditions.newValeBelowAtrLowerAt = NULL; } // // Bearish ... if (isBearish && isNewVale && IsValid(conditions.newPeakAboveAtrUpperAt)) { conditions.newPeakAboveAtrUpperAt = NULL; } // // Filling Up ... // // Sar Change ... // // Bullish ... if (isBullish && isSarSwitchedToBullish && !IsValid(conditions.sarSiwtchedToBullishAt)) { conditions.sarSiwtchedToBullishAt = cTime; } // // Bearish ... if (isBearish && isSarSwitchedToBearish && !IsValid(conditions.sarSiwtchedToBearishAt)) { conditions.sarSiwtchedToBearishAt = cTime; } // // Rsi Change ... // // Bullish ... if (isBullish && isRSICrossedOverOverSold && !IsValid(conditions.rsiCrossedOverOverSoldAt)) { conditions.rsiCrossedOverOverSoldAt = cTime; } // // Bearish ... if (isBearish && isRSICrossedUnderOverBought && !IsValid(conditions.rsiCrossedUnderOverBoughtAt)) { conditions.rsiCrossedUnderOverBoughtAt = cTime; } // // Atr Change ... // New Peaks and Vale ... // // Bullish ... if (isBullish && isNewValeBelowAtrLower && !IsValid(conditions.newValeBelowAtrLowerAt)) { conditions.newValeBelowAtrLowerAt = cTime; } // // Bearish ... if (isBearish && isNewPeakAboveAtrUpper && !IsValid(conditions.newPeakAboveAtrUpperAt)) { conditions.newPeakAboveAtrUpperAt = cTime; } // isConditionsFilled = conditions.IsFilled(); result = isConditionsFilled; if (!result) { return result; } } // // Fill Price Zones ... bool hasPriceZone = conditions.HasPriceZone(); if (!hasPriceZone) { // if (isBullish) { // XPriceZones vPZone; bool hasValeInsideZone = CalculatePriceInsideZones( vPZone, analyseState, vale // ); // XPriceZones cbPZone; bool hasPriceInsideZone = CalculatePriceInsideZones( cbPZone, analyseState, cBar // ); // if (hasValeInsideZone && hasPriceInsideZone && vPZone.IsBullish() && cbPZone.IsBullish()) { conditions.valePriceZone = cbPZone; } } else if (isBearish) { // XPriceZones pPZone; bool hasPeakInsideZone = CalculatePriceInsideZones( pPZone, analyseState, peak // ); // XPriceZones cbPZone; bool hasPriceInsideZone = CalculatePriceInsideZones( cbPZone, analyseState, cBar // ); // if ( hasPeakInsideZone && hasPriceInsideZone && pPZone.IsBearish() && cbPZone.IsBearish()) { conditions.peakPriceZone = cbPZone; } } // hasPriceZone = conditions.HasPriceZone(); result = hasPriceZone; if (!result) { return result; } } // // Check for Decision ... bool hasDecision = conditions.HasDecisionZone(); if (!hasDecision) { // if (isBullish) { // XPriceZones pZone; bool hasPZone = CalculatePriceInsideZones( pZone, decisionState, vale // ); // if (hasPZone && pZone.IsBullish()) { conditions.decisionZone = pZone; } } else if (isBearish) { // XPriceZones pZone; bool hasPZone = CalculatePriceInsideZones( pZone, decisionState, peak // ); // if (hasPZone && pZone.IsBearish()) { conditions.decisionZone = pZone; } } // hasDecision = conditions.HasDecisionZone(); result = hasDecision; if (!result) { return result; } } // result = isBullish || isBearish; if (!result) { return result; } // conditions.setupTime = cTime; conditions.dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // return result; } // // Detect Trigger Conditions ... bool DetectX121SMCXTWPVSiganlTrigger( // X121SMCStrategyXTWPVSignalConditions &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 = IsBullish(setupDir); bool isBearish = IsBearish(setupDir); // 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; } // XOHCL pBar; result = pBar.Init( symbol, period, pIndex // ); if (!result) { return result; } // double ask = GetAsk(symbol); double bid = GetBid(symbol); datetime cTime = TimeCurrent(); double points = GetPoints(symbol); // int swingLoopback = 9; double ll = cBar.FindLowest(swingLoopback, MODE_LOW); double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); double llDown = cBar.FindLowesttDown(swingLoopback); double hhUp = cBar.FindHighestUp(swingLoopback); // // 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 ... // // Detect Bullish Conditions ... isBullish = isBullish && cBar.IsBullish(); // // Detect Bearish Conditions ... isBearish = isBearish && cBar.IsBearish(); // result = isBullish || isBearish; if (!result) { // // Cleanup Setup Conditions ... int setupAge = conditions.GetSetupAge(); if (IsValidSize(setupAge) && IsValidSize(maxAllowedSetupAge) && setupAge >= maxAllowedSetupAge) { conditions.Clean(); } // return result; } // // Detect Nearest Pivot Point ... // // Detect Target ... double target = CalculateTarget( cBar, analyseState, setupDir // ); if (target == 0) { // target = CalculateTarget( cBar, verificationState, setupDir // ); } // double oppositTarget = CalculateTarget( cBar, analyseState, Opposit(setupDir) // ); // double entry = GetEntry( conditions.symbol, setupDir // ); // // Filling SL Candidates ... // double sls[]; // double atr = triggerConditions.x121Conditions.atrBuffer[1]; double peak = triggerConditions.x121Conditions.peaksBuffer[1]; double vale = triggerConditions.x121Conditions.valesBuffer[1]; // if (isBullish) { // double lowerVale = triggerCycleHelper.mX121Helper.xpvHelper.GetLowerVale(vale); if (lowerVale > 0) { // Add( lowerVale, sls // ); } } else if (isBearish) { // double higherPeak = triggerCycleHelper.mX121Helper.xpvHelper.GetHigherPeak(peak); if (higherPeak > 0) { // Add( higherPeak, sls // ); } } // if (ArraySize(sls) == 0) { } // double slsMin = GetMin(sls); double slsMax = GetMax(sls); // double sl = isBullish ? slsMin - atr : slsMax + atr; double risk = MathAbs(entry - sl); double targetDelta = 2 * (risk / 3); if (target == 0) { // int minTargetPint = 50; double minTargetPointValue = minTargetPint * points; if (targetDelta < minTargetPointValue) { targetDelta = minTargetPointValue; } // // Force Target On Half Risk ... target = isBullish ? entry + targetDelta : entry - targetDelta; // target = 0; // } // // Ignore Target ... target = 0; // // Filling Conditions Props ... conditions.sl = sl; conditions.target = target; conditions.triggerTime = cTime; conditions.type = isBullish ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; // return result; } // // Draw Signal ... int DrawX121SMCXTWPVSiganl( X121SMCStrategyXTWPVSignalConditions &conditions, XCBaseObject *&drawnObjects[], XCPOIDrawer *drawer // ) { // int result = 0; // Clean(drawnObjects); // if (drawer == NULL) { return result; } // bool isSetuped = conditions.IsSetuped(); if (!isSetuped) { return result; } // bool isBullish = IsBullish(conditions.dir); // XCBaseObject *priceZoneObjs[]; XCBaseObject *decisionZoneObjs[]; XCBaseObject *marketStructureObjs[]; // bool hasMarketStructure = conditions.HasMarketStrucutre(); if (hasMarketStructure) { // // // drawer.DrawMarketStructure( // conditions.analyseMarketStructure, // marketStructureObjs // // ); } // bool hasPriceZone = conditions.HasPriceZone(); if (hasPriceZone) { // XPriceZones pZone; if (isBullish) { pZone = conditions.valePriceZone; } else { pZone = conditions.peakPriceZone; } // drawer.DrawPriceZone( pZone, priceZoneObjs, conditions.dir // ); } // bool hasDecisionZone = conditions.HasDecisionZone(); if (hasDecisionZone) { // drawer.DrawPriceZone( conditions.decisionZone, decisionZoneObjs // , // conditions.dir // ); } // Copy( priceZoneObjs, drawnObjects, false // ); // Copy( decisionZoneObjs, drawnObjects, false // ); // Copy( marketStructureObjs, drawnObjects, false // ); // result = ArraySize(drawnObjects); // return result; } //