From 7c4cfd4321984ec33e95710bf2d1bd8c3d6e1678 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 23 Dec 2024 19:18:55 +0330 Subject: [PATCH] last ... --- .../1/x-121.smc.market.cycle.helper.class.mq5 | 2466 +++++++++++++++++ .../BKP/1/x-121.smc.test.signal.class.mq5 | 831 ++++++ .../BKP/1/x-121.smc.test.strategy.class.mq5 | 2088 ++++++++++++++ Documents/BKP/x-121.smc.test.signal.class.mq5 | 787 ++++++ Experts/x-saherelm.x-121.smc.ea.mq5 | 2 +- Libraries/x-saherelm.x-poi.lib.mq5 | 40 + .../x-121.smc.market.cycle.helper.class.mq5 | 186 +- .../Signals/x-121.smc.test.signal.class.mq5 | 1250 +++++++-- .../x-121.smc.test.strategy.class.mq5 | 243 +- 9 files changed, 7465 insertions(+), 428 deletions(-) create mode 100644 Documents/BKP/1/x-121.smc.market.cycle.helper.class.mq5 create mode 100644 Documents/BKP/1/x-121.smc.test.signal.class.mq5 create mode 100644 Documents/BKP/1/x-121.smc.test.strategy.class.mq5 create mode 100644 Documents/BKP/x-121.smc.test.signal.class.mq5 diff --git a/Documents/BKP/1/x-121.smc.market.cycle.helper.class.mq5 b/Documents/BKP/1/x-121.smc.market.cycle.helper.class.mq5 new file mode 100644 index 00000000..be6dad69 --- /dev/null +++ b/Documents/BKP/1/x-121.smc.market.cycle.helper.class.mq5 @@ -0,0 +1,2466 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XC121SMCCycleHelper +// Description: provides all based classes for use ... +// +// +// 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-saherelm.x-bar.analyser.class.mq5" +#include "../../Classes/x-saherelm.x-poi.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... + +// +// Implementations ... + +enum ENUM_X_CYCLES +{ + X_CYCLE_TRIGGER, + X_CYCLE_DECISION, + X_CYCLE_ANALYSE, + X_CYCLE_VERIFICATION, + X_CYCLE_CONSOLIDATION, + X_CYCLE_VISION, +}; + +enum ENUM_X_CYCLE_EVENTS +{ + SAR_CHANGE_DETECTED, + NEW_PEAK_DETECTED, + NEW_VALE_DETECTED, + PIVOT_POINT_DETECTED, + VWAP_ORDER_CHANGE_ETECTED, + VWAP_STATE_CHANGE_DETCTED, + CONSOLIDATION_BREAKED_DETECTED, + PIVOT_STARTED, + PIVOT_ENDED, +}; + +class XC121SMCCycleHelper : public XCBase +{ + // + public: + // + // Props ... + + // + // X121 ... + XCX121Helper *mX121Helper; + + // + // POI Detector ... + XCPOIDetector *mPOIDetector; + + // + // Bar Analyser + XCBarAnalyser *mBarAnalyser; + + // + // Constructor(s) ... + XC121SMCCycleHelper() + { + Default(); + } + + // + // Deconstructor ... + ~XC121SMCCycleHelper() + { + DeInit(); + } + + // + // Getter/Setter(s) ... + + /** + * Get Max llowed Changes to Save ... + * + * @return ( int ) + */ + int MaxAllowedSavedChanges() + { + return mMaxAllowedSavedChanges; + } + + /** + * Set Max llowed Changes to Save ... + * + * @param value: Integer ... + */ + void MaxAllowedSavedChanges(int value) + { + // + if (value < 10) + { + value = 10; + } + + // + mMaxAllowedSavedChanges = value; + } + + /** + * Get Consolidation Loopback Length ... + * + * @return ( int ) + */ + int ConsolidationLoopback() + { + return mConsolidationLoopback; + } + + /** + * Set Consolidation Loopback Length ... + * + * @param value: Integer ... + */ + void ConsolidationLoopback(int value) + { + // + if (value < 7) + { + value = 7; + } + + // + mConsolidationLoopback = value; + } + + // + // Actions ... + + /** + * Initialize ... + * + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... + * @param x121Inputs: X121Inputs instance ... + * + * @return ( bool ) + */ + bool Init( + string symbol, + ENUM_TIMEFRAMES period, + X121Inputs &x121Inputs // + ) + { + // + bool result = false; + + // + result = IsValid(symbol) && + IsValid(period); + if (!result) + { + return result; + } + + // + // X121 ... + mX121Helper = new XCX121Helper(); + result = mX121Helper.Init( + symbol, + period, + x121Inputs // + ); + if (!result) + { + return result; + } + + // + mPOIDetector = new XCPOIDetector( + symbol, + period // + ); + mPOIDetector.MaxNumberOfRequiredPOIs(0); + mPOIDetector.Init(); + + // + // Initialize Bar Analyser Class Instance ... + mBarAnalyser = new XCBarAnalyser(); + + // + // Set Chart Style ... + ApplyChartStyle(); + + // + return result; + } + + /** + * Retrieve Symbol ... + * + * @return ( string ) + */ + string GetSymbol() + { + // + string result = NULL; + + // + result = mX121Helper.GetSymbol(); + + // + return result; + } + + /** + * Retrieve TimeFrame (Period) ... + * + * @return ( ENUM_TIMEFRAMES ) + */ + ENUM_TIMEFRAMES GetPeriod() + { + // + ENUM_TIMEFRAMES result = NULL; + + // + result = mX121Helper.GetPeriod(); + + // + return result; + } + + /** + * Get Specified Bar ... + * + * @param source: XOHCL instance, Source Bar ... + * @param bar: XOHCL instance, Dest Bar ... + * + * @return ( bool ) + */ + bool GetBar( + XOHCL &source, + XOHCL &bar // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + result = + IsValid(symbol) && + IsValid(period) && + source.IsValid(); + if (!result) + { + return result; + } + + // + int index = iBarShift( + symbol, + period, + source.time // + ); + result = bar.Init( + symbol, + period, + index // + ); + if (!result) + { + // + bar.Clean(); + return result; + } + + // + return result; + } + + /** + * Retrieve Specified Bar ... + * + * @param bar: XOHCL instance ... + * @param index: Integer ... + * + * @return ( bool ) + */ + bool GetBar( + XOHCL &bar, + int index = 0 // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + if (index < 0) + { + index = 0; + } + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + result = bar.Init( + symbol, + period, + index // + ); + + // + return result; + } + + /** + * Retrieve Specified Bar ... + * + * @param bar: XOHCL instance ... + * @param time: Datetime ... + * + * @return ( bool ) + */ + bool GetBar( + XOHCL &bar, + datetime time = NULL // + ) + { + // + bool result = false; + + // + int index = GetBarIndex(time); + result = GetBar(bar, + index // + ); + + // + return result; + } + + /** + * Retrieve Specified Time Bar Index ... + * + * @param time: DateTime ... + * + * @return ( int ) + */ + int GetBarIndex(datetime time = NULL) + { + // + int result = -1; + + // + time = NormalizeTime(time); + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + result = iBarShift( + symbol, + period, + time // + ); + + // + return result; + } + + /** + * Retrieve Cycle Conditions ... + * + * @param events: ENUM_X_CYCLE_EVENTS member, Array ... + * @param conditions: X121SMCCycleConditions instance ... + * @param barIndex: Integer ... + * @param loopback: Integer ... + * + * @return ( bool ) + */ + bool GetConditions( + ENUM_X_CYCLE_EVENTS &events[], + ENUM_XPOI_EVENTS &poiEvents[], + X121SMCCycleConditions &conditions, + int barIndex = 0, + int loopback = 7 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (loopback < 5) + { + loopback = 5; + } + + // + Clean(events); + Clean(poiEvents); + conditions.Clean(); + + // + result = mX121Helper.GetConditions( + conditions.x121Conditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + mPOIDetector.Update(poiEvents); + mPOIDetector.GetState(conditions.state); + + // + conditions.symbol = conditions.x121Conditions.symbol; + conditions.period = conditions.x121Conditions.period; + conditions.time = TimeCurrent(); + + // + result = conditions.IsValid(); + + // + if (result) + { + // + Calculate( + barIndex, + events, + conditions // + ); + } + + // + return result; + } + + // + // Tools ... + + /** + * Detect Pivot ... + * + * @return ( bool ) + */ + bool DetectPivot( + XPVPivot &pivot, + XOHCL &bar // + ) { + // + bool result = false; + + // + XOHCL cBar; + result = GetBar(bar, cBar); + if (!result) { + return result; + } + + // + int start = cBar.Index(); + double peak = mX121Helper.GetPeak(start); + double vale = mX121Helper.GetVale(start); + bool canContinue = true; + while (canContinue) { + // + + } + + // + return result; + } + + /** + * Get POI State of Specified Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + * + * @return ( bool ) + */ + bool FillPivotState( + XPVPivot &pivot, + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // + ) + { + // + bool result = false; + + // + XPOIState state; + state.Clean(); + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + XPOIState _state; + mPOIDetector.GetState(_state); + result = _state.IsValid() && + _state.HasChild(); + if (!result) + { + return result; + } + + // + DetectPivotPOIs( + pivot, + _state, + state, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + result = state.IsValid() && + state.HasChild(); + if (result) + { + // + pivot.state = state; + + // + CalculatePivotTickZone(pivot); + } + + // + return result; + } + + /** + * Detect XPV Based POI(s) ... + * + * @param barIndex: Start Bar Index ... + * @param minRepetition: minimum Repeate of POI for Validation ... + * @param requiredPivots: Number of Min Requirement POI(s) ... + * @param pivotHelper: XC121SMCCycleHelper instance Pointer ... + * @param orderFlow: XPVPivot instance Array Reference ... + * @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ... + * @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ... + * + * @return ( bool ) + */ + bool DetectOrderFlow( + int barIndex, + XPVPivot &orderFlow[], // OrderFlows ... + ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ... + int minRepetition = 0, + int requiredPivots = 0, + int maxAllowedLoopbackBars = 576 // + ) + { + // + bool result = false; + + // + orderFlowDirection = X_DIRECTION_NONE; + + // + if (maxAllowedLoopbackBars <= 0) + { + maxAllowedLoopbackBars = 1000; + } + + // + if (minRepetition <= 0) + { + minRepetition = mX121Helper.GetDonChainLength(); + } + + // + if (requiredPivots <= 0) + { + requiredPivots = 3; + } + + // + int start = barIndex; + int end = start + maxAllowedLoopbackBars; + + // + Clean(orderFlow); + + // + result = minRepetition > 0 && + requiredPivots > 0; + if (!result) + { + return result; + } + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + double peak = 0; + XPVPivot peaks[]; + int peakRepeate = 0; + int peakToBarIndex = 0; + int peakFromBarIndex = 0; + + // + double vale = 0; + XPVPivot vales[]; + int valeRepeate = 0; + int valeToBarIndex = 0; + int valeFromBarIndex = 0; + + // + bool canLookupPeak = true; + bool canLookupVale = true; + bool canLookup = true; + while (canLookup) + { + // + // Check Peak ... + double iPeak = mX121Helper.GetPeak(barIndex); + if (iPeak != peak) + { + // + if (peak != 0 && + peakRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(peaks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = peaks[i]; + + // + if (iPivot.upper == iPeak) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.lower = 0; + iPivot.upper = peak; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_PEAK; + iPivot.repetition = peakRepeate; + iPivot.to = iTime( + symbol, + period, + peakToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + peakFromBarIndex // + ); + + // + iPivot.lower = iPivot.CalculateLower(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + peaks // + ); + } + } + } + + // + peak = iPeak; + peakRepeate = 0; + peakFromBarIndex = 0; + peakToBarIndex = barIndex; + } + else if (iPeak == peak) + { + // + peakRepeate++; + peakFromBarIndex = barIndex; + } + + // + // Check Vale ... + double iVale = mX121Helper.GetVale(barIndex); + if (iVale != vale) + { + // + if (vale != 0 && + valeRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(vales); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = vales[i]; + + // + if (iPivot.lower == iVale) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.upper = 0; + iPivot.lower = vale; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_VALE; + iPivot.repetition = valeRepeate; + iPivot.to = iTime( + symbol, + period, + valeToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + valeFromBarIndex // + ); + + // + iPivot.upper = iPivot.CalculateUpper(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + vales // + ); + } + } + } + + // + vale = iVale; + valeRepeate = 0; + valeFromBarIndex = 0; + valeToBarIndex = barIndex; + } + else if (iVale == vale) + { + // + valeRepeate++; + valeFromBarIndex = barIndex; + } + + // + canLookupPeak = ArraySize(peaks) < requiredPivots; + canLookupVale = ArraySize(vales) < requiredPivots; + canLookup = barIndex < end && + (canLookupPeak || + canLookupVale); + if (canLookup) + { + barIndex++; + } + } + + // + result = IsValidSize(ArraySize(peaks)) || + IsValidSize(ArraySize(vales)); + if (!result) + { + return result; + } + + // + // Detect Order Flow ... + Copy( + peaks, + orderFlow, + false // + ); + Copy( + vales, + orderFlow, + false // + ); + int count = ArraySize(orderFlow); + result = IsValidSize(orderFlow); + if (!result) + { + return result; + } + + // + // Sort Pivots ... + SortPivots(orderFlow); + + // + // Filter Broken Order Flows ... + FilterBrokenPivots(orderFlow); + + // + // Detect Order Flow Direction ... + result = DetectPivotDirection( + orderFlow, + orderFlowDirection // + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Change Values Actions ... + + /** + * Count Saved Parabolic Sar Changes ... + * + * @return ( int ) + */ + int CountSarChanges() + { + return ArraySize(mSarChanges); + } + + /** + * Fill Saved Sar Changes ... + * + * @param changes: XValueChange instance Array Reference ... + * + * @return ( int ) + */ + int FillSarChanges( + XValueChange &changes[] // + ) + { + // + Clean(changes); + + // + Copy( + mSarChanges, + changes // + ); + + // + int result = ArraySize(changes); + + // + return result; + } + + /** + * Retrieve Last Sar Changes ... + * + * @param change: XValueChange instance ... + * + * @return ( bool ) + */ + bool GetLastSarChange(XValueChange &change) + { + // + bool result = false; + + // + result = GetLastItem( + change, + mSarChanges // + ); + + // + return result; + } + + /** + * Count Saved Peaks Changes ... + * + * @return ( int ) + */ + int CountPeaksChanges() + { + return ArraySize(mPeaksChanges); + } + + /** + * Fill Saved Peaks Changes ... + * + * @param changes: XValueChange instance Array Reference ... + * + * @return ( int ) + */ + int FillPeaksChanges( + XValueChange &changes[] // + ) + { + // + Clean(changes); + + // + Copy( + mPeaksChanges, + changes // + ); + + // + int result = ArraySize(changes); + + // + return result; + } + + /** + * Retrieve Last Peak Changes ... + * + * @param change: XValueChange instance ... + * + * @return ( bool ) + */ + bool GetLastPeakChange(XValueChange &change) + { + // + bool result = false; + + // + result = GetLastItem( + change, + mPeaksChanges // + ); + + // + return result; + } + + /** + * Count Saved Vales Changes ... + * + * @return ( int ) + */ + int CountValesChanges() + { + return ArraySize(mValesChanges); + } + + /** + * Fill Saved Vales Changes ... + * + * @param changes: XValueChange instance Array Reference ... + * + * @return ( int ) + */ + int FillValesChanges( + XValueChange &changes[] // + ) + { + // + Clean(changes); + + // + Copy( + mValesChanges, + changes // + ); + + // + int result = ArraySize(changes); + + // + return result; + } + + /** + * Retrieve Last Vale Changes ... + * + * @param change: XValueChange instance ... + * + * @return ( bool ) + */ + bool GetLastValeChange(XValueChange &change) + { + // + bool result = false; + + // + result = GetLastItem( + change, + mValesChanges // + ); + + // + return result; + } + + /** + * Count Saved VWap Order Changes ... + * + * @return ( int ) + */ + int CountVWapOrderChanges() + { + return ArraySize(mVWapOrderChanges); + } + + /** + * Fill Saved VWap Order Changes ... + * + * @param changes: XValueChange instance Array Reference ... + * + * @return ( int ) + */ + int FillVWapOrderChanges( + XValueChange &changes[] // + ) + { + // + Clean(changes); + + // + Copy( + mVWapOrderChanges, + changes // + ); + + // + int result = ArraySize(changes); + + // + return result; + } + + /** + * Retrieve Last VWap Order Changes ... + * + * @param change: XValueChange instance ... + * + * @return ( bool ) + */ + bool GetLastVWapOrderChange(XValueChange &change) + { + // + bool result = false; + + // + result = GetLastItem( + change, + mVWapOrderChanges // + ); + + // + return result; + } + + /** + * Count Saved VWap State Changes ... + * + * @return ( int ) + */ + int CountVWapStateChanges() + { + return ArraySize(mVWapStateChanges); + } + + /** + * Fill Saved VWap State Changes ... + * + * @param changes: XValueChange instance Array Reference ... + * + * @return ( int ) + */ + int FillVWapStateChanges( + XValueChange &changes[] // + ) + { + // + Clean(changes); + + // + Copy( + mVWapStateChanges, + changes // + ); + + // + int result = ArraySize(changes); + + // + return result; + } + + /** + * Retrieve Last VWap State Changes ... + * + * @param change: XValueChange instance ... + * + * @return ( bool ) + */ + bool GetLastVWapStateChange(XValueChange &change) + { + // + bool result = false; + + // + result = GetLastItem( + change, + mVWapStateChanges // + ); + + // + return result; + } + + /** + * Count Founded Consolidation Zones ... + * + * @return ( int ) + */ + int CountConsolidationZones() + { + return ArraySize(mConsolidationZones); + } + + /** + * Fill Broken Consolidations ... + * + * @param consolidations: XConsolidationZone instance Array Reference ... + * + * @return ( int ) + */ + int FillConsolidationZones( + XConsolidationZone &consolidations[] // + ) + { + // + Clean(consolidations); + + // + Copy( + mConsolidationZones, + consolidations // + ); + + // + int result = ArraySize(consolidations); + + // + return result; + } + + /** + * Retrieve Last Consolidation Breaks ... + * + * @param change: XValueChange instance ... + * + * @return ( bool ) + */ + bool GetLastConsolidationZone(XConsolidationZone &zone) + { + // + bool result = false; + + // + result = GetLastItem( + zone, + mConsolidationZones // + ); + + // + return result; + } + + /** + * Count Pivot Points Change ... + * + * @return ( int ) + */ + int CountPivotPoints() + { + return ArraySize(mPivotPoints); + } + + /** + * Retrieve All Pivot Point Changes as a Collection ... + * + * @param pivots: XPVPivotPoint instance Reference ... + * + * @return ( int ) + */ + int FillPivotPointss(XPVPivotPoint &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + int count = CountPivotPoints(); + if (!IsValidSize(pivots)) + { + return result; + } + + // + Copy( + mPivotPoints, + pivots // + ); + + // + result = ArraySize(pivots); + + // + return result; + } + + /** + * Retrieve All Peak Pivot Point Changes as a Collection ... + * + * @param pivots: XPVPivotPoint instance Reference ... + * + * @return ( int ) + */ + int FillPeakPivotPoints(XPVPivotPoint &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + int count = CountPivotPoints(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPVPivotPoint iPivot = mPivotPoints[i]; + + // + bool isValid = iPivot.IsPeak(); + if (isValid) + { + // + AddRef( + iPivot, + pivots // + ); + } + } + + // + result = ArraySize(pivots); + + // + return result; + } + + /** + * Retrieve All Vale Pivot Point Changes as a Collection ... + * + * @param pivots: XPVPivotPoint instance Reference ... + * + * @return ( int ) + */ + int FillValePivotPoints(XPVPivotPoint &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + int count = CountPivotPoints(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPVPivotPoint iPivot = mPivotPoints[i]; + + // + bool isValid = iPivot.IsVale(); + if (isValid) + { + // + AddRef( + iPivot, + pivots // + ); + } + } + + // + result = ArraySize(pivots); + + // + return result; + } + + /** + * Get Current Active Pivot ... + * + * @param pivot: XPVPivot instance reference ... + */ + void GetActivePivot(XPVPivot &pivot) + { + // + mActivePivot.to = TimeCurrent(); + pivot = mActivePivot; + } + + /** + * Count Calculated Pivots ... + * + * @return ( int ) + */ + int CountPivots() + { + return ArraySize(mPivots); + } + + /** + * Fill Pivots ... + * + * @param pivots: XPVPivot instance Reference Array ... + * + * @return ( int ) + */ + int FillPivots(XPVPivot &pivots[]) + { + // + int result = 0; + + // + Clean(pivots); + + // + Copy( + mPivots, + pivots // + ); + + // + result = ArraySize(pivots); + + // + return result; + } + + // + // Virtuals ... + + /** + * Set Default Properties Values ... + */ + virtual void Default() + { + // + ConsolidationLoopback(10); + MaxAllowedSavedChanges(50); + } + + // + protected: + // + + /** + * Calculate Requirements ... + * + * @param barIndex: Integer, Bar Index ... + * @param events: ENUM_X_CYCLE_EVENTS member, Array ... + * @param conditions: X121SMCCycleConditions instance ... + */ + void Calculate( + int barIndex, + ENUM_X_CYCLE_EVENTS &events[], + X121SMCCycleConditions &conditions // + ) + { + // + Clean(events); + + // + string symbol = GetSymbol(); + datetime cTime = TimeCurrent(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL changeBar; + int index = + barIndex <= 0 + ? 1 + : barIndex; + bool isInited = GetBar( + changeBar, + index // + ); + if (!isInited) + { + return; + } + + // + // Detect Sar Change ... + bool isSarSwitchedToBullish = conditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = conditions.x121Conditions.isSarSwitchedToBearish; + bool isSarChanged = isSarSwitchedToBullish || + isSarSwitchedToBearish; + + // + if (isSarChanged) + { + // + XValueChange sarChanged; + + // + datetime time = changeBar.time; + double after = conditions.x121Conditions.sarBuffer[1]; + double before = conditions.x121Conditions.sarBuffer[2]; + ENUM_X_DIRECTION dir = + isSarSwitchedToBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Initialize Model ... + isInited = sarChanged.Init( + before, + after, + dir, + time // + ); + if (isInited) + { + // + isInited = AddSarChange(sarChanged); + + // + Add( + SAR_CHANGE_DETECTED, + events // + ); + } + } + + // + // Detect Peaks Changes ... + + // + bool isNewPeak = conditions.x121Conditions.isNewPeak; + double peak = conditions.x121Conditions.peaksBuffer[0]; + bool isNewPeakOverLast = conditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = conditions.x121Conditions.isNewPeakUnderLast; + + // + if (isNewPeak) + { + // + XValueChange peaksChanged; + + // + datetime time = changeBar.time; + double after = conditions.x121Conditions.peaksBuffer[1]; + double before = conditions.x121Conditions.peaksBuffer[2]; + ENUM_X_DIRECTION dir = + isNewPeakOverLast + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Initialize Model ... + isInited = peaksChanged.Init( + before, + after, + dir, + time // + ); + if (isInited) + { + // + isInited = AddPeaksChange(peaksChanged); + + // + Add( + NEW_PEAK_DETECTED, + events // + ); + } + } + + // + // Detect Vales Changes ... + + // + bool isNewVale = conditions.x121Conditions.isNewVale; + double vale = conditions.x121Conditions.valesBuffer[0]; + bool isNewValeOverLast = conditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = conditions.x121Conditions.isNewValeUnderLast; + + // + if (isNewVale) + { + // + XValueChange valesChanged; + + // + datetime time = changeBar.time; + double after = conditions.x121Conditions.valesBuffer[1]; + double before = conditions.x121Conditions.valesBuffer[2]; + ENUM_X_DIRECTION dir = + isNewValeUnderLast + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Initialize Model ... + isInited = valesChanged.Init( + before, + after, + dir, + time // + ); + if (isInited) + { + // + isInited = AddValesChange(valesChanged); + + // + Add( + NEW_VALE_DETECTED, + events // + ); + } + } + + // + // VWap Direction Change ... + + // + // Ordered Change ... + bool isVWapSwitchedToBullishOrdered = + conditions.x121Conditions.isVWapSwitchedToBullishOrdered; + bool isVWapSwitchedToBearishOrdered = + conditions.x121Conditions.isVWapSwitchedToBearishOrdered; + bool isVWAPOrderedChanged = isVWapSwitchedToBullishOrdered || + isVWapSwitchedToBearishOrdered; + // + if (isVWAPOrderedChanged) + { + // + XValueChange vwapOrderChanged; + + // + datetime time = changeBar.time; + ENUM_X_DIRECTION dir = + isVWapSwitchedToBullishOrdered + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + double after = 0; + double before = 0; + if (isVWapSwitchedToBullishOrdered) + { + // + // After Max ... + after = MathMax( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + after = MathMax( + after, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + + // + // Before Min ... + before = MathMin( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + before = MathMin( + before, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + } + else + { + // + // After Min ... + after = MathMin( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + after = MathMin( + after, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + + // + // Before Max ... + before = MathMax( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + before = MathMax( + before, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + } + + // + // Initialize Model ... + isInited = vwapOrderChanged.Init( + before, + after, + dir, + time // + ); + if (isInited) + { + // + isInited = AddVWapOrderChange(vwapOrderChanged); + + // + Add( + VWAP_ORDER_CHANGE_ETECTED, + events // + ); + } + } + + // + // States Changed ... + bool isVWapSwitchedToBullishState = + conditions.x121Conditions.isVWapSwitchedToBullishState; + bool isVWapSwitchedToBearishState = + conditions.x121Conditions.isVWapSwitchedToBearishState; + bool isVWapStatesChanged = isVWapSwitchedToBullishState || + isVWapSwitchedToBearishState; + + // + if (isVWapStatesChanged) + { + // + XValueChange vwapStateChanged; + + // + datetime time = changeBar.time; + ENUM_X_DIRECTION dir = + isVWapSwitchedToBullishState + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + double after = 0; + double before = 0; + if (isVWapSwitchedToBullishState) + { + // + // After Max ... + after = MathMax( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + after = MathMax( + after, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + + // + // Before Min ... + before = MathMin( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + before = MathMin( + before, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + } + else + { + // + // After Min ... + after = MathMin( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + after = MathMin( + after, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + + // + // Before Max ... + before = MathMax( + conditions.x121Conditions.vwapFastBuffer[1], + conditions.x121Conditions.vwapMidBuffer[1] // + ); + before = MathMax( + before, + conditions.x121Conditions.vwapSlowBuffer[1] // + ); + } + + // + // Initialize Model ... + isInited = vwapStateChanged.Init( + before, + after, + dir, + time // + ); + if (isInited) + { + // + isInited = AddVWapStateChange(vwapStateChanged); + + // + Add( + VWAP_STATE_CHANGE_DETCTED, + events // + ); + } + } + + // + // Detect Consolidations ... + + // + int consolidationLoopback = ConsolidationLoopback(); + if (IsValidSize(consolidationLoopback)) + { + // + double upper = 0; + double lower = 0; + bool hasConsolidation = + mBarAnalyser.IsConsolidate( + changeBar, + upper, + lower, + consolidationLoopback // + ); + + // + if (hasConsolidation && + !mActioveConsolidationZone.IsValid()) + { + // + // Initialize Consolidation Zone ... + bool isInited = mActioveConsolidationZone.Init( + changeBar.symbol, + changeBar.period, + upper, + lower, + consolidationLoopback // + ); + } + + // + if (!hasConsolidation && + mActioveConsolidationZone.IsValid()) + { + // + mActioveConsolidationZone.Update(); + bool isBreaked = mActioveConsolidationZone.IsBreaked(); + + // + if (isBreaked) + { + // + // Add Active to List ... + AddRef( + mActioveConsolidationZone, + mConsolidationZones // + ); + + // + // Clean Active Zone ... + mActioveConsolidationZone.Clean(); + + // + Add( + CONSOLIDATION_BREAKED_DETECTED, + events // + ); + } + } + } + + // + // Check Valid Peaks and Vales ... + if (isNewPeak || isNewVale) + { + // + int count = 0; + double value = 0; + int repetition = 0; + ENUM_TIMEFRAMES period = GetPeriod(); + int periodSeconds = PeriodSeconds(period); + int minRepetition = mX121Helper.GetDonChainLength(); + ENUM_XPV_PIVOTS type = isNewPeak + ? XPV_PEAK + : XPV_VALE; + + // + XValueChange lastChange; + XValueChange prevChange; + + // + count = CountPeaksChanges(); + if (isNewPeak && count >= 2) + { + // + lastChange = mPeaksChanges[count - 1]; + prevChange = mPeaksChanges[count - 2]; + } + + // + count = CountValesChanges(); + if (isNewVale && count >= 2) + { + // + lastChange = mValesChanges[count - 1]; + prevChange = mValesChanges[count - 2]; + } + + // + if (lastChange.IsValid() && + prevChange.IsValid()) + { + // + value = prevChange.after; + int delayTime = ((int)lastChange.time - (int)prevChange.time); + repetition = delayTime / periodSeconds; + + // + bool isValidPivot = repetition >= minRepetition; + if (isValidPivot) + { + // + XPVPivotPoint pivotPoint; + pivotPoint.type = type; + pivotPoint.value = value; + pivotPoint.time = prevChange.time; + pivotPoint.repetition = repetition; + + // + AddRef( + pivotPoint, + mPivotPoints // + ); + + // + Add( + PIVOT_POINT_DETECTED, + events // + ); + } + } + } + + // // + // // Calculate Pivots ... + // if (isNewPeak || isNewVale) + // { + // // + // if (!mActivePivot.IsValid()) + // { + // // + // mActivePivot.symbol = symbol; + // mActivePivot.period = period; + + // // + // mActivePivot.upper = peak; + // mActivePivot.lower = vale; + + // // + // mActivePivot.from = cTime; + // mActivePivot.to = cTime; + + // // + // mActivePivot.type = + // isNewPeak + // ? XPV_VALE + // : XPV_PEAK; + // mActivePivot.repetition++; + + // // + // Add( + // PIVOT_STARTED, + // events // + // ); + // } + // else + // { + // // + // mActivePivot.to = cTime; + + // // + // mActivePivot.repetition++; + + // // + // if (mActivePivot.to > mActivePivot.from) + // { + // FillPivotState(mActivePivot); + // } + + // // + // // Check Ticks Zone is Valid ... + // bool isTicksZoneValid = + // // + // mActivePivot.state.IsValid() && + // mActivePivot.state.ticksZone != NULL && + // mActivePivot.state.ticksZone.IsValid() + // // + // ; + // if (isTicksZoneValid) { + // // + // Print("Has Valid Ticks Zone ..."); + // } + // } + // } + } + + // + private: + // + // Props ... + + // + // Change Holders ... + int mMaxAllowedSavedChanges; // Max llowed Changes to Save ... + XValueChange mSarChanges[]; // Holds Parabolic Sar Direction Changes ... + XValueChange mPeaksChanges[]; // Holds Peaks Changes ... + XValueChange mValesChanges[]; // Holds Vales Changes ... + XValueChange mVWapOrderChanges[]; // Holds Vales Changes ... + XValueChange mVWapStateChanges[]; // Holds Vales Changes ... + + // + int mConsolidationLoopback; // Consolidation Loopback Length ... + XConsolidationZone mConsolidationZones[]; // Holds Consolidation Zones ... + XConsolidationZone mActioveConsolidationZone; // Holds Actiove Consolidation Zone ... + + // + XPVPivotPoint mPivotPoints[]; // Holds Pivots ... + + // + XCXPVPivotObject mActivePivotObject; + XPVPivot mActivePivot; + XPVPivot mPivots[]; + + // + // Actions ... + + /** + * Release All Resources ... + */ + void DeInit() + { + // + delete mX121Helper; + + // + delete mBarAnalyser; + } + + /** + * Apply Chart Style ... + */ + void ApplyChartStyle() + { + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + + // + ENUM_CHART_MODE mMode = CHART_CANDLES; // chart's mMode + bool mShowBidLine = true; // show bid line + bool mShowAskLine = true; // show ask line + bool mShowGrid = false; // show grids on chart + bool mShowVolumes = false; // show volumes + bool mShowTradeLevels = true; // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true; // chart autoscroll + bool mQuickNavigation = true; // chart quick navigation state + color mForeGroundColor = clrWhite; // chart's foreground color + color mBackGroundColor = clrBlack; // chart's background color + color mUpColor = clrGreen; // Up Color + color mDownColor = clrRed; // Down Color + color mBullishColor = clrGreen; // Bullish color + color mBearishColor = clrRed; // Bearish color + color mGridColor = clrGray; // grid color + color mBidLineColor = clrGray; // bid line color + color mAskLineColor = clrRed; // ask line color + color mLineColor = clrLime; // line mMode and doji candlestick color + color mStopColor = clrGold; // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen; // volumes color + + // + ChartSetInteger(chartId, CHART_MODE, mMode); + ChartSetInteger(chartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(chartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(chartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(chartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(chartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(chartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(chartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(chartId, CHART_COLOR_VOLUME, mVolumesColor); + } + + /** + * Fill Pivot Tick Zone ... + * + * @param pivot: XPVPivot instance Reference ... + */ + void CalculatePivotTickZone( + XPVPivot &pivot // + ) + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + bool isInited = false; + + // + datetime from = pivot.from; + XOHCL iFromBar; + int iFromBarIndex = iBarShift( + symbol, + period, + from // + ); + isInited = iFromBar.Init( + symbol, + period, + iFromBarIndex // + ); + if (!isInited) + { + return; + } + + // + datetime to = pivot.to; + XOHCL iToBar; + int iToBarIndex = iBarShift( + symbol, + period, + to // + ); + isInited = iToBar.Init( + symbol, + period, + iToBarIndex // + ); + if (!isInited) + { + return; + } + + // + if (iFromBarIndex <= iToBarIndex) + { + return; + } + + // + XCTicksZone *iZone; + iZone = new XCTicksZone(); + + // + int ticksLevels = mPOIDetector.TicksRangeZoneLevel(); + int ticksRange = mPOIDetector.TicksRangeZoneRange(); + isInited = ticksLevels > 0 && + ticksRange > 0; + if (!isInited) + { + return; + } + + // + isInited = iZone.Init( + iFromBar, + iToBar // + ); + if (!isInited) + { + return; + } + + // + pivot.state.ticksZone = iZone; + } + + // + // Change Values Actions ... + + /** + * Add Specified Parabolic Sar Changed Item ... + * + * @param value: XValueChange instance Reference ... + * + * @return ( bool ) + */ + bool AddSarChange(XValueChange &value) + { + // + bool result = false; + + // + result = value.IsValid(); + if (!result) + { + return result; + } + + // + int beforeCount = CountSarChanges(); + + // + AddIfNotExists( + value, + mSarChanges // + ); + + // + int afterCount = CountSarChanges(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mSarChanges, + maxAllowed // + ); + } + + // + return result; + } + + /** + * Add Specified Peaks Changed Item ... + * + * @param value: XValueChange instance Reference ... + * + * @return ( bool ) + */ + bool AddPeaksChange(XValueChange &value) + { + // + bool result = false; + + // + result = value.IsValid(); + if (!result) + { + return result; + } + + // + int beforeCount = CountSarChanges(); + + // + AddIfNotExists( + value, + mPeaksChanges // + ); + + // + int afterCount = CountSarChanges(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mPeaksChanges, + maxAllowed // + ); + } + + // + return result; + } + + /** + * Add Specified Vales Changed Item ... + * + * @param value: XValueChange instance Reference ... + * + * @return ( bool ) + */ + bool AddValesChange(XValueChange &value) + { + // + bool result = false; + + // + result = value.IsValid(); + if (!result) + { + return result; + } + + // + int beforeCount = CountSarChanges(); + + // + AddIfNotExists( + value, + mValesChanges // + ); + + // + int afterCount = CountSarChanges(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mValesChanges, + maxAllowed // + ); + } + + // + return result; + } + + /** + * Add Specified VWap Order Changed Item ... + * + * @param value: XValueChange instance Reference ... + * + * @return ( bool ) + */ + bool AddVWapOrderChange(XValueChange &value) + { + // + bool result = false; + + // + result = value.IsValid(); + if (!result) + { + return result; + } + + // + int beforeCount = CountSarChanges(); + + // + AddIfNotExists( + value, + mVWapOrderChanges // + ); + + // + int afterCount = CountSarChanges(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mVWapOrderChanges, + maxAllowed // + ); + } + + // + return result; + } + + /** + * Add Specified VWap State Changed Item ... + * + * @param value: XValueChange instance Reference ... + * + * @return ( bool ) + */ + bool AddVWapStateChange(XValueChange &value) + { + // + bool result = false; + + // + result = value.IsValid(); + if (!result) + { + return result; + } + + // + int beforeCount = CountSarChanges(); + + // + AddIfNotExists( + value, + mVWapStateChanges // + ); + + // + int afterCount = CountSarChanges(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mVWapStateChanges, + maxAllowed // + ); + } + + // + return result; + } + + // +}; diff --git a/Documents/BKP/1/x-121.smc.test.signal.class.mq5 b/Documents/BKP/1/x-121.smc.test.signal.class.mq5 new file mode 100644 index 00000000..39be1260 --- /dev/null +++ b/Documents/BKP/1/x-121.smc.test.signal.class.mq5 @@ -0,0 +1,831 @@ +/////////////////////////////////////////////////////// +// +// 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 X121SMCStrategyTestSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + XPVPivot pivot; + + // + // Trigger Props ... + + // + // Constructor ... + X121SMCStrategyTestSignalConditions() + { + 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; + + // + pivot.Clean(); + } + + /** + * 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; + } + + /** + * 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 ... + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCTestSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyTestSignalConditions &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; + + // + // Detect new Peak or new Vale ... + + // + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; + + // + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + bool isNewValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + result = isNewPeak || + isNewVale; + if (!result) + { + return result; + } + + // + // Detect Pivot ... + bool hasPivot = conditions.pivot.IsValid(); + if (!hasPivot) + { + // + XPVPivot pivot; + hasPivot = triggerCycleHelper.DetectPivot( + pivot, + cBar // + ); + result = hasPivot; + if (!result) + { + return result; + } + + // + conditions.pivot = pivot; + } + + // + // Check Order Block ... + // TODO: Later ... + // bool hasOrderBlock = conditions.HasOrderBlock(); + // if (hasOrderBlock) + // { + // // + // DetectX121SMCTestSiganlOrderBlock( + // zBar, + // consolidationState, + // conditions // + // ); + // } + + // + bool isMarketBullish = + // + // VWap State ... + decisionConditions.x121Conditions.isVWapBullishState && + analyseConditions.x121Conditions.isVWapBullishState && + verificationConditions.x121Conditions.isVWapBullishState + // + && + // + // VWap Order ... + decisionConditions.x121Conditions.isVWapBullishOrdered && + analyseConditions.x121Conditions.isVWapBullishOrdered && + verificationConditions.x121Conditions.isVWapBullishOrdered + // + && + // + // Sar ... + decisionConditions.x121Conditions.isSarBullish && + analyseConditions.x121Conditions.isSarBullish && + verificationConditions.x121Conditions.isSarBullish + // + ; + + // + bool isMarketBearish = + // + // VWap State ... + decisionConditions.x121Conditions.isVWapBearishState && + analyseConditions.x121Conditions.isVWapBearishState && + verificationConditions.x121Conditions.isVWapBearishState + // + && + // + // VWap Order ... + decisionConditions.x121Conditions.isVWapBearishOrdered && + analyseConditions.x121Conditions.isVWapBearishOrdered && + verificationConditions.x121Conditions.isVWapBearishOrdered + // + && + // + // Sar ... + decisionConditions.x121Conditions.isSarBearish && + analyseConditions.x121Conditions.isSarBearish && + verificationConditions.x121Conditions.isSarBearish + // + ; + + // + // Step 1 + // Detect Market Direction ... + isBullish = isMarketBullish; + isBearish = isMarketBearish; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Step 2 + // VWap Switches or Sar Switches ... + + // + bool isSarBullish = triggerConditions.x121Conditions.isSarBullish; + bool isSarBearish = triggerConditions.x121Conditions.isSarBearish; + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + bool isVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState; + bool isVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState; + + // + bool isVWapSwitchedToBullishState = triggerConditions.x121Conditions.isVWapSwitchedToBullishState; + bool isVWapSwitchedToBearishState = triggerConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isVWapBullishOrdered = triggerConditions.x121Conditions.isVWapBullishOrdered; + bool isVWapBearishOrdered = triggerConditions.x121Conditions.isVWapBearishOrdered; + + // + bool isVWapSwitchedToBullishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + bool isVWapSwitchedToBearishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + // + // + + // + bool isSarStartedBullishStructure = + // + isSarSwitchedToBullish && + isVWapBullishState && + isVWapBullishOrdered + // + ; + + // + bool isSarStartedBearishStructure = + // + isSarSwitchedToBearish && + isVWapBearishState && + isVWapBearishOrdered + // + ; + + // + // + // + + // + bool isVWapStateStartedBullishStructure = + // + isVWapSwitchedToBullishState && + isSarBullish && + isVWapBullishOrdered + // + ; + + // + bool isVWapStateStartedBearishStructure = + // + isVWapSwitchedToBearishState && + isSarBearish && + isVWapBearishOrdered + // + ; + + // + // + // + + // + bool isVWapOrderStartedBullishStructure = + // + isVWapSwitchedToBullishOrdered && + isSarBullish && + isVWapBullishState + // + ; + + // + bool isVWapOrderStartedBearishStructure = + // + isVWapSwitchedToBearishOrdered && + isSarBearish && + isVWapBearishState + // + ; + + // + // + // + + // + isBullish = + // + isBullish + // + && + // + ( + // + isSarStartedBullishStructure || + isVWapStateStartedBullishStructure || + isVWapOrderStartedBullishStructure + // + ) + // + ; + + // + isBearish = + // + isBearish + // + && + // + ( + // + isSarStartedBearishStructure || + isVWapStateStartedBearishStructure || + isVWapOrderStartedBearishStructure + // + ) + // + ; + + // + 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 DetectX121SMCTestSiganlTrigger( + // + X121SMCStrategyTestSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + 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; + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_SMPV; + string providerStr = ToString(provider); + + // + 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; + + // + result = false; + + // + return result; +} + +// +// Tools Functions ... + +// \ No newline at end of file diff --git a/Documents/BKP/1/x-121.smc.test.strategy.class.mq5 b/Documents/BKP/1/x-121.smc.test.strategy.class.mq5 new file mode 100644 index 00000000..d2cf0223 --- /dev/null +++ b/Documents/BKP/1/x-121.smc.test.strategy.class.mq5 @@ -0,0 +1,2088 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XCX121SMCTestStrategy +// Description: provides all based classes for use ... +// +// +// 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.base.strategy.class.mq5" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" +#include "../Signals/x-121.smc.test.signal.class.mq5" + +// +// Definitions ... + +// +// XStrategy Class Implementation(s) ... +class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy +{ + // + // Public ... + public: + // + + // + // Constructor(s) ... + void XCX121SMCTestStrategy( + // + // Base ... + string _symbol, // Trading Symbol + ENUM_TIMEFRAMES _period // Trading TimeFrame + ) + : XCX121SMCBaseStrategy(_symbol, _period) + { + InitialHelpers(); + } + + // + // Deconstructur ... + void ~XCX121SMCTestStrategy() + { + } + + // + // Overrides Actions ... + + /** + * Destroy All Class Implementations ... + */ + void Destroy() override + { + // + delete mTriggerCycleHelper; + delete mDecisionCycleHelper; + delete mAnalyseCycleHelper; + delete mVerificationCycleHelper; + delete mConsolidationCycleHelper; + delete mVisionCycleHelper; + } + + /** + * Check Conditions For Signal ... + */ + bool HasSignal( + XSignal &signal, + X121SMCStrategyConditions &conditions // + ) override + { + // + bool result = false; + + // + signal.Clean(); + conditions.Clean(); + + // + int pushers = 0; + + // + double sl = 0; + double tp = 0; + double risk = 0; + double entry = 0; + double reward = 0; + double r2r = R2R(); + string provider = ""; + double volume = Volume(); + ENUM_POSITION_TYPE type = POSITION_TYPE_BUY; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + + // + bool hasLong = false; + bool hasShort = false; + + // + double selectedSL = 0; + + // + // Start Calculations ... + + // + // Retrieve Common Data ... + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + // Required Value For SL/TP Calculations ... + double points = GetPoints(symbol); + double pip = GetPipPrice(symbol); + double pip2 = 2 * pip; + + // + // Retrieve and Fill Cycle Conditions ... + result = GetCyclesConditions(conditions); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + // Check Spread for Signalling Conditions ... + bool isSpreadPassed = IsSpreadPass(); + result = isSpreadPassed; + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + // Detect Signal Conditions ... + bool hasSignal = false; + + // + bool hasSMPVSignal = false; + bool hasRJBPVSignal = false; + bool hasVWAPCSignal = false; + bool hasTestSignal = false; + + // + // X_121_SMC_PROVIDER_SMPV ... + if (!hasSignal) + { + // + // hasSMPVSignal = DetectSamePeaksAndValesSignal(conditions); + // hasSignal = hasSMPVSignal; + } + + // + // X_121_SMC_PROVIDER_RJBPV ... + if (!hasSignal) + { + // // + // hasRJBPVSignal = DetectRJBPVSignal(conditions); + // hasSignal = hasRJBPVSignal; + } + + // + // X_121_SMC_PROVIDER_VWAPC ... + if (!hasSignal) + { + // // + // hasVWAPCSignal = DetectVWAPCSignal(conditions); + // hasSignal = hasVWAPCSignal; + } + + // + if (!hasSignal) + { + // + hasTestSignal = DetectTestSignal(conditions); + hasSignal = hasTestSignal; + } + + // + result = hasSignal; + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + // Combine all Signals Conditions ... + selectedSL = conditions.sl; + provider = conditions.provider; + + // + hasLong = + // + IsBullish(conditions.signalDir) + // + ; + + // + hasShort = + // + IsBearish(conditions.signalDir) + // + ; + + // + result = hasLong || + hasShort; + + // + // Rmove Signal Condition ... + if (result) + { + // + // TYPE ... + type = + hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_POSITION_TYPES xType = + hasLong + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + entry = GetEntry( + conditions.symbol, + type // + ); + + // + double slAddition = 0; + sl = + hasLong + ? selectedSL - slAddition + : selectedSL + slAddition; + + // + // RISK Reward ... + risk = + hasLong + ? entry - sl + : sl - entry; + reward = risk * r2r; + tp = + hasLong + ? entry + reward + : entry - reward; + + // + signal.sl = sl; + signal.tp = tp; + signal.type = type; + signal.mode = mode; + signal.entry = entry; + signal.volume = volume; + signal.symbol = symbol; + signal.period = period; + signal.pushers = pushers; + signal.provider = provider; + signal.time = TimeCurrent(); + + // + result = PrepareSignal(signal); + if (result) + { + DrawSignal(signal); + } + + // + hasLong = false; + hasShort = false; + } + + // + return result; + } + + /** + * Customize Strategy Identifier ... + */ + string GetTag() override + { + return X121SMCStrategyToken; + } + + // + // Protected ... + protected: + // + + // + // Props ... + + // + // Trigger Order Flow ... + XPVPivot mOrderFlow[]; + ENUM_X_DIRECTION mOrderFlowDir; + + // + ENUM_XPOI_EVENTS mTriggerPOIEvents[]; + ENUM_X_CYCLE_EVENTS mTriggerCycleEvents[]; + XC121SMCCycleHelper *mTriggerCycleHelper; + + // + ENUM_XPOI_EVENTS mDecisionPOIEvents[]; + ENUM_X_CYCLE_EVENTS mDecisionCycleEvents[]; + XC121SMCCycleHelper *mDecisionCycleHelper; + + // + ENUM_XPOI_EVENTS mAnalysePOIEvents[]; + ENUM_X_CYCLE_EVENTS mAnalyseCycleEvents[]; + XC121SMCCycleHelper *mAnalyseCycleHelper; + + // + ENUM_XPOI_EVENTS mVerificationPOIEvents[]; + ENUM_X_CYCLE_EVENTS mVerificationCycleEvents[]; + XC121SMCCycleHelper *mVerificationCycleHelper; + + // + ENUM_XPOI_EVENTS mConsolidationPOIEvents[]; + ENUM_X_CYCLE_EVENTS mConsolidationCycleEvents[]; + XC121SMCCycleHelper *mConsolidationCycleHelper; + + // + ENUM_XPOI_EVENTS mVisionPOIEvents[]; + ENUM_X_CYCLE_EVENTS mVisionCycleEvents[]; + XC121SMCCycleHelper *mVisionCycleHelper; + + // + // Actions ... + + /** + * Retrieve Cycles Conditions ... + * + * @param conditions: X121SMCStrategyConditions instance Reference ... + * + * @return ( bool ) + */ + bool GetCyclesConditions( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + datetime cTime = TimeCurrent(); + + // + conditions.time = cTime; + conditions.symbol = symbol; + conditions.period = period; + + // + int conditionsLoopback = 7; + + // + // Fill Cycles Conditions ... + + // + // Trigger ... + result = mTriggerCycleHelper.GetConditions( + mTriggerCycleEvents, + mTriggerPOIEvents, + conditions.triggerConditions, + zIndex, + conditionsLoopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + conditions.triggerConditions.state = mTriggerState; + + // + // Decision ... + result = mDecisionCycleHelper.GetConditions( + mDecisionCycleEvents, + mDecisionPOIEvents, + conditions.decisionConditions, + zIndex, + conditionsLoopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + conditions.decisionConditions.state = mDecisionState; + + // + // Analyse ... + result = mAnalyseCycleHelper.GetConditions( + mAnalyseCycleEvents, + mAnalysePOIEvents, + conditions.analyseConditions, + zIndex, + conditionsLoopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + conditions.analyseConditions.state = mAnalyseState; + + // + // Verification ... + result = mVerificationCycleHelper.GetConditions( + mVerificationCycleEvents, + mVerificationPOIEvents, + conditions.verificationConditions, + zIndex, + conditionsLoopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + conditions.verificationConditions.state = mVerificationState; + + // + // Consolidation ... + result = mConsolidationCycleHelper.GetConditions( + mConsolidationCycleEvents, + mConsolidationPOIEvents, + conditions.consolidationConditions, + zIndex, + conditionsLoopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + conditions.consolidationConditions.state = mConsolidationState; + + // + // Vision ... + result = mVisionCycleHelper.GetConditions( + mVisionCycleEvents, + mVisionPOIEvents, + conditions.visionConditions, + zIndex, + conditionsLoopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + conditions.visionConditions.state = mVisionState; + + // // + // XPVPivot triggerPivot; + // mTriggerCycleHelper.GetActivePivot(triggerPivot); + // result = triggerPivot.IsValid(); + // if (!result) + // { + // return result; + // } + + // // + // ClearDraws(); + // DrawPivot( + // triggerPivot, + // true, // Draw State ... + // true // Filter By Price ... + // ); + + // + return result; + } + + // + // Signalling Functions ... + + // + // TODO: Remove this ... + X121SMCStrategyTestSignalConditions mTestConditions; + bool DetectTestSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_SMPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mTestConditions.setupTime; + bool isSetuped = mTestConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mTestConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCTestSiganlSetup( + symbol, + period, + mTestConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = isSetuped; + if (!result) + { + return result; + } + + // + setupDir = mTestConditions.dir; + setupTime = mTestConditions.setupTime; + } + + // // + // ClearDraws(); + // CustomStateDrawing( + // mTriggerState, + // true // Filter By Price ... + // ); + + // + // Detect Trigger Conditions ... + // bool canTrigger = mTestConditions.CanTrigger(); + // datetime triggerTime = mTestConditions.triggerTime; + // result = canTrigger; + // if (!canTrigger) + // { + // // + // // Detect Signal Trigger ... + // canTrigger = DetectX121SMCTestSiganlTrigger( + // mTestConditions, + // symbol, + // period, + // mTriggerCycleHelper, + // mDecisionCycleHelper, + // mAnalyseCycleHelper, + // mVerificationCycleHelper, + // mConsolidationCycleHelper, + // mVisionCycleHelper // + // ); + + // // + // result = canTrigger; + // if (!result) + // { + // return result; + // } + + // // + // triggerTime = mTestConditions.triggerTime; + // } + + // + // Check Signal Direction ... + + // // + // isBullish = IsBullish(setupDir); + // isBearish = IsBearish(setupDir); + + // + // result = isBullish || + // isBearish; + // if (!result) + // { + // return result; + // } + + // // + // if (cTime - setupTime > 2400) + // { + // // + // ClearDraws(); + + // // + // mTestConditions.Clean(); + // } + + // // + // // Issues Signal on Conditions ... + // conditions.signalDir = setupDir; + // conditions.provider = providerStr; + // conditions.sl = mTestConditions.sl; + + // + mTestConditions.Clean(); + + // + return result; + } + + // + // Private ... + private: + // + // Props ... + + /** + * Initial Required Indicators Helper ... + */ + void InitialHelpers() + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + // Short ... + ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + + // + // Medium ... + ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + + // + // Long ... + ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + + // + // Hind ... + ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + + // + // XPV ... + X121Inputs x121Inputs; + + // + x121Inputs.Default(); + + // + x121Inputs.scMethod = scMethod; + x121Inputs.scPeriod = scPeriod; + x121Inputs.mcMethod = mcMethod; + x121Inputs.mcPeriod = mcPeriod; + x121Inputs.lcMethod = lcMethod; + x121Inputs.lcPeriod = lcPeriod; + x121Inputs.hcMethod = hcMethod; + x121Inputs.hcPeriod = hcPeriod; + + // + x121Inputs.showFibo2Levels = false; + x121Inputs.showFibo3Levels = true; + x121Inputs.showFibo4Levels = false; + + // + // Initialize Cycle Helpers ... + + // + mTriggerCycleHelper = new XC121SMCCycleHelper(); + mTriggerCycleHelper.Init( + symbol, + PERIOD_M1, + x121Inputs // + ); + + // + mDecisionCycleHelper = new XC121SMCCycleHelper(); + mDecisionCycleHelper.Init( + symbol, + PERIOD_M5, + x121Inputs // + ); + + // + mAnalyseCycleHelper = new XC121SMCCycleHelper(); + mAnalyseCycleHelper.Init( + symbol, + PERIOD_M15, + x121Inputs // + ); + + // + mVerificationCycleHelper = new XC121SMCCycleHelper(); + mVerificationCycleHelper.Init( + symbol, + PERIOD_M30, + x121Inputs // + ); + + // + mConsolidationCycleHelper = new XC121SMCCycleHelper(); + mConsolidationCycleHelper.Init( + symbol, + PERIOD_H1, + x121Inputs // + ); + + // + mVisionCycleHelper = new XC121SMCCycleHelper(); + mVisionCycleHelper.Init( + symbol, + PERIOD_H4, + x121Inputs // + ); + } + + // + // SL Selector Methods ... + + /** + * Select Specified Type of Stop Loss ... + * + * @param conditions: X121SMCStrategyConditions instance Reference ... + * @param forDir: ENUM_X_DIRECTION member, Signal Direction ... + * @param type: ENUM_X_121_SMC_SL_TYPES member, Specified Required SL Type ... + * + * @return ( double ) + */ + double SelectSL( + X121SMCStrategyConditions &conditions, + ENUM_X_DIRECTION forDir, + ENUM_X_121_SMC_SL_TYPES type // + ) + { + // + double result = 0; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + bool isValid = + // + HasDirection(forDir) && + conditions.IsValid() && + type != X_121_SMC_SL_TYPE_NONE + // + ; + if (!isValid) + { + return result; + } + + // + XOHCL zBar; + bool isInited = zBar.Init( + symbol, + period, + 0 // + ); + if (!isInited) + { + return result; + } + + // + bool isBullish = IsBullish(forDir); + + // + if (type == X_121_SMC_SL_TYPE_FIBO_LEVEL_3) + { + result = conditions.triggerConditions.x121Conditions.fl3Buffer[0]; + } + else if (type == X_121_SMC_SL_TYPE_FIBO_LEVEL_1_5) + { + // + result = + isBullish + ? conditions.triggerConditions.x121Conditions.fl1Buffer[0] + : conditions.triggerConditions.x121Conditions.fl5Buffer[0]; + } + else if (type == X_121_SMC_SL_TYPE_DON_CLOSE_BOX) + { + // + result = + isBullish + ? conditions.triggerConditions.x121Conditions.donCloseLowerBuffer[0] + : conditions.triggerConditions.x121Conditions.donCloseUpperBuffer[0]; + } + else if (type == X_121_SMC_SL_TYPE_SWING) + { + // + int swingLowsCount = conditions.triggerConditions.state.CountSwingLows(); + int swingHighsCount = conditions.triggerConditions.state.CountSwingHighs(); + result = + isBullish + ? conditions.triggerConditions.state.swingLows[swingLowsCount - 1].GetValue() + : conditions.triggerConditions.state.swingHighs[swingHighsCount - 1].GetValue(); + } + else if (type == X_121_SMC_SL_TYPE_REJECTION) + { + // + result = + isBullish + ? conditions.triggerConditions.state.bullishRejectionBars[conditions.triggerConditions.state.CountBullishRejectionBars() - 1].Lower() + : conditions.triggerConditions.state.bearishRejectionBars[conditions.triggerConditions.state.CountBearishRejectionBars() - 1].Upper(); + } + else if (type == X_121_SMC_SL_TYPE_MOMENTUM) + { + // + result = + isBullish + ? conditions.triggerConditions.state.bullishMomentumBars[conditions.triggerConditions.state.CountBullishMomentumBars() - 1].Lower() + : conditions.triggerConditions.state.bearishMomentumBars[conditions.triggerConditions.state.CountBearishMomentumBars() - 1].Upper(); + } + else if (type == X_121_SMC_SL_TYPE_VWAP_FAST) + { + result = conditions.triggerConditions.x121Conditions.vwapFastBuffer[0]; + } + else if (type == X_121_SMC_SL_TYPE_VWAP_MID) + { + result = conditions.triggerConditions.x121Conditions.vwapMidBuffer[0]; + } + else if (type == X_121_SMC_SL_TYPE_VWAP_SLOW) + { + result = conditions.triggerConditions.x121Conditions.vwapSlowBuffer[0]; + } + else if (type == X_121_SMC_SL_TYPE_CURRENT_SAR) + { + result = conditions.triggerConditions.x121Conditions.sarBuffer[0]; + } + else if (type == X_121_SMC_SL_TYPE_TENKAN_SEN) + { + // + double hh = zBar.FindHighest( + 9, + MODE_HIGH // + ); + double ll = zBar.FindLowest( + 9, + MODE_LOW // + ); + double mid = (hh - ll) / 2; + result = isBullish + ? ll - mid + : hh + mid; + } + else if (type == X_121_SMC_SL_TYPE_CURRENT_SAR_BOX || + type == X_121_SMC_SL_TYPE_LAST_SAR_CHANGED_BAR || + type == X_121_SMC_SL_TYPE_LAST_DIRECTIONAL_SAR) + { + // + XOHCL cSarChangeBar; + XOHCL pSarChangeBar; + XValueChange cSarChange; // Current Sar Change (IsDirect) ... + XValueChange pSarChange; // Prev Sar Change (Direct) ... + XValueChange sarChanges[]; + int sarChangesCount = mTriggerCycleHelper + .FillSarChanges(sarChanges); + if (!IsValidSize(sarChangesCount) || sarChangesCount < 2) + { + return result; + } + + // + // + cSarChange = sarChanges[sarChangesCount - 1]; + pSarChange = sarChanges[sarChangesCount - 2]; + + // + bool isFilled = cSarChange.FillBar( + cSarChangeBar, + symbol, + period // + ); + if (!isFilled) + { + return result; + } + + // + isFilled = pSarChange.FillBar( + pSarChangeBar, + symbol, + period // + ); + if (!isFilled) + { + return result; + } + + // + if (type == X_121_SMC_SL_TYPE_LAST_SAR_CHANGED_BAR) + { + // + result = isBullish + ? pSarChangeBar.low + : pSarChangeBar.high; + } + else if (type == X_121_SMC_SL_TYPE_CURRENT_SAR_BOX) + { + // + result = + isBullish + ? zBar.FindLowest( + MathAbs(cSarChangeBar.Index() - 1), + MODE_LOW // + ) + : zBar.FindHighest( + MathAbs(cSarChangeBar.Index() - 1), + MODE_HIGH // + ); + } + else if (type == X_121_SMC_SL_TYPE_LAST_DIRECTIONAL_SAR) + { + // + XOHCL prevBar; + bool isInited = cSarChangeBar.GetPreviousBar(prevBar); + if (!isInited) + { + return result; + } + + // + result = isBullish + ? prevBar.low + : prevBar.high; + } + } + + // + return result; + } + + // + // Drawing Functions ... + + /** + * Custom Drawing State ... + * + * @param state: XPOIState instance reference, Specified Which state to Draw ... + * @param forceDrawSamePeriod: Boolean ... + */ + void CustomStateDrawing( + XPOIState &state, + bool filterByPrice = false, + bool forceDrawSamePeriod = false, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + // + // Ignores List ... + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // + ) + { + // + XPOIState tmpState = state; + + // + if (forceDrawSamePeriod) + { + // + int count = 0; + ENUM_TIMEFRAMES period = GetPeriod(); + + // + count = state.CountSwingHighs(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingHighs, + i, + 1 // + ); + } + } + } + + // + count = state.CountSwingLows(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingLows, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone iZone = state.supportZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supportZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone iZone = state.resistanceZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.resistanceZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone iZone = state.supplyZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supplyZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone iZone = state.demandZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.demandZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bullishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bearishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bullishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bearishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + } + + // + if (filterByPrice) + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL bar; + bool isInited = bar.Init( + symbol, + period, + 1 // + ); + + // + if (isInited) + { + // + // Support Zones ... + int supportZonesCount = ArraySize(tmpState.supportZones); + if (IsValidSize(supportZonesCount)) + { + // + XCSupportZone *supports[]; + for (int i = 0; i < supportZonesCount; i++) + { + // + XCSupportZone *iZone = tmpState.supportZones[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + supports // + ); + } + } + + // + Clean(tmpState.supportZones); + Copy( + supports, + tmpState.supportZones // + ); + } + + // + // Resistance Zones ... + int resistanceZonesCount = ArraySize(tmpState.resistanceZones); + if (IsValidSize(resistanceZonesCount)) + { + // + XCResistanceZone *resistances[]; + for (int i = 0; i < resistanceZonesCount; i++) + { + // + XCResistanceZone *iZone = tmpState.resistanceZones[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + resistances // + ); + } + } + + // + Clean(tmpState.resistanceZones); + Copy( + resistances, + tmpState.resistanceZones // + ); + } + + // + // Supply Zones ... + int supplyZonesCount = ArraySize(tmpState.supplyZones); + if (IsValidSize(supplyZonesCount)) + { + // + XCSupplyZone *supplies[]; + for (int i = 0; i < supplyZonesCount; i++) + { + // + XCSupplyZone *iZone = tmpState.supplyZones[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + supplies // + ); + } + } + + // + Clean(tmpState.supplyZones); + Copy( + supplies, + tmpState.supplyZones // + ); + } + + // + // Demand Zones ... + int demandZonesCount = ArraySize(tmpState.demandZones); + if (IsValidSize(demandZonesCount)) + { + // + XCDemandZone *demands[]; + for (int i = 0; i < demandZonesCount; i++) + { + // + XCDemandZone *iZone = tmpState.demandZones[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + demands // + ); + } + } + + // + Clean(tmpState.demandZones); + Copy( + demands, + tmpState.demandZones // + ); + } + + // + // Bullish Order Blocks ... + int bullishOrderBlocksCount = ArraySize(tmpState.bullishOrderBlocks); + if (IsValidSize(bullishOrderBlocksCount)) + { + // + XCOrderBlock *obs[]; + for (int i = 0; i < bullishOrderBlocksCount; i++) + { + // + XCOrderBlock *iZone = tmpState.bullishOrderBlocks[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + obs // + ); + } + } + + // + Clean(tmpState.bullishOrderBlocks); + Copy( + obs, + tmpState.bullishOrderBlocks // + ); + } + + // + // Bearish Order Blocks ... + int bearishOrderBlocksCount = ArraySize(tmpState.bearishOrderBlocks); + if (IsValidSize(bearishOrderBlocksCount)) + { + // + XCOrderBlock *obs[]; + for (int i = 0; i < bearishOrderBlocksCount; i++) + { + // + XCOrderBlock *iZone = tmpState.bearishOrderBlocks[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + obs // + ); + } + } + + // + Clean(tmpState.bearishOrderBlocks); + Copy( + obs, + tmpState.bearishOrderBlocks // + ); + } + + // + // Bullish Fair Value Gaps ... + int bullishFairValueGapsCount = ArraySize(tmpState.bullishFairValueGaps); + if (IsValidSize(bullishFairValueGapsCount)) + { + // + XCFVG *obs[]; + for (int i = 0; i < bullishFairValueGapsCount; i++) + { + // + XCFVG *iZone = tmpState.bullishFairValueGaps[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + obs // + ); + } + } + + // + Clean(tmpState.bullishFairValueGaps); + Copy( + obs, + tmpState.bullishFairValueGaps // + ); + } + + // + // Bearish Fair Value Gaps ... + int bearishFairValueGapsCount = ArraySize(tmpState.bearishFairValueGaps); + if (IsValidSize(bearishFairValueGapsCount)) + { + // + XCFVG *obs[]; + for (int i = 0; i < bearishFairValueGapsCount; i++) + { + // + XCFVG *iZone = tmpState.bearishFairValueGaps[i]; + + // + bool isValid = + // + (bar.low < iZone.Upper() && + bar.high > iZone.Upper()) || + (bar.high > iZone.Lower() && + bar.low < iZone.Lower()) || + (bar.low > iZone.Lower() && + bar.high < iZone.Upper()) + // + ; + if (isValid) + { + Add( + iZone, + obs // + ); + } + } + + // + Clean(tmpState.bearishFairValueGaps); + Copy( + obs, + tmpState.bearishFairValueGaps // + ); + } + } + } + + // + bool drawSwingHighs = true; + bool drawSwingLows = true; + bool drawSupportZones = true; + bool drawResistanceZones = true; + bool drawSupplyZones = true; + bool drawDemandZones = true; + bool drawBullishOrderBlocks = true; + bool drawBearishOrderBlocks = true; + bool drawBullishFairValueGaps = true; + bool drawBearishFairValueGaps = true; + bool drawBullishRejectionBars = true; + bool drawBearishRejectionBars = true; + bool drawBullishMomentumBars = true; + bool drawBearishMomentumBars = true; + + // + // Change Drawing Specs Conditions based on + // Provided Direction ... + if (forDir == X_DIRECTION_BULLISH) + { + // + drawSwingLows = true; + drawDemandZones = true; + drawSupportZones = true; + drawBullishOrderBlocks = true; + drawBullishFairValueGaps = true; + drawBullishRejectionBars = true; + drawBullishMomentumBars = true; + + // + drawSwingHighs = false; + drawSupplyZones = false; + drawResistanceZones = false; + drawBearishOrderBlocks = false; + drawBearishFairValueGaps = false; + drawBearishRejectionBars = false; + drawBearishMomentumBars = false; + } + else if (forDir == X_DIRECTION_BEARISH) + { + // + drawSwingLows = false; + drawDemandZones = false; + drawSupportZones = false; + drawBullishOrderBlocks = false; + drawBullishFairValueGaps = false; + drawBullishRejectionBars = false; + drawBullishMomentumBars = false; + + // + drawSwingHighs = true; + drawSupplyZones = true; + drawResistanceZones = true; + drawBearishOrderBlocks = true; + drawBearishFairValueGaps = true; + drawBearishRejectionBars = true; + drawBearishMomentumBars = true; + } + + // + // Apply Ignore List ... + + // + if (ignoreSwingHighs) + { + drawSwingHighs = false; + } + + // + if (ignoreSwingLows) + { + drawSwingLows = false; + } + + // + if (ignoreSupportZones) + { + drawSupportZones = false; + } + + // + if (ignoreResistanceZones) + { + drawResistanceZones = false; + } + + // + if (ignoreSupplyZones) + { + drawSupplyZones = false; + } + + // + if (ignoreDemandZones) + { + drawDemandZones = false; + } + + // + if (ignoreBullishOrderBlocks) + { + drawBullishOrderBlocks = false; + } + + // + if (ignoreBearishOrderBlocks) + { + drawBearishOrderBlocks = false; + } + + // + if (ignoreBullishFairValueGaps) + { + drawBullishFairValueGaps = false; + } + + // + if (ignoreBearishFairValueGaps) + { + drawBearishFairValueGaps = false; + } + + // + if (ignoreBullishRejectionBars) + { + drawBullishRejectionBars = false; + } + + // + if (ignoreBearishRejectionBars) + { + drawBearishRejectionBars = false; + } + + // + if (ignoreBullishMomentumBars) + { + drawBullishMomentumBars = false; + } + + // + if (ignoreBearishMomentumBars) + { + drawBearishMomentumBars = false; + } + + // + DrawState( + tmpState, // State ... + true, // Update To of all Drawings Till now ... + drawSwingHighs, // Draw SwingHighs .. + drawSwingLows, // Draw SwingLows .. + drawSupportZones, // Draw SupportZones .. + drawResistanceZones, // Draw ResistanceZones .. + drawSupplyZones, // Draw SupplyZones .. + drawDemandZones, // Draw DemandZones .. + drawBullishOrderBlocks, // Draw BullishOrderBlocks .. + drawBearishOrderBlocks, // Draw BearishOrderBlocks .. + drawBullishFairValueGaps, // Draw BullishFairValueGaps .. + drawBearishFairValueGaps, // Draw BearishFairValueGaps .. + drawBullishRejectionBars, // Draw BullishRejectionBars .. + drawBearishRejectionBars, // Draw BearishRejectionBars .. + drawBullishMomentumBars, // Draw BullishMomentumBars .. + drawBearishMomentumBars, // Draw BearishMomentumBars .. + true // Draw Ticks Zone ... + ); + } + + /** + * Draw Specific Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * @param drawState: Boolean ... + * @param filterByPrice: Boolean ... + * @param ignoreSwingHighs: Boolean ... + * @param ignoreSwingLows: Boolean ... + * @param ignoreSupportZones: Boolean ... + * @param ignoreResistanceZones: Boolean ... + * @param ignoreSupplyZones: Boolean ... + * @param ignoreDemandZones: Boolean ... + * @param ignoreBullishOrderBlocks: Boolean ... + * @param ignoreBearishOrderBlocks: Boolean ... + * @param ignoreBullishFairValueGaps: Boolean ... + * @param ignoreBearishFairValueGaps: Boolean ... + * @param ignoreBullishRejectionBars: Boolean ... + * @param ignoreBearishRejectionBars: Boolean ... + * @param ignoreBullishMomentumBars: Boolean ... + * @param ignoreBearishMomentumBars: Boolean ... + */ + void DrawPivot( + XPVPivot &pivot, + bool drawState = true, + bool filterByPrice = false, + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // + ) + { + // + if (!pivot.IsValid()) + { + return; + } + + // + // Draw Pivot it self ... + XCXPVPivotObject *iPivotObj; + iPivotObj = new XCXPVPivotObject(); + bool isCreated = iPivotObj.Create( + mPOIDrawer.ChartIdentification(), + mPOIDrawer.SubWindowIdentification(), + pivot // + ); + if (!isCreated) + { + return; + } + + // + color clrPivotColor = pivot.IsPeak() + ? clrAqua + : clrMagenta; + iPivotObj.PivotColor(clrPivotColor); + iPivotObj.PivotWidth(2); + + // + AddObjectIfNotExists(iPivotObj); + + // + if (!drawState) + { + return; + } + + // + if (!pivot.state.IsValid()) + { + return; + } + + // + CustomStateDrawing( + pivot.state, + filterByPrice, + false, // forceDrawSamePeriod + X_DIRECTION_NONE, // forDir + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.test.signal.class.mq5 b/Documents/BKP/x-121.smc.test.signal.class.mq5 new file mode 100644 index 00000000..20cdf644 --- /dev/null +++ b/Documents/BKP/x-121.smc.test.signal.class.mq5 @@ -0,0 +1,787 @@ +/////////////////////////////////////////////////////// +// +// 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 X121SMCStrategyTestSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + XPVPivot pivot; + + // + // Trigger Props ... + + // + // Constructor ... + X121SMCStrategyTestSignalConditions() + { + 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; + + // + pivot.Clean(); + } + + /** + * 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; + } + + /** + * 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 ... + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCTestSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyTestSignalConditions &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; + + // + // Check Order Block ... + // TODO: Later ... + // bool hasOrderBlock = conditions.HasOrderBlock(); + // if (hasOrderBlock) + // { + // // + // DetectX121SMCTestSiganlOrderBlock( + // zBar, + // consolidationState, + // conditions // + // ); + // } + + // + bool isMarketBullish = + // + // VWap State ... + decisionConditions.x121Conditions.isVWapBullishState && + analyseConditions.x121Conditions.isVWapBullishState && + verificationConditions.x121Conditions.isVWapBullishState + // + && + // + // VWap Order ... + decisionConditions.x121Conditions.isVWapBullishOrdered && + analyseConditions.x121Conditions.isVWapBullishOrdered && + verificationConditions.x121Conditions.isVWapBullishOrdered + // + && + // + // Sar ... + decisionConditions.x121Conditions.isSarBullish && + analyseConditions.x121Conditions.isSarBullish && + verificationConditions.x121Conditions.isSarBullish + // + ; + + // + bool isMarketBearish = + // + // VWap State ... + decisionConditions.x121Conditions.isVWapBearishState && + analyseConditions.x121Conditions.isVWapBearishState && + verificationConditions.x121Conditions.isVWapBearishState + // + && + // + // VWap Order ... + decisionConditions.x121Conditions.isVWapBearishOrdered && + analyseConditions.x121Conditions.isVWapBearishOrdered && + verificationConditions.x121Conditions.isVWapBearishOrdered + // + && + // + // Sar ... + decisionConditions.x121Conditions.isSarBearish && + analyseConditions.x121Conditions.isSarBearish && + verificationConditions.x121Conditions.isSarBearish + // + ; + + // + // Step 1 + // Detect Market Direction ... + isBullish = isMarketBullish; + isBearish = isMarketBearish; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Step 2 + // VWap Switches or Sar Switches ... + + // + bool isSarBullish = triggerConditions.x121Conditions.isSarBullish; + bool isSarBearish = triggerConditions.x121Conditions.isSarBearish; + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + bool isVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState; + bool isVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState; + + // + bool isVWapSwitchedToBullishState = triggerConditions.x121Conditions.isVWapSwitchedToBullishState; + bool isVWapSwitchedToBearishState = triggerConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isVWapBullishOrdered = triggerConditions.x121Conditions.isVWapBullishOrdered; + bool isVWapBearishOrdered = triggerConditions.x121Conditions.isVWapBearishOrdered; + + // + bool isVWapSwitchedToBullishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + bool isVWapSwitchedToBearishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + // + // + + // + bool isSarStartedBullishStructure = + // + isSarSwitchedToBullish && + isVWapBullishState && + isVWapBullishOrdered + // + ; + + // + bool isSarStartedBearishStructure = + // + isSarSwitchedToBearish && + isVWapBearishState && + isVWapBearishOrdered + // + ; + + // + // + // + + // + bool isVWapStateStartedBullishStructure = + // + isVWapSwitchedToBullishState && + isSarBullish && + isVWapBullishOrdered + // + ; + + // + bool isVWapStateStartedBearishStructure = + // + isVWapSwitchedToBearishState && + isSarBearish && + isVWapBearishOrdered + // + ; + + // + // + // + + // + bool isVWapOrderStartedBullishStructure = + // + isVWapSwitchedToBullishOrdered && + isSarBullish && + isVWapBullishState + // + ; + + // + bool isVWapOrderStartedBearishStructure = + // + isVWapSwitchedToBearishOrdered && + isSarBearish && + isVWapBearishState + // + ; + + // + // + // + + // + isBullish = + // + isBullish + // + && + // + ( + // + isSarStartedBullishStructure || + isVWapStateStartedBullishStructure || + isVWapOrderStartedBullishStructure + // + ) + // + ; + + // + isBearish = + // + isBearish + // + && + // + ( + // + isSarStartedBearishStructure || + isVWapStateStartedBearishStructure || + isVWapOrderStartedBearishStructure + // + ) + // + ; + + // + 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 DetectX121SMCTestSiganlTrigger( + // + X121SMCStrategyTestSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + 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; + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_SMPV; + string providerStr = ToString(provider); + + // + 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; + + // + result = false; + + // + return result; +} + +// +// Tools Functions ... + +// \ No newline at end of file diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index 71a4d1d6..05d12efc 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -44,7 +44,7 @@ input string eaSymbols = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb"; // Trading Symbols // // Volume ... input group "Volume"; -input double eaR2R = 2; // Risk to Reward Ratio +input double eaR2R = 3.0; // Risk to Reward Ratio input bool eaUseDynamicVolume = false; // Use Dynamic Volume input double eaDynamicVolumeStep = 0.01; // Increase Volume Step input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 50aee741..cfd7d38f 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -275,6 +275,46 @@ class XCZone : public XCBasePOI return mLower; } + /** + * Retrieve Zone Range ... + * + * @return ( double ) + */ + double Range() + { + // + double result = 0; + + // + double upper = Upper(); + double lower = Lower(); + + // + if (upper > 0 && lower > 0 && upper > lower) + { + result = upper - lower; + } + + // + return result; + } + + double RangePercent() + { + // + double result = 0; + + // + double range = Range(); + if (range > 0) + { + result = range / 100; + } + + // + return result; + } + // // Virtuals ... diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index 9deb1d55..a4b9bdc8 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -1941,145 +1941,67 @@ class XC121SMCCycleHelper : public XCBase } } - // - // Calculate Pivots ... - if (isNewPeak || isNewVale) - { - // - mActivePivot.symbol = symbol; - mActivePivot.period = period; + // // + // // Calculate Pivots ... + // if (isNewPeak || isNewVale) + // { + // // + // if (!mActivePivot.IsValid()) + // { + // // + // mActivePivot.symbol = symbol; + // mActivePivot.period = period; - // - if (!IsValid(mActivePivot.from)) - { - // - mActivePivot.from = cTime; + // // + // mActivePivot.upper = peak; + // mActivePivot.lower = vale; - // - Add( - PIVOT_STARTED, - events // - ); - } - mActivePivot.to = cTime; + // // + // mActivePivot.from = cTime; + // mActivePivot.to = cTime; - // - if (mActivePivot.upper <= 0) - { - // - if (isNewPeakUnderLast) - { - mActivePivot.upper = conditions.x121Conditions.peaksBuffer[1]; - } - else - { - mActivePivot.upper = conditions.x121Conditions.peaksBuffer[1]; - } - } + // // + // mActivePivot.type = + // isNewPeak + // ? XPV_VALE + // : XPV_PEAK; + // mActivePivot.repetition++; - // - if (mActivePivot.lower <= 0) - { - // - if (isNewValeOverLast) - { - mActivePivot.lower = conditions.x121Conditions.valesBuffer[1]; - } - else - { - mActivePivot.lower = conditions.x121Conditions.valesBuffer[1]; - } - } + // // + // Add( + // PIVOT_STARTED, + // events // + // ); + // } + // else + // { + // // + // mActivePivot.to = cTime; - // - mActivePivot.type = - isNewPeak - ? XPV_VALE - : XPV_PEAK; - mActivePivot.repetition++; + // // + // mActivePivot.repetition++; - // - if (mActivePivot.to > mActivePivot.from) - { - // - FillPivotState(mActivePivot); + // // + // if (mActivePivot.to > mActivePivot.from) + // { + // FillPivotState(mActivePivot); + // } - // - // Check Active Pivot has State and Ticks Zone ... - if (mActivePivot.state.IsValid() && - mActivePivot.state.ticksZone != NULL && - mActivePivot.state.ticksZone.IsValid()) - { - // - // Here We Have to Calculate Ticks Level Volume and Percents ... - // Liquidity ... - - // - // Select Current TickZone which Price is Inside ... - int cTZoneIDX = -1; - int count = mActivePivot.state.ticksZone.Count(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCTickZone *iTZ = mActivePivot.state.ticksZone.GetZone(i); - - // - double pivot = - isNewPeak - ? peak - : vale; - bool isPivotInsideZone = - pivot >= iTZ.low && - pivot <= iTZ.high; - if (isPivotInsideZone) - { - // - cTZoneIDX = i; - break; - } - - // - bool isBarInside = - changeBar.low >= iTZ.low && - changeBar.high <= iTZ.high; - // if (isBarInside) - // { - // // - // cTZoneIDX = i; - // break; - // } - } - - // - // Last Zone ... - // We Can Break Active Zone ... - if (IsValidIndex(cTZoneIDX) && cTZoneIDX == count - 1) - { - // - Print("ZoneIndex: ", cTZoneIDX); - - // - AddRef( - mActivePivot, - mPivots // - ); - - // - Add( - PIVOT_ENDED, - events // - ); - - // - mActivePivot.Clean(); - } - } - } - } - } + // // + // // Check Ticks Zone is Valid ... + // bool isTicksZoneValid = + // // + // mActivePivot.state.IsValid() && + // mActivePivot.state.ticksZone != NULL && + // mActivePivot.state.ticksZone.IsValid() + // // + // ; + // if (isTicksZoneValid) { + // // + // Print("Has Valid Ticks Zone ..."); + // } + // } + // } } // diff --git a/X121SMCEA/Signals/x-121.smc.test.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.test.signal.class.mq5 index 20cdf644..e2c06d94 100644 --- a/X121SMCEA/Signals/x-121.smc.test.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.test.signal.class.mq5 @@ -48,7 +48,13 @@ struct X121SMCStrategyTestSignalConditions datetime triggerTime; // - XPVPivot pivot; + XCOrderBlock *bullishOBs[]; + XCOrderBlock *bearishOBs[]; + + // + XCFVG *activeFVG; + XCFVG *bullishFVGs[]; + XCFVG *bearishFVGs[]; // // Trigger Props ... @@ -82,7 +88,9 @@ struct X121SMCStrategyTestSignalConditions triggerTime = NULL; // - pivot.Clean(); + activeFVG = NULL; + Clean(bullishOBs); + Clean(bearishOBs); } /** @@ -109,6 +117,29 @@ struct X121SMCStrategyTestSignalConditions 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 ... * @@ -138,6 +169,54 @@ struct X121SMCStrategyTestSignalConditions // // Extensions ... + // + int CountBullishOBs() + { + return ArraySize(bullishOBs); + } + + // + int CountBearishOBs() + { + return ArraySize(bearishOBs); + } + + // + bool HasBullishOB() + { + return IsValidSize(CountBullishOBs()); + } + + // + bool HasBearishOB() + { + return IsValidSize(CountBearishOBs()); + } + + // + int CountBullishFVGs() + { + return ArraySize(bullishFVGs); + } + + // + int CountBearishFVGs() + { + return ArraySize(bearishFVGs); + } + + // + bool HasBullishFVG() + { + return IsValidSize(CountBullishFVGs()); + } + + // + bool HasBearishFVG() + { + return IsValidSize(CountBearishFVGs()); + } + // }; @@ -341,218 +420,340 @@ bool DetectX121SMCTestSiganlSetup( XPOIState visionState = visionConditions.state; // - // Check Order Block ... - // TODO: Later ... - // bool hasOrderBlock = conditions.HasOrderBlock(); - // if (hasOrderBlock) - // { - // // - // DetectX121SMCTestSiganlOrderBlock( - // zBar, - // consolidationState, - // conditions // - // ); - // } + // Detect Imbalances ... // - bool isMarketBullish = - // - // VWap State ... - decisionConditions.x121Conditions.isVWapBullishState && - analyseConditions.x121Conditions.isVWapBullishState && - verificationConditions.x121Conditions.isVWapBullishState - // - && - // - // VWap Order ... - decisionConditions.x121Conditions.isVWapBullishOrdered && - analyseConditions.x121Conditions.isVWapBullishOrdered && - verificationConditions.x121Conditions.isVWapBullishOrdered - // - && - // - // Sar ... - decisionConditions.x121Conditions.isSarBullish && - analyseConditions.x121Conditions.isSarBullish && - verificationConditions.x121Conditions.isSarBullish - // - ; + XPOIState state = decisionState; // - bool isMarketBearish = + bool hasBullishOB = conditions.HasBullishOB(); + if (!hasBullishOB) + { // - // VWap State ... - decisionConditions.x121Conditions.isVWapBearishState && - analyseConditions.x121Conditions.isVWapBearishState && - verificationConditions.x121Conditions.isVWapBearishState + int count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = state.bullishOrderBlocks[i]; + + // + // Validate Order Block ... + bool isValid = + // + cBar.low > iOB.Upper() + // + ; + if (isValid) + { + // + Add( + iOB, + conditions.bullishOBs // + ); + } + } + } + // - && - // - // VWap Order ... - decisionConditions.x121Conditions.isVWapBearishOrdered && - analyseConditions.x121Conditions.isVWapBearishOrdered && - verificationConditions.x121Conditions.isVWapBearishOrdered - // - && - // - // Sar ... - decisionConditions.x121Conditions.isSarBearish && - analyseConditions.x121Conditions.isSarBearish && - verificationConditions.x121Conditions.isSarBearish - // - ; + hasBullishOB = conditions.HasBullishOB(); + } // - // Step 1 - // Detect Market Direction ... - isBullish = isMarketBullish; - isBearish = isMarketBearish; + bool hasBearishOB = conditions.HasBearishOB(); + if (!hasBearishOB) + { + // + int count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iOB = state.bearishOrderBlocks[i]; + + // + // Validate Order Block ... + bool isValid = + // + cBar.high < iOB.Lower() + // + ; + if (isValid) + { + // + Add( + iOB, + conditions.bearishOBs // + ); + } + } + } + + // + hasBearishOB = conditions.HasBearishOB(); + } // - result = isBullish || - isBearish; + result = hasBullishOB || + hasBearishOB; if (!result) { return result; } // - // Step 2 - // VWap Switches or Sar Switches ... + int fvgValidationLength = 5; // - bool isSarBullish = triggerConditions.x121Conditions.isSarBullish; - bool isSarBearish = triggerConditions.x121Conditions.isSarBearish; - - // - bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; - bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; - - // - bool isVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState; - bool isVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState; - - // - bool isVWapSwitchedToBullishState = triggerConditions.x121Conditions.isVWapSwitchedToBullishState; - bool isVWapSwitchedToBearishState = triggerConditions.x121Conditions.isVWapSwitchedToBearishState; - - // - bool isVWapBullishOrdered = triggerConditions.x121Conditions.isVWapBullishOrdered; - bool isVWapBearishOrdered = triggerConditions.x121Conditions.isVWapBearishOrdered; - - // - bool isVWapSwitchedToBullishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBullishOrdered; - bool isVWapSwitchedToBearishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBearishOrdered; - - // - // - // - - // - bool isSarStartedBullishStructure = + bool hasBullishFVG = conditions.HasBullishFVG(); + if (!hasBullishFVG) + { // - isSarSwitchedToBullish && - isVWapBullishState && - isVWapBullishOrdered - // - ; - - // - bool isSarStartedBearishStructure = - // - isSarSwitchedToBearish && - isVWapBearishState && - isVWapBearishOrdered - // - ; - - // - // - // - - // - bool isVWapStateStartedBullishStructure = - // - isVWapSwitchedToBullishState && - isSarBullish && - isVWapBullishOrdered - // - ; - - // - bool isVWapStateStartedBearishStructure = - // - isVWapSwitchedToBearishState && - isSarBearish && - isVWapBearishOrdered - // - ; - - // - // - // - - // - bool isVWapOrderStartedBullishStructure = - // - isVWapSwitchedToBullishOrdered && - isSarBullish && - isVWapBullishState - // - ; - - // - bool isVWapOrderStartedBearishStructure = - // - isVWapSwitchedToBearishOrdered && - isSarBearish && - isVWapBearishState - // - ; - - // - // - // - - // - isBullish = - // - isBullish - // - && - // - ( + if (hasBullishOB) + { // - isSarStartedBullishStructure || - isVWapStateStartedBullishStructure || - isVWapOrderStartedBullishStructure - // - ) + int obsCount = conditions.CountBullishOBs(); + int count = state.CountBullishFairValueGaps(); + for (int i = 0; i < obsCount; i++) + { + // + XCOrderBlock *iOB = conditions.bullishOBs[i]; + + // + for (int j = 0; j < count; j++) + { + // + XCFVG *jFVG = state.bullishFairValueGaps[j]; + + // + bool isValid = + // + cBar.low > iOB.Upper() && + cBar.low > jFVG.Upper() && + // + jFVG.From() > iOB.From() && + (((int)(jFVG.From() - iOB.From())) / PeriodSeconds(state.period)) <= fvgValidationLength + // + ; + if (isValid) + { + // + Add( + jFVG, + conditions.bullishFVGs // + ); + } + } + } + } + // - ; + hasBullishFVG = conditions.HasBullishFVG(); + } // - isBearish = + bool hasBearishFVG = conditions.HasBearishFVG(); + if (!hasBearishFVG) + { // - isBearish - // - && - // - ( + if (hasBullishOB) + { // - isSarStartedBearishStructure || - isVWapStateStartedBearishStructure || - isVWapOrderStartedBearishStructure - // - ) + int obsCount = conditions.CountBearishOBs(); + int count = state.CountBearishFairValueGaps(); + for (int i = 0; i < obsCount; i++) + { + // + XCOrderBlock *iOB = conditions.bearishOBs[i]; + + // + for (int j = 0; j < count; j++) + { + // + XCFVG *jFVG = state.bearishFairValueGaps[j]; + + // + bool isValid = + // + cBar.high < iOB.Lower() && + cBar.high < jFVG.Lower() && + // + jFVG.From() > iOB.From() && + (((int)(jFVG.From() - iOB.From())) / PeriodSeconds(state.period)) <= fvgValidationLength + // + ; + if (isValid) + { + // + Add( + jFVG, + conditions.bearishFVGs // + ); + } + } + } + } + // - ; + hasBearishFVG = conditions.HasBearishFVG(); + } + + // + result = (hasBullishOB && + hasBullishFVG) || + (hasBearishOB && + hasBearishFVG); + if (!result) + { + return result; + } + + // + // Detect new Peak or new Vale ... + + // + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + bool isNewPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; + + // + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + bool isNewValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + result = isNewPeak || + isNewVale; + if (!result) + { + return result; + } + + // + // Detect Setup Conditions based on Peaks or Vales Occurance ... + bool lookupForLong = isNewVale && hasBullishOB && hasBullishFVG; + bool lookupForShort = isNewPeak && hasBearishOB && hasBearishFVG; + result = lookupForLong || + lookupForShort; + if (!result) + { + return result; + } + + // + XCFVG *fvg = NULL; + double fvgZoneValidationRangePercent = 0; + if (lookupForLong) + { + // + // Long Conditions ... + // Vales must be Happens Inside Bullish Fair Value Gaps ... + int count = conditions.CountBullishFVGs(); + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = conditions.bullishFVGs[i]; + + // + bool isValid = + // + vale <= iFVG.Upper() && + vale >= iFVG.Lower() && + (fvgZoneValidationRangePercent <= 0 + ? true + : (vale < iFVG.Upper() - (iFVG.RangePercent() * fvgZoneValidationRangePercent))) + // + ; + if (isValid) + { + // + fvg = iFVG; + break; + } + } + + // + isBullish = + // + fvg != NULL && + fvg.IsValid() + // + ; + if (isBullish) + { + conditions.activeFVG = fvg; + } + } + else if (lookupForShort) + { + // + // Short Conditions ... + // Peaks Must be Happens Inside Bearish Fair Value Gaps ... + int count = conditions.CountBearishFVGs(); + for (int i = 0; i < count; i++) + { + // + XCFVG *iFVG = conditions.bearishFVGs[i]; + + // + bool isValid = + // + peak <= iFVG.Upper() && + peak >= iFVG.Lower() && + (fvgZoneValidationRangePercent <= 0 + ? true + : (peak > iFVG.Lower() + (iFVG.RangePercent() * fvgZoneValidationRangePercent))) + // + ; + if (isValid) + { + // + fvg = iFVG; + break; + } + } + + // + isBearish = + // + fvg != NULL && + fvg.IsValid() + // + ; + if (isBearish) + { + conditions.activeFVG = fvg; + } + } // result = isBullish || isBearish; if (!result) { + // + if (lookupForLong) + { + // + conditions.activeFVG = NULL; + Clean(conditions.bullishOBs); + Clean(conditions.bullishFVGs); + } + else if (lookupForShort) + { + // + conditions.activeFVG = NULL; + Clean(conditions.bearishOBs); + Clean(conditions.bearishFVGs); + } + + // return result; } @@ -581,7 +782,9 @@ bool DetectX121SMCTestSiganlTrigger( XC121SMCCycleHelper *analyseCycleHelper, XC121SMCCycleHelper *verificationCycleHelper, XC121SMCCycleHelper *consolidationCycleHelper, - XC121SMCCycleHelper *visionCycleHelper + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // // ) { @@ -596,6 +799,7 @@ bool DetectX121SMCTestSiganlTrigger( } // + datetime setupTime = conditions.setupTime; ENUM_X_DIRECTION setupDir = conditions.dir; // @@ -775,7 +979,685 @@ bool DetectX121SMCTestSiganlTrigger( XPOIState visionState = visionConditions.state; // - result = false; + // Trigger Conditions ... + XCFVG *iFVG = conditions.activeFVG; + result = iFVG != NULL && + iFVG.IsValid(); + if (!result) + { + return result; + } + + // + bool lookupLong = IsBullish(setupDir) && + iFVG.IsBullish(); + bool lookupShort = IsBearish(setupDir) && + iFVG.IsBearish(); + result = lookupLong || + lookupShort; + if (!result) + { + return result; + } + + // + // Check PEAKS and Vales ... + + // + // Trigger ... + + // + // Peaks and Vales ... + double triggerPeak = triggerConditions.x121Conditions.peaksBuffer[1]; + double triggerVale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + bool isTriggerPeakInsideFVG = + // + triggerPeak <= iFVG.Upper() && + triggerPeak >= iFVG.Lower() + // + ; + bool isTriggerValeInsideFVG = + // + triggerVale <= iFVG.Upper() && + triggerVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isTriggerVWapFastBullish = triggerConditions.x121Conditions.isVWapFastBullish; + bool isTriggerVWapMidBullish = triggerConditions.x121Conditions.isVWapMidBullish; + bool isTriggerVWapSlowBullish = triggerConditions.x121Conditions.isVWapSlowBullish; + + // + bool isTriggerVWapFastOverMid = triggerConditions.x121Conditions.isVWapFastOverMid; + bool isTriggerVWapMidOverSlow = triggerConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isTriggerVWapFastBearish = triggerConditions.x121Conditions.isVWapFastBearish; + bool isTriggerVWapMidBearish = triggerConditions.x121Conditions.isVWapMidBearish; + bool isTriggerVWapSlowBearish = triggerConditions.x121Conditions.isVWapSlowBearish; + + // + bool isTriggerVWapFastUnderMid = triggerConditions.x121Conditions.isVWapFastUnderMid; + bool isTriggerVWapMidUnderSlow = triggerConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isTriggerMarketBullish = + // + // State ... + ( + // + (isTriggerVWapFastBullish && + isTriggerVWapMidBullish && + isTriggerVWapSlowBullish) + // + || + // + (isTriggerVWapMidBullish && + isTriggerVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isTriggerVWapFastOverMid && + isTriggerVWapMidOverSlow) + // + || + // + isTriggerVWapMidOverSlow + // + ) + // + ; + + // + bool isTriggerMarketBearish = + // + // State ... + ( + // + (isTriggerVWapFastBearish && + isTriggerVWapMidBearish && + isTriggerVWapSlowBearish) + // + || + // + (isTriggerVWapMidBearish && + isTriggerVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isTriggerVWapFastUnderMid && + isTriggerVWapMidUnderSlow) + // + || + // + isTriggerVWapMidUnderSlow + // + ) + // + ; + + // + // Decision ... + + // + double decisionPeak = decisionConditions.x121Conditions.peaksBuffer[1]; + double decisionVale = decisionConditions.x121Conditions.valesBuffer[1]; + + // + bool isDecisionPeakInsideFVG = + // + decisionPeak <= iFVG.Upper() && + decisionPeak >= iFVG.Lower() + // + ; + bool isDecisionValeInsideFVG = + // + decisionVale <= iFVG.Upper() && + decisionVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isDecisionVWapFastBullish = decisionConditions.x121Conditions.isVWapFastBullish; + bool isDecisionVWapMidBullish = decisionConditions.x121Conditions.isVWapMidBullish; + bool isDecisionVWapSlowBullish = decisionConditions.x121Conditions.isVWapSlowBullish; + + // + bool isDecisionVWapFastOverMid = decisionConditions.x121Conditions.isVWapFastOverMid; + bool isDecisionVWapMidOverSlow = decisionConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isDecisionVWapFastBearish = decisionConditions.x121Conditions.isVWapFastBearish; + bool isDecisionVWapMidBearish = decisionConditions.x121Conditions.isVWapMidBearish; + bool isDecisionVWapSlowBearish = decisionConditions.x121Conditions.isVWapSlowBearish; + + // + bool isDecisionVWapFastUnderMid = decisionConditions.x121Conditions.isVWapFastUnderMid; + bool isDecisionVWapMidUnderSlow = decisionConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isDecisionMarketBullish = + // + // State ... + ( + // + (isDecisionVWapFastBullish && + isDecisionVWapMidBullish && + isDecisionVWapSlowBullish) + // + || + // + (isDecisionVWapMidBullish && + isDecisionVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isDecisionVWapFastOverMid && + isDecisionVWapMidOverSlow) + // + || + // + isDecisionVWapMidOverSlow + // + ) + // + ; + + // + bool isDecisionMarketBearish = + // + // State ... + ( + // + (isDecisionVWapFastBearish && + isDecisionVWapMidBearish && + isDecisionVWapSlowBearish) + // + || + // + (isDecisionVWapMidBearish && + isDecisionVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isDecisionVWapFastUnderMid && + isDecisionVWapMidUnderSlow) + // + || + // + isDecisionVWapMidUnderSlow + // + ) + // + ; + + // + // Analyse ... + + // + double analysePeak = analyseConditions.x121Conditions.peaksBuffer[1]; + double analyseVale = analyseConditions.x121Conditions.valesBuffer[1]; + + // + bool isAnalysePeakInsideFVG = + // + analysePeak <= iFVG.Upper() && + analysePeak >= iFVG.Lower() + // + ; + bool isAnalyseValeInsideFVG = + // + analyseVale <= iFVG.Upper() && + analyseVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isAnalyseVWapFastBullish = analyseConditions.x121Conditions.isVWapFastBullish; + bool isAnalyseVWapMidBullish = analyseConditions.x121Conditions.isVWapMidBullish; + bool isAnalyseVWapSlowBullish = analyseConditions.x121Conditions.isVWapSlowBullish; + + // + bool isAnalyseVWapFastOverMid = analyseConditions.x121Conditions.isVWapFastOverMid; + bool isAnalyseVWapMidOverSlow = analyseConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isAnalyseVWapFastBearish = analyseConditions.x121Conditions.isVWapFastBearish; + bool isAnalyseVWapMidBearish = analyseConditions.x121Conditions.isVWapMidBearish; + bool isAnalyseVWapSlowBearish = analyseConditions.x121Conditions.isVWapSlowBearish; + + // + bool isAnalyseVWapFastUnderMid = analyseConditions.x121Conditions.isVWapFastUnderMid; + bool isAnalyseVWapMidUnderSlow = analyseConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isAnalyseMarketBullish = + // + // State ... + ( + // + (isAnalyseVWapFastBullish && + isAnalyseVWapMidBullish && + isAnalyseVWapSlowBullish) + // + || + // + (isAnalyseVWapMidBullish && + isAnalyseVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isAnalyseVWapFastOverMid && + isAnalyseVWapMidOverSlow) + // + || + // + isAnalyseVWapMidOverSlow + // + ) + // + ; + + // + bool isAnalyseMarketBearish = + // + // State ... + ( + // + (isAnalyseVWapFastBearish && + isAnalyseVWapMidBearish && + isAnalyseVWapSlowBearish) + // + || + // + (isAnalyseVWapMidBearish && + isAnalyseVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isAnalyseVWapFastUnderMid && + isAnalyseVWapMidUnderSlow) + // + || + // + isAnalyseVWapMidUnderSlow + // + ) + // + ; + + // + // Verification ... + + // + double verificationPeak = verificationConditions.x121Conditions.peaksBuffer[1]; + double verificationVale = verificationConditions.x121Conditions.valesBuffer[1]; + + // + bool isVerificationPeakInsideFVG = + // + verificationPeak <= iFVG.Upper() && + verificationPeak >= iFVG.Lower() + // + ; + bool isVerificationValeInsideFVG = + // + verificationVale <= iFVG.Upper() && + verificationVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isVerificationVWapFastBullish = verificationConditions.x121Conditions.isVWapFastBullish; + bool isVerificationVWapMidBullish = verificationConditions.x121Conditions.isVWapMidBullish; + bool isVerificationVWapSlowBullish = verificationConditions.x121Conditions.isVWapSlowBullish; + + // + bool isVerificationVWapFastOverMid = verificationConditions.x121Conditions.isVWapFastOverMid; + bool isVerificationVWapMidOverSlow = verificationConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isVerificationVWapFastBearish = verificationConditions.x121Conditions.isVWapFastBearish; + bool isVerificationVWapMidBearish = verificationConditions.x121Conditions.isVWapMidBearish; + bool isVerificationVWapSlowBearish = verificationConditions.x121Conditions.isVWapSlowBearish; + + // + bool isVerificationVWapFastUnderMid = verificationConditions.x121Conditions.isVWapFastUnderMid; + bool isVerificationVWapMidUnderSlow = verificationConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isVerificationMarketBullish = + // + // State ... + ( + // + (isVerificationVWapFastBullish && + isVerificationVWapMidBullish && + isVerificationVWapSlowBullish) + // + || + // + (isVerificationVWapMidBullish && + isVerificationVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isVerificationVWapFastOverMid && + isVerificationVWapMidOverSlow) + // + || + // + isVerificationVWapMidOverSlow + // + ) + // + ; + + // + bool isVerificationMarketBearish = + // + // State ... + ( + // + (isVerificationVWapFastBearish && + isVerificationVWapMidBearish && + isVerificationVWapSlowBearish) + // + || + // + (isVerificationVWapMidBearish && + isVerificationVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isVerificationVWapFastUnderMid && + isVerificationVWapMidUnderSlow) + // + || + // + isVerificationVWapMidUnderSlow + // + ) + // + ; + + // + // Consolidation ... + + // + double consolidationPeak = consolidationConditions.x121Conditions.peaksBuffer[1]; + double consolidationVale = consolidationConditions.x121Conditions.valesBuffer[1]; + + // + bool isConsolidationPeakInsideFVG = + // + consolidationPeak <= iFVG.Upper() && + consolidationPeak >= iFVG.Lower() + // + ; + bool isConsolidationValeInsideFVG = + // + consolidationVale <= iFVG.Upper() && + consolidationVale >= iFVG.Lower() + // + ; + + // + // VWap ... + + // + bool isConsolidationVWapFastBullish = consolidationConditions.x121Conditions.isVWapFastBullish; + bool isConsolidationVWapMidBullish = consolidationConditions.x121Conditions.isVWapMidBullish; + bool isConsolidationVWapSlowBullish = consolidationConditions.x121Conditions.isVWapSlowBullish; + + // + bool isConsolidationVWapFastOverMid = consolidationConditions.x121Conditions.isVWapFastOverMid; + bool isConsolidationVWapMidOverSlow = consolidationConditions.x121Conditions.isVWapMidOverSlow; + + // + bool isConsolidationVWapFastBearish = consolidationConditions.x121Conditions.isVWapFastBearish; + bool isConsolidationVWapMidBearish = consolidationConditions.x121Conditions.isVWapMidBearish; + bool isConsolidationVWapSlowBearish = consolidationConditions.x121Conditions.isVWapSlowBearish; + + // + bool isConsolidationVWapFastUnderMid = consolidationConditions.x121Conditions.isVWapFastUnderMid; + bool isConsolidationVWapMidUnderSlow = consolidationConditions.x121Conditions.isVWapMidUnderSlow; + + // + bool isConsolidationMarketBullish = + // + // State ... + ( + // + (isConsolidationVWapFastBullish && + isConsolidationVWapMidBullish && + isConsolidationVWapSlowBullish) + // + || + // + (isConsolidationVWapMidBullish && + isConsolidationVWapSlowBullish) + // + ) + // + && + // + // Order ... + ( + // + (isConsolidationVWapFastOverMid && + isConsolidationVWapMidOverSlow) + // + || + // + isConsolidationVWapMidOverSlow + // + ) + // + ; + + // + bool isConsolidationMarketBearish = + // + // State ... + ( + // + (isConsolidationVWapFastBearish && + isConsolidationVWapMidBearish && + isConsolidationVWapSlowBearish) + // + || + // + (isConsolidationVWapMidBearish && + isConsolidationVWapSlowBearish) + // + ) + // + && + // + // Order ... + ( + // + (isConsolidationVWapFastUnderMid && + isConsolidationVWapMidUnderSlow) + // + || + // + isConsolidationVWapMidUnderSlow + // + ) + // + ; + + // + // Sar ... + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + // Summarize Conditions ... + + // + bool isSamePeak = + triggerPeak == decisionPeak && + triggerPeak == analysePeak && + triggerPeak == verificationPeak; + + // + bool isPeaksInsideFVG = + // + isTriggerPeakInsideFVG && + isDecisionPeakInsideFVG && + isAnalysePeakInsideFVG && + isVerificationPeakInsideFVG + // + ; + + // + bool isSameVale = + triggerVale == decisionVale && + triggerVale == analyseVale && + triggerVale == verificationVale; + + // + bool isValesInsideFVG = + // + isTriggerValeInsideFVG && + isDecisionValeInsideFVG && + isAnalyseValeInsideFVG && + isVerificationValeInsideFVG + // + ; + + // + bool isMarketReadyForLong = + // + // !isTriggerMarketBearish && + // !isDecisionMarketBearish && + !isAnalyseMarketBearish && + !isVerificationMarketBearish && + !isConsolidationMarketBearish + // + ; + + // + bool isMarketReadyForShort = + // + // !isTriggerMarketBullish && + // !isDecisionMarketBullish && + !isAnalyseMarketBullish && + !isVerificationMarketBullish && + !isConsolidationMarketBullish + // + ; + + // + // Create Trigger ... + + // + isBullish = + // isSameVale && + lookupLong && + isValesInsideFVG && + isMarketReadyForLong && + isSarSwitchedToBullish && + triggerVale <= iFVG.Upper() && + triggerVale >= iFVG.Lower(); + + // + isBearish = + // isSamePeak && + lookupShort && + isPeaksInsideFVG && + isMarketReadyForShort && + isSarSwitchedToBearish && + triggerPeak <= iFVG.Upper() && + triggerPeak >= iFVG.Lower(); + + // + 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 + ? iFVG.Lower() + : iFVG.Upper(); + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; // return result; diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index c9503670..48f616ff 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -487,6 +487,23 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy } conditions.visionConditions.state = mVisionState; + // // + // XPVPivot triggerPivot; + // mTriggerCycleHelper.GetActivePivot(triggerPivot); + // result = triggerPivot.IsValid(); + // if (!result) + // { + // return result; + // } + + // // + // ClearDraws(); + // DrawPivot( + // triggerPivot, + // true, // Draw State ... + // true // Filter By Price ... + // ); + // return result; } @@ -520,123 +537,127 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy string providerStr = ToString(provider); // - XPVPivot triggerPivot; - mTriggerCycleHelper.GetActivePivot(triggerPivot); - result = triggerPivot.IsValid(); + // Detect Setup Conditions ... + datetime setupTime = mTestConditions.setupTime; + bool isSetuped = mTestConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mTestConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCTestSiganlSetup( + symbol, + period, + mTestConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = isSetuped; + if (!result) + { + return result; + } + + // + setupDir = mTestConditions.dir; + setupTime = mTestConditions.setupTime; + } + + // + // Draw Conditions Active FVG ... + if (isSetuped) + { + // + XCFVG *iFVG = mTestConditions.activeFVG; + if (iFVG != NULL && iFVG.IsValid()) + { + // + ClearDraws(); + iFVG.To(cTime); + if (IsBullish(setupDir) && iFVG.IsBullish()) + { + // + XCBullishFairValueGapObject *iObj; + bool isCreated = mPOIDrawer.CreateBullishFairValueGap( + iFVG, + iObj // + ); + if (isCreated) + { + AddObjectIfNotExists(iObj); + } + } + else if (IsBearish(setupDir) && iFVG.IsBearish()) + { + // + XCBearishFairValueGapObject *iObj; + bool isCreated = mPOIDrawer.CreateBearishFairValueGap( + iFVG, + iObj // + ); + if (isCreated) + { + AddObjectIfNotExists(iObj); + } + } + } + } + + // + // Detect Trigger Conditions ... + bool canTrigger = mTestConditions.CanTrigger(); + datetime triggerTime = mTestConditions.triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCTestSiganlTrigger( + mTestConditions, + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + return result; + } + + // + triggerTime = mTestConditions.triggerTime; + } + + // + // Check Signal Direction ... + + // + isBullish = IsBullish(setupDir); + isBearish = IsBearish(setupDir); + result = isBullish || + isBearish; if (!result) { return result; } // - ClearDraws(); - DrawPivot( - triggerPivot, - true, // Draw State ... - true // Filter By Price ... - ); - - // - // Detect Setup Conditions ... - // datetime setupTime = mTestConditions.setupTime; - // bool isSetuped = mTestConditions.IsSetuped(); - // ENUM_X_DIRECTION setupDir = mTestConditions.dir; - // if (!isSetuped) - // { - // // - // // Detect Signal Setup ... - // isSetuped = DetectX121SMCTestSiganlSetup( - // symbol, - // period, - // mTestConditions, - // mTriggerCycleHelper, - // mDecisionCycleHelper, - // mAnalyseCycleHelper, - // mVerificationCycleHelper, - // mConsolidationCycleHelper, - // mVisionCycleHelper // - // ); - - // // - // result = isSetuped; - // if (!result) - // { - // return result; - // } - - // // - // setupTime = mTestConditions.setupTime; - // } - - // // - // ClearDraws(); - // CustomStateDrawing( - // mTriggerState, - // true // Filter By Price ... - // ); - - // - // Detect Trigger Conditions ... - // bool canTrigger = mTestConditions.CanTrigger(); - // datetime triggerTime = mTestConditions.triggerTime; - // result = canTrigger; - // if (!canTrigger) - // { - // // - // // Detect Signal Trigger ... - // canTrigger = DetectX121SMCTestSiganlTrigger( - // mTestConditions, - // symbol, - // period, - // mTriggerCycleHelper, - // mDecisionCycleHelper, - // mAnalyseCycleHelper, - // mVerificationCycleHelper, - // mConsolidationCycleHelper, - // mVisionCycleHelper // - // ); - - // // - // result = canTrigger; - // if (!result) - // { - // return result; - // } - - // // - // triggerTime = mTestConditions.triggerTime; - // } - - // - // Check Signal Direction ... - - // // - // isBullish = IsBullish(setupDir); - // isBearish = IsBearish(setupDir); - - // - // result = isBullish || - // isBearish; - // if (!result) - // { - // return result; - // } - - // // - // if (cTime - setupTime > 2400) - // { - // // - // ClearDraws(); - - // // - // mTestConditions.Clean(); - // } - - // // - // // Issues Signal on Conditions ... - // conditions.signalDir = setupDir; - // conditions.provider = providerStr; - // conditions.sl = mTestConditions.sl; + // Issues Signal on Conditions ... + conditions.signalDir = setupDir; + conditions.provider = providerStr; + conditions.sl = mTestConditions.sl; // mTestConditions.Clean();