From a9ab5a62587996e28505e26884d5bf737d44664e Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 3 Jan 2025 20:25:00 +0330 Subject: [PATCH] last ... --- ...-121.smc.market.cycle.helper.class.old.mq5 | 4143 +++++++++++++++++ .../1/x-121.smc.xtwpv.old.1.signal.lib.mq5 | 1420 ++++++ .../BKP/1/x-121.smc.xtwpv.old.signal.lib.mq5 | 2060 ++++++++ Helpers/x-saherelm.x121.helper.mq5 | 240 + .../x-121.smc.market.cycle.helper.class.mq5 | 3106 ------------ .../x-121.smc.x-tradehandler.class.mq5 | 115 + X121SMCEA/Experts/x-121.smc.expert.class.mq5 | 1 + X121SMCEA/Libraries/x-121.smc.lib.mq5 | 175 +- .../Signals/x-121.smc.xtwpv.signal.lib.mq5 | 1704 ++----- .../Strategy/x-121.smc.strategy.class.mq5 | 94 +- 10 files changed, 8609 insertions(+), 4449 deletions(-) create mode 100644 Documents/BKP/1/x-121.smc.market.cycle.helper.class.old.mq5 create mode 100644 Documents/BKP/1/x-121.smc.xtwpv.old.1.signal.lib.mq5 create mode 100644 Documents/BKP/1/x-121.smc.xtwpv.old.signal.lib.mq5 diff --git a/Documents/BKP/1/x-121.smc.market.cycle.helper.class.old.mq5 b/Documents/BKP/1/x-121.smc.market.cycle.helper.class.old.mq5 new file mode 100644 index 00000000..492a1aad --- /dev/null +++ b/Documents/BKP/1/x-121.smc.market.cycle.helper.class.old.mq5 @@ -0,0 +1,4143 @@ +/////////////////////////////////////////////////////// +// +// 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_NONE, + X_CYCLE_TRIGGER, + X_CYCLE_DECISION, + X_CYCLE_ANALYSE, + X_CYCLE_VERIFICATION, + X_CYCLE_CONSOLIDATION, + X_CYCLE_VISION, +}; + +string ToString(ENUM_X_CYCLES value) +{ + // + string result = EnumToString(value); + + // + StringReplace(result, "X_CYCLE_", ""); + + // + return result; +} + +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, + PEAK_PIVOT_STARTED, + PEAK_PIVOT_ENDED, + VALE_PIVOT_STARTED, + VALE_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; + } + + /** + * Get Valid Pivot Points Repetition Length ... + * min => 7 + * + * @return ( int ) + */ + int ValidPivotRepetition() + { + return mValidPivotRepetition; + } + + /** + * Set Valid Pivot Points Repetition Length ... + * + * @param value: Integer ... + * min => 7 + */ + void ValidPivotRepetition(int value) + { + // + if (value < 7) + { + value = 7; + } + + // + mValidPivotRepetition = 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(10); + 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) + { + // + if (!IsValidSize(ArraySize(mPivots))) + { + Detect(barIndex); + } + + // + Calculate( + barIndex, + events, + conditions // + ); + } + + // + return result; + } + + /** + * Detect Market Structure ... + * + * @param model: XMarketStructure instance Reference ... + * + * @return ( bool ) + */ + bool DetectMarketStructure( + XMarketStructure &model // + ) + { + // + bool result = false; + + // + model.Clean(); + + // + int barIndex = 0; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + model.symbol = symbol; + model.period = period; + + // + int highestPeakIndex = -1; + double highestPeakVale = 0; + double highestPeak = mX121Helper + .GetHighestPeak( + barIndex, + highestPeakIndex, + highestPeakVale // + ); + + // + int lowestValeIndex = -1; + double lowestValePeak = 0; + double lowestVale = mX121Helper + .GetLowestVale( + barIndex, + lowestValeIndex, + lowestValePeak // + ); + + // + result = IsValidIndex(highestPeakIndex) && + IsValidIndex(lowestValeIndex); + if (!result) + { + return result; + } + + // + model.bias = + highestPeakIndex < lowestValeIndex + ? X_DIRECTION_BEARISH + : highestPeakIndex > lowestValeIndex + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + + // + result = HasDirection(model.bias); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(model.bias); + + // + // Looking for Change Of Character Proved ... + + // + // Bullish Bias: + // - Price Must Break Up Lowst Vale's Peak; + // - Create a Vale Above Lowest Vale's Peak; + + // + // Bearish Bias: + // - Price Must Breake Down HighestPeak's Vale; + // - Create a Peak Under Highest Peak's Vale; + + // + // Checking Peak Breake Up ... + int lowestValePeakBreakeUpIndex = -1; + for (int i = lowestValeIndex; i >= barIndex; i--) + { + // + XOHCL iBar; + result = GetBar(iBar, i); + if (!result) + { + continue; + } + + // + bool isBreake = iBar.IsBreakeUp(lowestValePeak); + if (isBreake) + { + // + lowestValePeakBreakeUpIndex = i; + break; + } + } + bool isValidBreakeUpLowestValePeak = IsValidIndex(lowestValePeakBreakeUpIndex) && + lowestValePeakBreakeUpIndex <= lowestValeIndex; + + // + // Checking Vale Breake Down ... + int highestPeakValeBreakeDownIndex = -1; + for (int i = highestPeakIndex; i >= barIndex; i--) + { + // + XOHCL iBar; + result = GetBar(iBar, i); + if (!result) + { + continue; + } + + // + bool isBreake = iBar.IsBreakeDown(highestPeakVale); + if (isBreake) + { + // + highestPeakValeBreakeDownIndex = i; + break; + } + } + bool isValidBreakeDownHighestPeakVale = IsValidIndex(highestPeakValeBreakeDownIndex) && + highestPeakValeBreakeDownIndex <= highestPeakIndex; + // + result = isBullish + ? isValidBreakeUpLowestValePeak + : isValidBreakeDownHighestPeakVale; + if (!result) + { + return result; + } + + // + // Checking Create a Vale above Peak ... + int valeAboveLowestValePeakIndex = -1; + double valeAboveLowestValePeakPeak = 0; + for (int i = lowestValePeakBreakeUpIndex; i >= barIndex; i--) + { + // + double iVale = mX121Helper.GetVale(i); + + // + bool isValid = + iVale > 0 && + iVale > lowestValePeak; + if (isValid) + { + // + valeAboveLowestValePeakIndex = i; + valeAboveLowestValePeakPeak = mX121Helper.GetPeak(i); + break; + } + } + bool isValidValeAboveLowestValePeak = IsValidIndex(valeAboveLowestValePeakIndex) && + valeAboveLowestValePeakIndex < lowestValePeakBreakeUpIndex; + + // + // Checking Create a Peak below Vale ... + int peakBelowHighestPeakValeIndex = -1; + double peakBelowHighestPeakValeVale = 0; + for (int i = highestPeakValeBreakeDownIndex; i >= barIndex; i--) + { + // + double iPeak = mX121Helper.GetPeak(i); + + // + bool isValid = + iPeak > 0 && + iPeak < highestPeakVale; + if (isValid) + { + // + peakBelowHighestPeakValeIndex = i; + peakBelowHighestPeakValeVale = mX121Helper.GetVale(i); + break; + } + } + bool isValidPeakBelowHighestPeakVale = IsValidIndex(peakBelowHighestPeakValeIndex) && + peakBelowHighestPeakValeIndex < highestPeakValeBreakeDownIndex; + + // + result = isBullish ? isValidValeAboveLowestValePeak + : isValidPeakBelowHighestPeakVale; + if (!result) + { + return result; + } + + // + // Now we Have to Detect Valid Peaks and Valid Vales Here ... + // based on Detected Range ... + + // + XPVPivotPoint iPeakPoint; + XPVPivotPoint iValePoint; + XPriceZones peakPriceZone; + XPriceZones valePriceZone; + + // + XPOIState state; + mPOIDetector.GetState( + state // + ); + + // + int minRepetition = 5; + + // + int from = + isBullish + ? valeAboveLowestValePeakIndex + : peakBelowHighestPeakValeIndex; + for (int i = from; i >= barIndex; i--) + { + // + XOHCL iBar; + bool isInited = GetBar(iBar, i); + + // + double iPeak = mX121Helper.GetPeak(i); + double iVale = mX121Helper.GetVale(i); + + // + bool hasPeakPriceInsideZone = CalculatePriceInsideZones( + peakPriceZone, + state, + iPeak // + ); + bool hasValePriceInsideZone = CalculatePriceInsideZones( + valePriceZone, + state, + iVale // + ); + + // + if (hasPeakPriceInsideZone) + { + // + // Peak ... + if (!iPeakPoint.IsValid()) + { + // + // Initialization ... + iPeakPoint.value = iPeak; + iPeakPoint.repetition = 1; + iPeakPoint.type = XPV_PEAK; + iPeakPoint.time = iBar.time; + } + else + { + // + if (iPeakPoint.value == iPeak) + { + iPeakPoint.repetition++; + } + else + { + // + if (iPeakPoint.repetition > minRepetition) + { + // + AddRef( + iPeakPoint, + model.peaks // + ); + + // + AddRef( + peakPriceZone, + model.peakPriceZones // + ); + } + + // + iPeakPoint.Clean(); + peakPriceZone.Clean(); + iPeakPoint.value = iPeak; + iPeakPoint.repetition = 1; + iPeakPoint.type = XPV_PEAK; + iPeakPoint.time = iBar.time; + } + } + } + + // + if (hasValePriceInsideZone) + { + // + // Vale ... + if (!iValePoint.IsValid()) + { + // + // Initialization ... + iValePoint.value = iVale; + iValePoint.repetition = 1; + iValePoint.type = XPV_VALE; + iValePoint.time = iBar.time; + } + else + { + // + if (iValePoint.value == iVale) + { + iValePoint.repetition++; + } + else + { + // + if (iValePoint.repetition > minRepetition) + { + // + AddRef( + iValePoint, + model.vales // + ); + + // + AddRef( + valePriceZone, + model.valePriceZones // + ); + } + + // + iValePoint.Clean(); + valePriceZone.Clean(); + iValePoint.value = iVale; + iValePoint.repetition = 1; + iValePoint.type = XPV_VALE; + iValePoint.time = iBar.time; + } + } + } + } + + // + // in Bullish Bias we Looking for Vales Oder ... + // in Bearish Bias we Looking for Peaks Oder ... + + // + // Bullish Bias Drawn ... + if (isBullish) + { + // + result = GetBar( + model.lowestValeBar, + lowestValeIndex // + ); + if (!result) + { + return result; + } + + // + if (isValidBreakeUpLowestValePeak) + { + // + result = GetBar( + model.lowestValePeakBreakeUpBar, + lowestValePeakBreakeUpIndex // + ); + if (!result) + { + return result; + } + } + + // + if (isValidValeAboveLowestValePeak) + { + // + result = GetBar( + model.valeAboveLowestValePeakBar, + valeAboveLowestValePeakIndex // + ); + if (!result) + { + return result; + } + } + } + + // + // Bearish Bias Drawn ... + if (!isBullish) + { + // + result = GetBar( + model.highestPeakBar, + highestPeakIndex // + ); + if (!result) + { + return result; + } + + // + if (isValidBreakeDownHighestPeakVale) + { + // + result = GetBar( + model.highestPeakValeBreakeDownBar, + highestPeakValeBreakeDownIndex // + ); + if (!result) + { + return result; + } + } + + // + if (isValidPeakBelowHighestPeakVale) + { + // + result = GetBar( + model.peakBelowHighestPeakValeBar, + peakBelowHighestPeakValeIndex // + ); + if (!result) + { + return result; + } + } + } + + // + result = model.IsValid(); + + // + return result; + } + + // + // Tools ... + + /** + * 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; + } + + /** + * Validate Specified Pivot's State ... + * + * @param pivot: XPVPivot instance Reference ... + * @param barIndex: Integer ... + */ + void ValidatePivotState( + XPVPivot &pivot, + int barIndex = 0 // + ) + { + // + if (!pivot.IsValid() || + !pivot.state.IsValid() || + !pivot.state.HasChild()) + { + return; + } + + // + double upperr = pivot.upper; + double lower = pivot.lower; + + // + XOHCL cBar; + bool isInited = cBar.Init( + pivot.symbol, + pivot.period, + barIndex // + ); + if (!isInited) + { + return; + } + + // + int count = 0; + + // + double ask = GetAsk(pivot.symbol); + double bid = GetBid(pivot.symbol); + + // + double pivotMid = pivot.CalculateMid(); + + // + // Try to Validate States ... + + // + bool isPriceInPremium = + // + ask > pivotMid && + bid > pivotMid && + cBar.low > pivotMid + // + ; + + // + bool isPriceInDiscount = + // + ask < pivotMid && + bid < pivotMid && + cBar.high < pivotMid + // + ; + + // + // Swings ... + XCSwing *tmpSwings[]; + + // + // Swing Highs ... + Clean(tmpSwings); + count = pivot.state.CountSwingHighs(); + if (IsValidSize(count)) + { + // + if (isPriceInPremium) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = pivot.state.swingHighs[i]; + + // + bool isValid = + // + iSwing.GetTime() >= pivot.from && + iSwing.GetTime() <= pivot.to && + iSwing.GetValue() > pivotMid + // + ; + if (isValid) + { + // + Add( + iSwing, + tmpSwings // + ); + } + } + + // + Copy( + tmpSwings, + pivot.state.swingHighs // + ); + } + } + + // + // Swing Lows ... + Clean(tmpSwings); + count = pivot.state.CountSwingLows(); + if (IsValidSize(count)) + { + // + if (isPriceInDiscount) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = pivot.state.swingLows[i]; + + // + bool isValid = + // + iSwing.GetTime() >= pivot.from && + iSwing.GetTime() <= pivot.to && + iSwing.GetValue() < pivotMid + // + ; + if (isValid) + { + // + Add( + iSwing, + tmpSwings // + ); + } + } + + // + Copy( + tmpSwings, + pivot.state.swingLows // + ); + } + } + + // + Clean(tmpSwings); + + // + // Rejection Bars ... + XCRejectionBar *tmpRejections[]; + + // + // Bullish ... + Clean(tmpRejections); + count = pivot.state.CountBullishRejectionBars(); + if (IsValidSize(count)) + { + // + if (isPriceInDiscount) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = pivot.state.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isValid = + // + iRejection.BarTime() >= pivot.from && + iBar.high < pivotMid + // + ; + if (isValid) + { + // + Add( + iRejection, + tmpRejections // + ); + } + } + + // + Copy( + tmpRejections, + pivot.state.bullishRejectionBars // + ); + } + } + + // + // Bearish ... + Clean(tmpRejections); + count = pivot.state.CountBearishRejectionBars(); + if (IsValidSize(count)) + { + // + if (isPriceInPremium) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = pivot.state.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isValid = + // + iRejection.BarTime() >= pivot.from && + iBar.low > pivotMid + // + ; + if (isValid) + { + // + Add( + iRejection, + tmpRejections // + ); + } + } + + // + Copy( + tmpRejections, + pivot.state.bearishRejectionBars // + ); + } + } + + // + Clean(tmpRejections); + + // + // Support Zone ... + XCSupportZone *tmpSupports[]; + count = pivot.state.CountSupportZones(); + if (IsValidSize(count)) + { + // + if (isPriceInDiscount) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = pivot.state.supportZones[i]; + + // + bool isValid = + // + iZone.Upper() < pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpSupports // + ); + } + } + + // + Copy( + tmpSupports, + pivot.state.supportZones // + ); + } + } + + // + Clean(tmpSupports); + + // + // Resistance Zone ... + XCResistanceZone *tmpResistances[]; + count = pivot.state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + if (isPriceInPremium) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = pivot.state.resistanceZones[i]; + + // + bool isValid = + // + iZone.Lower() > pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpResistances // + ); + } + } + + // + Copy( + tmpResistances, + pivot.state.resistanceZones // + ); + } + } + + // + Clean(tmpResistances); + + // + // Supply Zones ... + XCSupplyZone *tmpSupplies[]; + count = pivot.state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + if (isPriceInPremium) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = pivot.state.supplyZones[i]; + + // + bool isValid = + // + iZone.Lower() > pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpSupplies // + ); + } + } + + // + Copy( + tmpSupplies, + pivot.state.supplyZones // + ); + } + } + + // + Clean(tmpSupplies); + + // + // Demand Zones ... + XCDemandZone *tmpDemands[]; + count = pivot.state.CountDemandZones(); + if (IsValidSize(count)) + { + // + if (isPriceInDiscount) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = pivot.state.demandZones[i]; + + // + bool isValid = + // + iZone.Upper() < pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpDemands // + ); + } + } + + // + Copy( + tmpDemands, + pivot.state.demandZones // + ); + } + } + + // + Clean(tmpDemands); + + // + // Order Blocks ... + XCOrderBlock *tmpOrderBlocks[]; + + // + // Bullish ... + Clean(tmpOrderBlocks); + count = pivot.state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + if (isPriceInDiscount) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = pivot.state.bullishOrderBlocks[i]; + + // + bool isValid = + // + iZone.Upper() < pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpOrderBlocks // + ); + } + } + + // + Copy( + tmpOrderBlocks, + pivot.state.bullishOrderBlocks // + ); + } + } + + // + // Bearish ... + Clean(tmpOrderBlocks); + count = pivot.state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + if (isPriceInPremium) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = pivot.state.bearishOrderBlocks[i]; + + // + bool isValid = + // + iZone.Lower() > pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpOrderBlocks // + ); + } + } + + // + Copy( + tmpOrderBlocks, + pivot.state.bearishOrderBlocks // + ); + } + } + + // + Clean(tmpOrderBlocks); + + // + // Fair Value Gaps ... + XCFVG *tmpFVGs[]; + + // + // Bullish ... + Clean(tmpFVGs); + count = pivot.state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + if (isPriceInDiscount) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = pivot.state.bullishFairValueGaps[i]; + + // + bool isValid = + // + iZone.Upper() < pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpFVGs // + ); + } + } + + // + Copy( + tmpFVGs, + pivot.state.bullishFairValueGaps // + ); + } + } + + // + // Bearish ... + Clean(tmpFVGs); + count = pivot.state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + if (isPriceInPremium) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = pivot.state.bearishFairValueGaps[i]; + + // + bool isValid = + // + iZone.Lower() > pivotMid + // + ; + if (isValid) + { + // + Add( + iZone, + tmpFVGs // + ); + } + } + + // + Copy( + tmpFVGs, + pivot.state.bearishFairValueGaps // + ); + } + } + + // + Clean(tmpFVGs); + + // + } + + /** + * Detect Cycle Trend Based On Pivots ... + * + * @param dir: ENUM_X_DIRECTION member Reference ... + * @param numberOfPivots: Integer ... + * @param maxAllowedLoopback: Integer ... + * @param minRequiredPivotVerification: Integer ... + * + * @return ( bool ) + */ + bool DetectTrend( + ENUM_X_DIRECTION &dir, + int numberOfPivots = 3, + int maxAllowedLoopback = 576, + int minRequiredPivotVerification = 5 // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + if (numberOfPivots < 3) + { + numberOfPivots = 3; + } + + // + int index = 0; + double peaks[]; + double vales[]; + double peak = 0; + double vale = 0; + int peaksVerified = 0; + int valesVerified = 0; + bool canContinue = true; + while (canContinue) + { + // + // Peak ... + bool lookupPeak = ArraySize(peaks) < numberOfPivots; + if (lookupPeak) + { + // + double iPeak = mX121Helper.GetPeak(index); + if (iPeak == peak) + { + peaksVerified++; + } + else + { + // + if (peaksVerified >= minRequiredPivotVerification) + { + // + Add( + iPeak, + peaks // + ); + + // + peaksVerified = 0; + lookupPeak = ArraySize(peaks) < numberOfPivots; + } + else + { + peak = iPeak; + } + } + } + + // + // Vale ... + bool lookupVale = ArraySize(vales) < numberOfPivots; + if (lookupVale) + { + // + double iVale = mX121Helper.GetVale(index); + if (iVale == vale) + { + valesVerified++; + } + else + { + // + if (valesVerified >= minRequiredPivotVerification) + { + // + Add( + iVale, + vales // + ); + + // + valesVerified = 0; + lookupVale = ArraySize(vales) < numberOfPivots; + } + else + { + vale = iVale; + } + } + } + + // + canContinue = index < maxAllowedLoopback && + (lookupPeak || + lookupVale); + if (canContinue) + { + index++; + } + } + + // + int verifications = 0; + + // + // Peaks ... + int peaksCount = ArraySize(peaks); + if (!result && + peaksCount == numberOfPivots) + { + // + verifications = 0; + for (int i = 0; i < peaksCount - 1; i++) + { + // + double iValue = peaks[i]; + double nValue = peaks[i + 1]; + if (iValue < nValue) + { + verifications++; + } + } + + // + result = verifications == numberOfPivots - 1; + if (result) + { + dir = X_DIRECTION_BEARISH; + } + } + + // + // Vales ... + int valesCount = ArraySize(vales); + if (!result && + valesCount == numberOfPivots) + { + // + verifications = 0; + for (int i = 0; i < valesCount - 1; i++) + { + // + double iValue = vales[i]; + double nValue = vales[i + 1]; + if (iValue > nValue) + { + verifications++; + } + } + + // + result = verifications == numberOfPivots - 1; + if (result) + { + dir = X_DIRECTION_BULLISH; + } + } + + // + return result; + } + + /** + * Detect Market Structure based on Peaks and Vales ... + * + * @param dir: ENUM_X_DIRECTION member Reference ... + * @param minVerification: Integer ... + * + * @return ( bool ) + */ + bool HasPVDirection( + ENUM_X_DIRECTION &dir, + int minVerification = 12 // + ) + { + // + bool result = false; + + // + if (minVerification < 7) + { + minVerification = 7; + } + + // + dir = X_DIRECTION_NONE; + + // + int bullishSum = mBullishPeaks + mBullishVales; + int bearishSum = mBearishPeaks + mBearishVales; + + // + int diff = MathAbs(bullishSum - bearishSum); + bool isDiffPassed = diff >= minVerification; + result = isDiffPassed; + if (!result) + { + return result; + } + + // + dir = bullishSum > bearishSum + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + 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 FillPivotPoints(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; + } + + /** + * Get Last Peaks Pivot Point ... + * + * @param pivot: XPVPivotPoint instance Reference ... + * + * @return ( bool ) + */ + bool GetLastPeakPivotPoint(XPVPivotPoint &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + XPVPivotPoint pivots[]; + int count = FillPeakPivotPoints(pivots); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + pivot = pivots[count - 1]; + + // + 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 Last Vale Pivot Point ... + * + * @param pivot: XPVPivotPoint instance Reference ... + * + * @return ( bool ) + */ + bool GetLastValePivotPoint(XPVPivotPoint &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + XPVPivotPoint pivots[]; + int count = FillValePivotPoints(pivots); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + pivot = pivots[count - 1]; + + // + return result; + } + + /** + * 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; + } + + /** + * Retrieve Last Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool GetLastPivot(XPVPivot &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + XPVPivot pivots[]; + int count = FillPivots(pivots); + if (IsValidSize(count)) + { + pivot = pivots[count - 1]; + } + + // + result = pivot.IsValid(); + + // + return result; + } + + /** + * Retrieve Active Peak Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool GetActivePeakPivot(XPVPivot &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + pivot = mActivePeakPivot; + + // + result = pivot.IsValid(); + + // + return result; + } + + /** + * Retrieve Active Vale Pivot ... + * + * @param pivot: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool GetActiveValePivot(XPVPivot &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + pivot = mActiveValePivot; + + // + result = pivot.IsValid(); + + // + return result; + } + + // + // Virtuals ... + + /** + * Set Default Properties Values ... + */ + virtual void Default() + { + // + ValidPivotRepetition(21); + 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); + + // + if (isInited) + { + // + Add( + SAR_CHANGE_DETECTED, + events // + ); + } + } + } + + // + // Detect Peaks Changes ... + + // + bool isNewPeak = conditions.x121Conditions.isNewPeak; + double peak = conditions.x121Conditions.peaksBuffer[1]; + double peakPrev = conditions.x121Conditions.peaksBuffer[2]; + bool isPeakSameAsPrev = peak == peakPrev; + 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); + + // + if (isInited) + { + // + Add( + NEW_PEAK_DETECTED, + events // + ); + } + } + } + + // + // Detect Vales Changes ... + + // + bool isNewVale = conditions.x121Conditions.isNewVale; + double vale = conditions.x121Conditions.valesBuffer[1]; + double valePrev = conditions.x121Conditions.valesBuffer[2]; + bool isValeSameAsPrev = vale == valePrev; + 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); + + // + if (isInited) + { + // + Add( + NEW_VALE_DETECTED, + events // + ); + } + } + } + + // + // Count Bullish / Bearish Peaks and Vales ... + + // + // Peaks ... + + // + if (isNewPeakOverLast) + { + // + mBullishPeaks++; + mIsLastPeakBullish = true; + } + + // + if (isNewPeakUnderLast) + { + // + mBearishPeaks++; + mIsLastPeakBullish = false; + } + + // + if (isPeakSameAsPrev) + { + // + if (mIsLastPeakBullish) + { + // + mBullishPeaks++; + mBearishPeaks--; + if (mBearishPeaks < 0) + { + mBearishPeaks = 0; + } + } + else + { + // + mBullishPeaks--; + mBearishPeaks++; + if (mBullishPeaks < 0) + { + mBullishPeaks = 0; + } + } + } + + // + // Vales ... + + // + if (isNewValeOverLast) + { + // + mBullishVales++; + mIsLastValeBullish = true; + } + + // + if (isNewValeUnderLast) + { + // + mBearishVales++; + mIsLastValeBullish = false; + } + + // + if (isValeSameAsPrev) + { + // + if (mIsLastValeBullish) + { + // + mBullishVales++; + mBearishVales--; + if (mBearishVales < 0) + { + mBearishVales = 0; + } + } + else + { + // + mBullishVales--; + mBearishVales++; + if (mBullishVales < 0) + { + mBullishVales = 0; + } + } + } + + // + // 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); + + // + if (isInited) + { + // + 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); + + // + if (isInited) + { + // + 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 && + !mActiveConsolidationZone.IsValid()) + { + // + // Initialize Consolidation Zone ... + bool isInited = mActiveConsolidationZone.Init( + changeBar.symbol, + changeBar.period, + upper, + lower, + consolidationLoopback // + ); + } + + // + if (!hasConsolidation && + mActiveConsolidationZone.IsValid()) + { + // + mActiveConsolidationZone.Update(); + bool isBreaked = mActiveConsolidationZone.IsBreaked(); + + // + if (isBreaked) + { + // + // Add Active to List ... + bool isInited = AddConsolidationZone(mActiveConsolidationZone); + if (isInited) + { + // + // Clean Active Zone ... + mActiveConsolidationZone.Clean(); + + // + Add( + CONSOLIDATION_BREAKED_DETECTED, + events // + ); + } + } + } + + // + // Draw ... + // if (mActiveConsolidationZone.IsValid()) + // { + // // + // if (mActiveConsolidationZoneObj != NULL) + // { + // mActiveConsolidationZoneObj.Delete(); + // } + + // // + // bool isCreated = mPOIDetector.mDrawer.CreateConsolidationZone( + // mActiveConsolidationZone, + // mActiveConsolidationZoneObj // + // ); + // } + } + + // + // 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 = ValidPivotRepetition(); + 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; + + // + bool isInited = AddPivotPoint(pivotPoint); + if (isInited) + { + // + Add( + PIVOT_POINT_DETECTED, + events // + ); + } + } + } + } + + // + // Calculate XPVPivot ... + int pvValidation = ValidPivotRepetition(); + if (IsValidSize(pvValidation)) + { + // + // Peak ... + mActivePeakPivot.symbol = symbol; + mActivePeakPivot.period = period; + mActivePeakPivot.type = XPV_PEAK; + + // + if (mActivePeakPivot.upper == 0 && peak > 0) + { + // + mActivePeakPivot.upper = peak; + mActivePeakPivot.lower = vale; + mActivePeakPivot.from = changeBar.time; + + // + Add( + PEAK_PIVOT_STARTED, + events // + ); + } + else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper == peak) + { + // + mActivePeakPivot.repetition++; + mActivePeakPivot.to = changeBar.time; + + // + if (mActivePeakPivot.IsValid()) + { + // + FillPivotState(mActivePeakPivot); + ValidatePivotState(mActivePeakPivot, barIndex); + } + } + else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper != peak) + { + // + if (mActivePeakPivot.repetition >= pvValidation) + { + // + bool isInited = AddPivot(mActivePeakPivot); + if (isInited) + { + // + Add( + PEAK_PIVOT_ENDED, + events // + ); + + // + mActivePeakPivot.Clean(); + } + } + else + { + // + mActivePeakPivot.upper = peak; + mActivePeakPivot.lower = vale; + mActivePeakPivot.repetition = 0; + mActivePeakPivot.from = changeBar.time; + + // + Add( + PEAK_PIVOT_STARTED, + events // + ); + } + } + + // + // Vale ... + mActiveValePivot.symbol = symbol; + mActiveValePivot.period = period; + mActiveValePivot.type = XPV_VALE; + + // + // Peak ... + if (mActiveValePivot.lower == 0 && vale > 0) + { + // + mActiveValePivot.lower = vale; + mActiveValePivot.upper = peak; + mActiveValePivot.from = changeBar.time; + + // + Add( + VALE_PIVOT_STARTED, + events // + ); + } + else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower == vale) + { + // + mActiveValePivot.repetition++; + mActiveValePivot.to = changeBar.time; + + // + if (mActiveValePivot.IsValid()) + { + // + FillPivotState(mActiveValePivot); + ValidatePivotState(mActiveValePivot, barIndex); + } + } + else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower != vale) + { + // + if (mActiveValePivot.repetition >= pvValidation) + { + // + bool isInited = AddPivot(mActiveValePivot); + if (isInited) + { + // + Add( + VALE_PIVOT_ENDED, + events // + ); + + // + mActiveValePivot.Clean(); + } + } + else + { + // + mActiveValePivot.lower = vale; + mActiveValePivot.upper = peak; + mActiveValePivot.repetition = 0; + mActiveValePivot.from = changeBar.time; + + // + Add( + VALE_PIVOT_STARTED, + events // + ); + } + } + } + } + + /** + * Detect Requirements ... + */ + void Detect(int barIndex) + { + // + if (isDetecting) + { + return; + } + + // + int start = barIndex; + int max = 576; + int validPivotRepetition = ValidPivotRepetition(); + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + // Try To Detect Valid Peaks or Vales ... + double peak = 0; + double vale = 0; + int peakRepetition = 0; + int valeRepetition = 0; + + // + int from = start; + int index = from; + int count = start + max; + + // + bool canContinue = true; + + // + // Loop Throug Peaks and Vales ... + while (canContinue) + { + // + datetime toTime = iTime( + symbol, + period, + index // + ); + + // + double iPeak = mX121Helper.GetPeak(index); + double iVale = mX121Helper.GetVale(index); + + // + // Peak ... + if (peak == 0 && iPeak > 0) + { + // + peak = iPeak; + peakRepetition = 0; + } + else if (peak > 0 && iPeak > 0 && peak == iPeak) + { + peakRepetition++; + } + else if (peak > 0 && iPeak > 0 && peak != iPeak) + { + // + if (peakRepetition >= validPivotRepetition) + { + // + datetime fromTime = iTime( + symbol, + period, + index - peakRepetition // + ); + + // + // Create XPVPivotPoint ... + XPVPivotPoint pivotPoint; + pivotPoint.value = iPeak; + pivotPoint.time = toTime; + pivotPoint.type = XPV_PEAK; + pivotPoint.repetition = peakRepetition; + if (pivotPoint.IsValid()) + { + // + AddRef( + pivotPoint, + mPivotPoints // + ); + } + + // + // Create XPVPivot ... + XPVPivot pivot; + pivot.symbol = symbol; + pivot.period = period; + pivot.from = fromTime; + pivot.to = toTime; + pivot.repetition = peakRepetition; + pivot.type = XPV_PEAK; + pivot.upper = peak; + pivot.lower = iVale; + FillPivotState(pivot); + + // + if (pivot.IsValid()) + { + // + AddRef( + pivot, + mPivots // + ); + } + } + + // + peak = iPeak; + peakRepetition = 0; + } + + // + // Vale ... + if (vale == 0 && iVale > 0) + { + // + vale = iVale; + valeRepetition = 0; + } + else if (vale > 0 && iVale > 0 && vale == iVale) + { + valeRepetition++; + } + else if (vale > 0 && iVale > 0 && vale != iVale) + { + // + if (valeRepetition >= validPivotRepetition) + { + // + datetime fromTime = iTime( + symbol, + period, + index - valeRepetition // + ); + + // + // Create XPVPivotPoint ... + XPVPivotPoint pivotPoint; + pivotPoint.value = iVale; + pivotPoint.time = toTime; + pivotPoint.type = XPV_VALE; + pivotPoint.repetition = valeRepetition; + if (pivotPoint.IsValid()) + { + // + AddRef( + pivotPoint, + mPivotPoints // + ); + } + + // + // Create XPVPivot ... + XPVPivot pivot; + pivot.symbol = symbol; + pivot.period = period; + pivot.from = fromTime; + pivot.to = toTime; + pivot.repetition = valeRepetition; + pivot.type = XPV_VALE; + pivot.upper = iPeak; + pivot.lower = vale; + FillPivotState(pivot); + + // + if (pivot.IsValid()) + { + // + AddRef( + pivot, + mPivots // + ); + } + } + + // + vale = iVale; + valeRepetition = 0; + } + + // + index++; + canContinue = index < count; + } + + // + int pivotsCount = ArraySize(mPivots); + if (IsValidSize(mPivots)) + { + ArrayReverse(mPivots); + } + + // + isDetecting = false; + } + + // + private: + // + // Props ... + + // + bool mIsLastPeakBullish; + int mBullishPeaks; // Count Bullish Peaks ... + int mBearishPeaks; // Count Bearish Peaks ... + + // + bool mIsLastValeBullish; + int mBullishVales; // Count Bullish Vales ... + int mBearishVales; // Count Bearish Vales ... + + // + // 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 mActiveConsolidationZone; // Holds Actiove Consolidation Zone ... + // XCConsolidationZoneObject *mActiveConsolidationZoneObj; + + // + int mValidPivotRepetition; // Valid Pivot Point's Repetition ... + XPVPivotPoint mPivotPoints[]; // Holds Pivots ... + + // + bool isDetecting; + XPVPivot mActivePeakPivot; // Active Pivots ... + XPVPivot mActiveValePivot; // Active Pivots ... + XPVPivot mPivots[]; // Holds Active Pivot ... + + // + // 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; + } + + /** + * Add Specified Consolidation Zone to List ... + * + * @param zone: XConsolidationZone instance Reference ... + * + * @return ( bool ) + */ + bool AddConsolidationZone(XConsolidationZone &zone) + { + // + bool result = false; + + // + result = zone.IsValid(); + + // + int beforeCount = CountConsolidationZones(); + + // + AddRef( + zone, + mConsolidationZones // + ); + + // + int afterCount = CountConsolidationZones(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mConsolidationZones, + maxAllowed // + ); + } + + // + return result; + } + + /** + * Add Specified Pivot Point to List ... + * + * @param pivotPoint: XPVPivotPoint instance Reference ... + * + * @return ( bool ) + */ + bool AddPivotPoint(XPVPivotPoint &pivotPoint) + { + // + bool result = false; + + // + if (!pivotPoint.IsValid()) + { + return result; + } + + // + int beforeCount = CountPivotPoints(); + + // + AddRef( + pivotPoint, + mPivotPoints // + ); + + // + int afterCount = CountPivotPoints(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mPivotPoints, + maxAllowed // + ); + } + + // + return result; + } + + /** + * Add Specified Pivot to List ... + * + * @param pivot: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool AddPivot(XPVPivot &pivot) + { + // + bool result = false; + + // + if (!pivot.IsValid()) + { + return result; + } + + // + int beforeCount = CountPivots(); + + // + AddRef( + pivot, + mPivots // + ); + + // + int afterCount = CountPivots(); + + // + result = afterCount == beforeCount + 1; + if (result) + { + // + // Cleaning Up Unused Items ... + int maxAllowed = MaxAllowedSavedChanges(); + CleanupArray( + mPivots, + maxAllowed // + ); + } + + // + return result; + } + + // +}; diff --git a/Documents/BKP/1/x-121.smc.xtwpv.old.1.signal.lib.mq5 b/Documents/BKP/1/x-121.smc.xtwpv.old.1.signal.lib.mq5 new file mode 100644 index 00000000..55fb83e4 --- /dev/null +++ b/Documents/BKP/1/x-121.smc.xtwpv.old.1.signal.lib.mq5 @@ -0,0 +1,1420 @@ +/////////////////////////////////////////////////////// +// +// 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" + +// // +// const string X121SMCXTWPV_Method_1_Token = "X121SMCXTWPV_1"; +// const string X121SMCXTWPV_Method_2_Token = "X121SMCXTWPV_2"; +// const string X121SMCXTWPV_Method_3_Token = "X121SMCXTWPV_3"; + +// // +// enum ENUM_X_X121SMC_XTWPV_METHODS +// { +// X_X121SMC_XTWPV_METHOD_UNKNOWN, +// X_X121SMC_XTWPV_METHOD_1, +// X_X121SMC_XTWPV_METHOD_2, +// X_X121SMC_XTWPV_METHOD_3, +// }; + +// // +// string ToString(ENUM_X_X121SMC_XTWPV_METHODS value) +// { +// // +// string result = NULL; + +// // +// if (value == X_X121SMC_XTWPV_METHOD_UNKNOWN) +// { +// return result; +// } + +// // +// switch (value) +// { +// // +// case X_X121SMC_XTWPV_METHOD_1: +// result = "Method_1"; +// break; + +// // +// case X_X121SMC_XTWPV_METHOD_2: +// result = "Method_2"; +// break; +// } + +// // +// return result; +// } + +// // +// ENUM_X_X121SMC_XTWPV_METHODS ParseMethod(string value) +// { +// // +// ENUM_X_X121SMC_XTWPV_METHODS result = X_X121SMC_XTWPV_METHOD_UNKNOWN; + +// // +// if (!IsValid(value)) +// { +// return result; +// } + +// // +// if (Contains(X121SMCXTWPV_Method_1_Token, value)) +// { +// result = X_X121SMC_XTWPV_METHOD_1; +// } +// else if (Contains(X121SMCXTWPV_Method_2_Token, value)) +// { +// result = X_X121SMC_XTWPV_METHOD_2; +// } + +// // +// return result; +// } + +// +// Definitions ... +struct X121SMCStrategyXTWPVSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + XMarketStructure consolidationMarketStructure; + XMarketStructure analyseMarketStructure; + + // + datetime newPeakAboveAtrUpperAt; + datetime newValeBelowAtrLowerAt; + datetime sarSiwtchedToBullishAt; + datetime sarSiwtchedToBearishAt; + datetime rsiCrossedOverOverSoldAt; + datetime rsiCrossedUnderOverBoughtAt; + + // + XPriceZones decisionZone; + XPriceZones peakPriceZone; + XPriceZones valePriceZone; + + // + // Constructor ... + X121SMCStrategyXTWPVSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + decisionZone.Clean(); + peakPriceZone.Clean(); + valePriceZone.Clean(); + + // + analyseMarketStructure.Clean(); + consolidationMarketStructure.Clean(); + + // + newPeakAboveAtrUpperAt = NULL; + newValeBelowAtrLowerAt = NULL; + sarSiwtchedToBullishAt = NULL; + sarSiwtchedToBearishAt = NULL; + rsiCrossedOverOverSoldAt = NULL; + rsiCrossedUnderOverBoughtAt = NULL; + } + + /** + * Check Required Market Strucutre Exists or not ... + * + * @return ( bool ) + */ + bool HasMarketStrucutre() + { + // + bool result = false; + + // + result = + // + analyseMarketStructure.IsValid() && + consolidationMarketStructure.IsValid() + // + && + // + analyseMarketStructure.HasTrend() && + consolidationMarketStructure.HasTrend() + // + && + // + analyseMarketStructure.bias == consolidationMarketStructure.bias + // + ; + + // + return result; + } + + /** + * Check if Conditions Filled ... + * + * @return ( bool ) + */ + bool IsFilled() + { + // + bool result = false; + + // + result = HasMarketStrucutre(); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(analyseMarketStructure.bias); + + // + result = + isBullish + ? IsValid(newValeBelowAtrLowerAt) && + IsValid(sarSiwtchedToBullishAt) && + IsValid(rsiCrossedOverOverSoldAt) + : IsValid(newPeakAboveAtrUpperAt) && + IsValid(sarSiwtchedToBearishAt) && + IsValid(rsiCrossedUnderOverBoughtAt); + + // + return result; + } + + /** + * Check if Has Price Zones ... + * + * @return ( bool ) + */ + bool HasPriceZone() + { + // + bool result = false; + + // + result = HasMarketStrucutre(); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(analyseMarketStructure.bias); + + // + result = + isBullish + ? valePriceZone.IsValid() + : peakPriceZone.IsValid(); + + // + return result; + } + + /** + * Check if Has Decision Zones ... + * + * @return ( bool ) + */ + bool HasDecisionZone() + { + return HasPriceZone() && + decisionZone.IsValid(); + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXTWPVSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXTWPVSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + bool hasMarketStructure = conditions.HasMarketStrucutre(); + if (!hasMarketStructure) + { + // + bool hasConsolidationMarketStructure = + consolidationCycleHelper + .DetectMarketStructure(conditions.consolidationMarketStructure); + + // + bool hasAnalyseMarketStructure = + analyseCycleHelper + .DetectMarketStructure(conditions.analyseMarketStructure); + + // + hasMarketStructure = conditions.HasMarketStrucutre(); + result = hasMarketStructure; + if (!result) + { + return result; + } + } + + // + // We Are Sure we Have Direct Structure Bias ... + isBullish = IsBullish(conditions.analyseMarketStructure.bias); + isBearish = IsBearish(conditions.analyseMarketStructure.bias); + + // + // RSI ... + double rsi = triggerConditions.x121Conditions.rsiBuffer[1]; + + // + bool isRSICrossedOverOverBought = triggerConditions.x121Conditions.isRSICrossedOverOverBought; + bool isRSICrossedUnderOverBought = triggerConditions.x121Conditions.isRSICrossedUnderOverBought; + + // + bool isRSICrossedOverOverSold = triggerConditions.x121Conditions.isRSICrossedOverOverSold; + bool isRSICrossedUnderOverSold = triggerConditions.x121Conditions.isRSICrossedUnderOverSold; + + // + // PV ... + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + + // + // ATR ... + double atr = triggerConditions.x121Conditions.atrBuffer[1]; + double atrUpper = triggerConditions.x121Conditions.atrUpperBuffer[1]; + double atrLower = triggerConditions.x121Conditions.atrLowerBuffer[1]; + + // + // SAR ... + double sar = triggerConditions.x121Conditions.sarBuffer[1]; + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + // Complex Conditions ... + + // + bool isNewPeakAboveAtrUpper = + isNewPeak && + peak > atrUpper; + + // + bool isNewValeBelowAtrLower = + isNewVale && + vale < atrLower; + + // + // Fill Conditions ... + bool isConditionsFilled = conditions.IsFilled(); + if (!isConditionsFilled) + { + // + // Cleanup ... + + // + // Sar ... + + // + // Bullish ... + if (isBullish && + isSarSwitchedToBearish && + IsValid(conditions.sarSiwtchedToBullishAt)) + { + conditions.sarSiwtchedToBullishAt = NULL; + } + + // + // Bearish ... + if (isBearish && + isSarSwitchedToBullish && + IsValid(conditions.sarSiwtchedToBearishAt)) + { + conditions.sarSiwtchedToBearishAt = NULL; + } + + // + // Rsi ... + + // + // Bullish ... + if (isBullish && + isRSICrossedUnderOverSold && + IsValid(conditions.rsiCrossedOverOverSoldAt)) + { + conditions.rsiCrossedOverOverSoldAt = NULL; + } + + // + // Bearish ... + if (isBearish && + isRSICrossedOverOverBought && + IsValid(conditions.rsiCrossedUnderOverBoughtAt)) + { + conditions.rsiCrossedUnderOverBoughtAt = NULL; + } + + // + // Atr Change ... + + // + // Bullish ... + if (isBullish && + isNewPeak && + IsValid(conditions.newValeBelowAtrLowerAt)) + { + conditions.newValeBelowAtrLowerAt = NULL; + } + + // + // Bearish ... + if (isBearish && + isNewVale && + IsValid(conditions.newPeakAboveAtrUpperAt)) + { + conditions.newPeakAboveAtrUpperAt = NULL; + } + + // + // Filling Up ... + + // + // Sar Change ... + + // + // Bullish ... + if (isBullish && + isSarSwitchedToBullish && + !IsValid(conditions.sarSiwtchedToBullishAt)) + { + conditions.sarSiwtchedToBullishAt = cTime; + } + + // + // Bearish ... + if (isBearish && + isSarSwitchedToBearish && + !IsValid(conditions.sarSiwtchedToBearishAt)) + { + conditions.sarSiwtchedToBearishAt = cTime; + } + + // + // Rsi Change ... + + // + // Bullish ... + if (isBullish && + isRSICrossedOverOverSold && + !IsValid(conditions.rsiCrossedOverOverSoldAt)) + { + conditions.rsiCrossedOverOverSoldAt = cTime; + } + + // + // Bearish ... + if (isBearish && + isRSICrossedUnderOverBought && + !IsValid(conditions.rsiCrossedUnderOverBoughtAt)) + { + conditions.rsiCrossedUnderOverBoughtAt = cTime; + } + + // + // Atr Change ... + // New Peaks and Vale ... + + // + // Bullish ... + if (isBullish && + isNewValeBelowAtrLower && + !IsValid(conditions.newValeBelowAtrLowerAt)) + { + conditions.newValeBelowAtrLowerAt = cTime; + } + + // + // Bearish ... + if (isBearish && + isNewPeakAboveAtrUpper && + !IsValid(conditions.newPeakAboveAtrUpperAt)) + { + conditions.newPeakAboveAtrUpperAt = cTime; + } + + // + isConditionsFilled = conditions.IsFilled(); + result = isConditionsFilled; + if (!result) + { + return result; + } + } + + // + // Fill Price Zones ... + bool hasPriceZone = conditions.HasPriceZone(); + if (!hasPriceZone) + { + // + if (isBullish) + { + // + XPriceZones vPZone; + bool hasValeInsideZone = CalculatePriceInsideZones( + vPZone, + analyseState, + vale // + ); + + // + XPriceZones cbPZone; + bool hasPriceInsideZone = CalculatePriceInsideZones( + cbPZone, + analyseState, + cBar // + ); + + // + if (hasValeInsideZone && + hasPriceInsideZone && + vPZone.IsBullish() && + cbPZone.IsBullish()) + { + conditions.valePriceZone = cbPZone; + } + } + else if (isBearish) + { + // + XPriceZones pPZone; + bool hasPeakInsideZone = CalculatePriceInsideZones( + pPZone, + analyseState, + peak // + ); + + // + XPriceZones cbPZone; + bool hasPriceInsideZone = CalculatePriceInsideZones( + cbPZone, + analyseState, + cBar // + ); + + // + if ( + hasPeakInsideZone && + hasPriceInsideZone && + pPZone.IsBearish() && + cbPZone.IsBearish()) + { + conditions.peakPriceZone = cbPZone; + } + } + + // + hasPriceZone = conditions.HasPriceZone(); + result = hasPriceZone; + if (!result) + { + return result; + } + } + + // + // Check for Decision ... + bool hasDecision = conditions.HasDecisionZone(); + if (!hasDecision) + { + // + if (isBullish) + { + // + XPriceZones pZone; + bool hasPZone = CalculatePriceInsideZones( + pZone, + decisionState, + vale // + ); + + // + if (hasPZone && + pZone.IsBullish()) + { + conditions.decisionZone = pZone; + } + } + else if (isBearish) + { + // + XPriceZones pZone; + bool hasPZone = CalculatePriceInsideZones( + pZone, + decisionState, + peak // + ); + + // + if (hasPZone && + pZone.IsBearish()) + { + conditions.decisionZone = pZone; + } + } + + // + hasDecision = conditions.HasDecisionZone(); + result = hasDecision; + if (!result) + { + return result; + } + } + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXTWPVSiganlTrigger( + // + X121SMCStrategyXTWPVSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + + // + // Detect Target ... + double target = CalculateTarget( + cBar, + analyseState, + setupDir // + ); + if (target == 0) + { + // + target = CalculateTarget( + cBar, + verificationState, + setupDir // + ); + } + + // + double oppositTarget = CalculateTarget( + cBar, + analyseState, + Opposit(setupDir) // + ); + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + // Filling SL Candidates ... + + // + double sls[]; + + // + double atr = triggerConditions.x121Conditions.atrBuffer[1]; + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + if (isBullish) + { + // + double lowerVale = triggerCycleHelper.mX121Helper.GetLowerVale(vale); + if (lowerVale > 0) + { + // + Add( + lowerVale, + sls // + ); + } + } + else if (isBearish) + { + // + double higherPeak = triggerCycleHelper.mX121Helper.GetHigherPeak(peak); + if (higherPeak > 0) + { + // + Add( + higherPeak, + sls // + ); + } + } + + // + if (ArraySize(sls) == 0) + { + } + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - atr + : slsMax + atr; + double risk = MathAbs(entry - sl); + double targetDelta = 2 * (risk / 3); + if (target == 0) + { + // + int minTargetPint = 50; + double minTargetPointValue = minTargetPint * points; + if (targetDelta < minTargetPointValue) + { + targetDelta = minTargetPointValue; + } + + // + // Force Target On Half Risk ... + target = + isBullish + ? entry + targetDelta + : entry - targetDelta; + + // + target = 0; + + // + } + + // + conditions.sl = sl; + conditions.target = target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +// +// Draw Signal ... +int DrawX121SMCXTWPVSiganl( + X121SMCStrategyXTWPVSignalConditions &conditions, + XCBaseObject *&drawnObjects[], + XCPOIDrawer *drawer // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (drawer == NULL) + { + return result; + } + + // + bool isSetuped = conditions.IsSetuped(); + if (!isSetuped) + { + return result; + } + + // + bool isBullish = IsBullish(conditions.dir); + + // + XCBaseObject *priceZoneObjs[]; + XCBaseObject *decisionZoneObjs[]; + XCBaseObject *marketStructureObjs[]; + + // + bool hasMarketStructure = conditions.HasMarketStrucutre(); + if (hasMarketStructure) + { + // // + // drawer.DrawMarketStructure( + // conditions.analyseMarketStructure, + // marketStructureObjs // + // ); + } + + // + bool hasPriceZone = conditions.HasPriceZone(); + if (hasPriceZone) + { + // + XPriceZones pZone; + if (isBullish) + { + pZone = conditions.valePriceZone; + } + else + { + pZone = conditions.peakPriceZone; + } + + // + drawer.DrawPriceZone( + pZone, + priceZoneObjs, + conditions.dir // + ); + } + + // + bool hasDecisionZone = conditions.HasDecisionZone(); + if (hasDecisionZone) + { + // + drawer.DrawPriceZone( + conditions.decisionZone, + decisionZoneObjs + // , + // conditions.dir // + ); + } + + // + Copy( + priceZoneObjs, + drawnObjects, + false // + ); + + // + Copy( + decisionZoneObjs, + drawnObjects, + false // + ); + + // + Copy( + marketStructureObjs, + drawnObjects, + false // + ); + + // + result = ArraySize(drawnObjects); + + // + return result; +} + +// diff --git a/Documents/BKP/1/x-121.smc.xtwpv.old.signal.lib.mq5 b/Documents/BKP/1/x-121.smc.xtwpv.old.signal.lib.mq5 new file mode 100644 index 00000000..ba1637da --- /dev/null +++ b/Documents/BKP/1/x-121.smc.xtwpv.old.signal.lib.mq5 @@ -0,0 +1,2060 @@ +/////////////////////////////////////////////////////// +// +// 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" + +// +const string X121SMCXTWPV_Method_1_Token = "X121SMCXTWPV_1"; +const string X121SMCXTWPV_Method_2_Token = "X121SMCXTWPV_2"; +const string X121SMCXTWPV_Method_3_Token = "X121SMCXTWPV_3"; + +// +enum ENUM_X_X121SMC_XTWPV_METHODS +{ + X_X121SMC_XTWPV_METHOD_UNKNOWN, + X_X121SMC_XTWPV_METHOD_1, + X_X121SMC_XTWPV_METHOD_2, + X_X121SMC_XTWPV_METHOD_3, +}; + +// +string ToString(ENUM_X_X121SMC_XTWPV_METHODS value) +{ + // + string result = NULL; + + // + if (value == X_X121SMC_XTWPV_METHOD_UNKNOWN) + { + return result; + } + + // + switch (value) + { + // + case X_X121SMC_XTWPV_METHOD_1: + result = "Method_1"; + break; + + // + case X_X121SMC_XTWPV_METHOD_2: + result = "Method_2"; + break; + } + + // + return result; +} + +// +ENUM_X_X121SMC_XTWPV_METHODS ParseMethod(string value) +{ + // + ENUM_X_X121SMC_XTWPV_METHODS result = X_X121SMC_XTWPV_METHOD_UNKNOWN; + + // + if (!IsValid(value)) + { + return result; + } + + // + if (Contains(X121SMCXTWPV_Method_1_Token, value)) + { + result = X_X121SMC_XTWPV_METHOD_1; + } + else if (Contains(X121SMCXTWPV_Method_2_Token, value)) + { + result = X_X121SMC_XTWPV_METHOD_2; + } + + // + return result; +} + +// +// Definitions ... +struct X121SMCStrategyXTWPVSignalConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double sl; + double target; + ENUM_X_DIRECTION dir; + ENUM_X_POSITION_TYPES type; + + // + // Setup Props ... + + // + datetime setupTime; + datetime triggerTime; + + // + double point; + XPVPivot pivot; + + // + XConsolidationZone consolidationZone; + + // + string method; + + // + bool hasSupportZone; + bool hasResistanceZone; + bool hasSupplyZone; + bool hasDemandZone; + bool hasOrderBlock; + bool hasFairValueGap; + XCSupportZone *supportZone; + XCResistanceZone *resistanceZone; + XCSupplyZone *supplyZone; + XCDemandZone *demandZone; + XCOrderBlock *orderBlock; + XCFVG *fairValueGap; + + // + // Constructor ... + X121SMCStrategyXTWPVSignalConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + target = 0; + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + symbol = NULL; + period = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + ExtensionClean(); + } + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // + // Extensions ... + + /** + * Clean Additional Properties ... + */ + void ExtensionClean() + { + // + point = 0; + pivot.Clean(); + consolidationZone.Clean(); + + // + method = NULL; + + // + CleanPriceInsideZones(); + } + + /** + * Clean Price Insie Zones ... + */ + void CleanPriceInsideZones() + { + // + hasSupportZone = false; + hasResistanceZone = false; + hasSupplyZone = false; + hasDemandZone = false; + hasOrderBlock = false; + hasFairValueGap = false; + + // + supportZone = NULL; + resistanceZone = NULL; + supplyZone = NULL; + demandZone = NULL; + orderBlock = NULL; + fairValueGap = NULL; + } + + /** + * Count Price Inside Zones ... + * + * @return ( int ) + */ + int CountPriceInsideZones() + { + // + int result = 0; + + // + if (hasSupportZone) + { + result++; + } + + // + if (hasResistanceZone) + { + result++; + } + + // + if (hasSupplyZone) + { + result++; + } + + // + if (hasDemandZone) + { + result++; + } + + // + if (hasOrderBlock) + { + result++; + } + + // + if (hasFairValueGap) + { + result++; + } + + // + return result; + } + + /** + * Check Conditions Has Price Inside Zones ... + * + * @return ( bool ) + */ + bool HasPriceInsideZones() + { + // + bool result = false; + + // + result = IsValidSize(CountPriceInsideZones()); + + // + return result; + } + + /** + * Check Conditions Has Bullish Price Inside Zone ... + * + * @return ( bool ) + */ + bool HasBullishPriceInsideZone() + { + // + bool result = false; + + // + result = + // + HasPriceInsideZones() && + // + (hasDemandZone || + hasSupportZone || + (hasOrderBlock && + orderBlock.IsBullish()) || + (hasFairValueGap && + fairValueGap.IsBullish())) + // + ; + + // + return result; + } + + /** + * Check Conditions Has Bearish Price Inside Zone ... + * + * @return ( bool ) + */ + bool HasBearishPriceInsideZone() + { + // + bool result = false; + + // + result = + // + HasPriceInsideZones() && + // + (hasSupplyZone || + hasResistanceZone || + (hasOrderBlock && + orderBlock.IsBearish()) || + (hasFairValueGap && + fairValueGap.IsBearish())) + // + ; + + // + return result; + } + + /** + * Check has Vald Pivot or not ... + * + * @return ( bool ) + */ + bool HasPivot() + { + return pivot.IsValid(); + } + + /** + * Check Model Has Consolidation Zone or not ... + * + * @return ( bool ) + */ + bool HasConsolidationZone() + { + return consolidationZone.IsValid(); + } + + // +}; + +// +// Extension Functions ... + +// +// Detect Setup Conditions ... +bool DetectX121SMCXTWPVSiganlSetup( + string _symbol, + ENUM_TIMEFRAMES _period, + // + X121SMCStrategyXTWPVSignalConditions &conditions, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper + // +) +{ + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + conditions.symbol = symbol; + conditions.period = period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Setup Conditions ... + + // + XMarketStructure consolidationMarketStructure; + bool hasConsolidationMarketStructure = + consolidationCycleHelper + .DetectMarketStructure(consolidationMarketStructure); + + // + XMarketStructure analyseMarketStructure; + bool hasAnalyseMarketStructure = + analyseCycleHelper + .DetectMarketStructure(analyseMarketStructure); + + // + // Check Same Bias ... + result = + hasAnalyseMarketStructure && + hasConsolidationMarketStructure && + analyseMarketStructure.HasTrend() && + consolidationMarketStructure.HasTrend() && + analyseMarketStructure.bias == consolidationMarketStructure.bias; + if (!result) + { + return result; + } + + // + XOHCL analyseCBar; + result = analyseCycleHelper.GetBar( + cBar, + analyseCBar // + ); + if (!result) + { + return result; + } + + // + XOHCL analysePBar; + result = analyseCBar.GetPreviousBar(analysePBar); + if (!result) + { + return result; + } + + // + double bullishFib = GetFibonacciLevel( + analyseCBar.high, + analyseCBar.low, + GetFiboLevelValue(X_FIBO_LEVEL_382), + -1 // + ); + + // + double bearishFib = GetFibonacciLevel( + analyseCBar.high, + analyseCBar.low, + GetFiboLevelValue(X_FIBO_LEVEL_382), + 1 // + ); + + // + // Detect Market Trend ... + // ENUM_X_DIRECTION trend; + // bool hasTrend = verificationCycleHelper + // .DetectTrend(trend); + // bool hasBullishTrend = hasTrend && + // IsBullish(trend); + // bool hasBearishTrend = hasTrend && + // IsBearish(trend); + // result = hasBullishTrend || + // hasBearishTrend; + // if (!result) + // { + // return result; + // } + + // + // Detect Trend Based On Peaks and Vales ... + ENUM_X_DIRECTION trend; + bool hasTrend = triggerCycleHelper + .HasPVDirection(trend); + bool hasBullishTrend = hasTrend && + IsBullish(trend); + bool hasBearishTrend = hasTrend && + IsBearish(trend); + + // + // Retrieve Active Pivots ... + + // + XPVPivot peakPivot; + bool hasPeakPivot = analyseCycleHelper + .GetActivePeakPivot(peakPivot); + + // + XPVPivot valePivot; + bool hasValePivot = analyseCycleHelper + .GetActiveValePivot(valePivot); + + // + // Check Pivot ... + bool hasPivot = conditions.HasPivot(); + if (!hasPivot) + { + // + if (hasPeakPivot && !hasValePivot) + { + conditions.pivot = peakPivot; + } + else if (hasValePivot && !hasPeakPivot) + { + conditions.pivot = valePivot; + } + else if (hasPeakPivot && hasValePivot) + { + // + if (peakPivot.from > valePivot.from) + { + conditions.pivot = peakPivot; + } + else if (valePivot.from > peakPivot.from) + { + conditions.pivot = valePivot; + } + } + + // + hasPivot = conditions.HasPivot(); + result = hasPivot; + if (!result) + { + return result; + } + } + + // + // Update Pivot States ... + if (hasPivot) + { + // + conditions.pivot.to = cTime; + analyseCycleHelper.FillPivotState(conditions.pivot); + + // + // Check Pivot Renewation ... + bool hasNewPivot = + // + (hasPeakPivot && + peakPivot.from > conditions.pivot.from) || + (hasValePivot && + valePivot.from > conditions.pivot.from) + // + ; + result = !hasNewPivot; + if (!result) + { + // + conditions.pivot.Clean(); + return result; + } + } + + // + // XOHCL Conditions ... + + // + // Fibo Pressure ... + ENUM_X_DIRECTION pBarFiboPressureDir; + bool pBarHasFiboPressure = triggerCycleHelper + .mBarAnalyser + .HasFiboPressure( + pBar, + pBarFiboPressureDir // + ); + bool isPBarHasBullishFiboPressure = + pBarHasFiboPressure && + IsBullish(pBarFiboPressureDir); + bool isPBarHasBearishFiboPressure = + pBarHasFiboPressure && + IsBearish(pBarFiboPressureDir); + + // + // Rejection ... + ENUM_X_DIRECTION pBarRejectionDir; + bool isPBarRejected = triggerCycleHelper + .mBarAnalyser + .IsRejectionBar( + pBar, + pBarRejectionDir, + 0 // + ); + bool isPBarBullishRejected = + isPBarRejected && + IsBullish(pBarRejectionDir); + bool isPBarBearishRejected = + isPBarRejected && + IsBearish(pBarRejectionDir); + + // + // Momentum ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentumBar = triggerCycleHelper + .mBarAnalyser + .IsMomentumBar( + cBar, + cBarMomentumDir, + 0 // + ); + bool isCBarBullishMomentumBar = + isCBarMomentumBar && + IsBullish(cBarMomentumDir); + bool isCBarBearishMomentumBar = + isCBarMomentumBar && + IsBearish(cBarMomentumDir); + + // + // Engulfing ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulfed = triggerCycleHelper + .mBarAnalyser + .IsEngulfBar( + cBar, + cBarEngulfDir, + 0 // + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarEngulfDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarEngulfDir); + + // + // Helper cBar Conditions ... + bool isBearishFiboPassed = bullishFib <= conditions.pivot.lower; + bool isBullishFiboPassed = bearishFib >= conditions.pivot.upper; + + // + // Detect a Zone Which Price Inside it ... + // Helper (Optional) ... + conditions.CleanPriceInsideZones(); + bool hasPriceInsideZones = conditions.HasPriceInsideZones(); + int priceInsideZonesCount = conditions.CountPriceInsideZones(); + if (!hasPriceInsideZones) + { + // + hasPriceInsideZones = DetectPriceInsideZones( + verificationState, + cBar, + priceInsideZonesCount, + conditions.hasSupportZone, + conditions.supportZone, + conditions.hasResistanceZone, + conditions.resistanceZone, + conditions.hasSupplyZone, + conditions.supplyZone, + conditions.hasDemandZone, + conditions.demandZone, + conditions.hasOrderBlock, + conditions.orderBlock, + conditions.hasFairValueGap, + conditions.fairValueGap // + ); + + // + priceInsideZonesCount = conditions.CountPriceInsideZones(); + } + + // + // Check Price Inside Consolidation Zone ... + XConsolidationZone cZone; + bool hasConsolidationZone = conditions + .HasConsolidationZone(); + if (!hasConsolidationZone) + { + // + hasConsolidationZone = triggerCycleHelper + .GetLastConsolidationZone(cZone); + // + if (!hasConsolidationZone) + { + // + XConsolidationZone cZones[]; + int count = triggerCycleHelper + .FillConsolidationZones(cZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XConsolidationZone iZone = cZones[i]; + + // + XCZone *iCZone; + bool isInited = ToZone(iZone, iCZone); + if (!isInited) + { + continue; + } + + // + bool isValid = IsPriceInsideZone( + cBar, + iCZone // + ); + if (isValid) + { + cZone = iZone; + } + } + } + + // + conditions.consolidationZone = cZone; + hasConsolidationZone = conditions + .HasConsolidationZone(); + } + } + if (hasConsolidationZone) + { + conditions.consolidationZone = cZone; + } + + // + // PV Conditions ... + + // + double analysePeak = analyseConditions.x121Conditions.peaksBuffer[1]; + double analysePeakPrev = analyseConditions.x121Conditions.peaksBuffer[2]; + double analysePeakDiff = MathAbs(analysePeakPrev - analysePeak); + + // + bool isNewAnalysePeak = analyseConditions.x121Conditions.isNewPeak; + bool isNewAnalysePeakOverLast = analyseConditions.x121Conditions.isNewPeakOverLast; + bool isNewAnalysePeakUnderLast = analyseConditions.x121Conditions.isNewPeakUnderLast; + + // + double analyseVale = analyseConditions.x121Conditions.valesBuffer[1]; + double analyseValePrev = analyseConditions.x121Conditions.valesBuffer[2]; + double analyseValeDiff = MathAbs(analyseValePrev - analyseVale); + + // + bool isNewAnalyseVale = analyseConditions.x121Conditions.isNewVale; + bool isNewAnalyseValeOverLast = analyseConditions.x121Conditions.isNewValeOverLast; + bool isNewAnalyseValeUnderLast = analyseConditions.x121Conditions.isNewValeUnderLast; + + // + double triggerPeak = triggerConditions.x121Conditions.peaksBuffer[1]; + double triggerVale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + bool isNewTriggerPeak = triggerConditions.x121Conditions.isNewPeak; + bool isNewTriggerPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; + bool isNewTriggerPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; + + // + bool isNewTriggerVale = triggerConditions.x121Conditions.isNewVale; + bool isNewTriggerValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; + bool isNewTriggerValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; + + // + int condition2MinPVDiffPoint = 30; + bool isAnalysePeakDiffPointPassed = analysePeakDiff >= (condition2MinPVDiffPoint * points); + bool isAnalyseValeDiffPointPassed = analyseValeDiff >= (condition2MinPVDiffPoint * points); + + // + // DONCHAIN Conditions ... + + // + double analyseDonOpenUpper = analyseConditions.x121Conditions.donOpenUpperBuffer[1]; + double analyseDonOpenLower = analyseConditions.x121Conditions.donOpenLowerBuffer[1]; + + // + double analyseDonHighUpper = analyseConditions.x121Conditions.donHighUpperBuffer[1]; + double analyseDonHighLower = analyseConditions.x121Conditions.donHighLowerBuffer[1]; + + // + double analyseDonCloseUpper = analyseConditions.x121Conditions.donCloseUpperBuffer[1]; + double analyseDonCloseLower = analyseConditions.x121Conditions.donCloseLowerBuffer[1]; + + // + double analyseDonLowUpper = analyseConditions.x121Conditions.donLowUpperBuffer[1]; + double analyseDonLowLower = analyseConditions.x121Conditions.donLowLowerBuffer[1]; + + // + // OPEN ... + double triggerDonOpenUpper = triggerConditions.x121Conditions.donOpenUpperBuffer[1]; + double triggerDonOpenLower = triggerConditions.x121Conditions.donOpenLowerBuffer[1]; + double triggerDonOpenUpperPrev = triggerConditions.x121Conditions.donOpenUpperBuffer[2]; + double triggerDonOpenLowerPrev = triggerConditions.x121Conditions.donOpenLowerBuffer[2]; + + // + // HIGH ... + double triggerDonHighUpper = triggerConditions.x121Conditions.donHighUpperBuffer[1]; + double triggerDonHighLower = triggerConditions.x121Conditions.donHighLowerBuffer[1]; + double triggerDonHighUpperPrev = triggerConditions.x121Conditions.donHighUpperBuffer[2]; + double triggerDonHighLowerPrev = triggerConditions.x121Conditions.donHighLowerBuffer[2]; + + // + // CLOSE ... + double triggerDonCloseUpper = triggerConditions.x121Conditions.donCloseUpperBuffer[1]; + double triggerDonCloseLower = triggerConditions.x121Conditions.donCloseLowerBuffer[1]; + double triggerDonCloseUpperPrev = triggerConditions.x121Conditions.donCloseUpperBuffer[2]; + double triggerDonCloseLowerPrev = triggerConditions.x121Conditions.donCloseLowerBuffer[2]; + + // + // LOW ... + double triggerDonLowUpper = triggerConditions.x121Conditions.donLowUpperBuffer[1]; + double triggerDonLowLower = triggerConditions.x121Conditions.donLowLowerBuffer[1]; + double triggerDonLowUpperPrev = triggerConditions.x121Conditions.donLowUpperBuffer[2]; + double triggerDonLowLowerPrev = triggerConditions.x121Conditions.donLowLowerBuffer[2]; + + // + double triggerAtr = triggerConditions.x121Conditions.atrBuffer[1]; + double triggerUpperAtr = triggerConditions.x121Conditions.atrUpperBuffer[1]; + double triggerLowerAtr = triggerConditions.x121Conditions.atrLowerBuffer[1]; + + // + bool isNewTriggerPeakOverAtrUpper = + // + isNewTriggerPeak && + triggerPeak > triggerUpperAtr + // + ; + + // + bool isNewTriggerValeUnderAtrLower = + // + isNewTriggerVale && + triggerVale < triggerLowerAtr + // + ; + + // + if (isNewTriggerPeakOverAtrUpper || + isNewTriggerValeUnderAtrLower) + { + Print("ATR Break ..."); + } + + // + // Method 1 ... + + // + // Bullish Conditions 1 ... + bool bullishConditions1 = + // + false && + hasBullishTrend && + isBullishFiboPassed && + hasConsolidationZone && + analyseCBar.IsBullish() && + isNewAnalysePeakOverLast && + conditions.pivot.upper < analysePeak && + conditions.pivot.upper < analyseCBar.GetUp() && + conditions.pivot.upper > analyseCBar.GetDown() + // + ; + if (bullishConditions1) + { + // + conditions.point = conditions.pivot.upper; + conditions.method = ToString(X_X121SMC_XTWPV_METHOD_1); + } + + // + // Bearish Conditions 1 ... + bool bearishConditions1 = + // + false && + hasBearishTrend && + isBearishFiboPassed && + hasConsolidationZone && + analyseCBar.IsBearish() && + isNewAnalyseValeUnderLast && + conditions.pivot.lower > analyseVale && + conditions.pivot.lower < analyseCBar.GetUp() && + conditions.pivot.lower > analyseCBar.GetDown() + // + ; + if (bearishConditions1) + { + // + conditions.point = conditions.pivot.lower; + conditions.method = ToString(X_X121SMC_XTWPV_METHOD_1); + } + + // + // Method 2 ... + + // + // Bullish Conditions 2 ... + bool bullishConditions2 = + // + false && + hasBullishTrend && + isNewAnalyseValeOverLast && + isAnalyseValeDiffPointPassed && + analyseDonCloseLower > analyseVale + // + ; + if (bullishConditions2) + { + // + conditions.point = analyseVale; + conditions.method = ToString(X_X121SMC_XTWPV_METHOD_2); + } + + // + // Bearish Conditions 2 ... + bool bearishConditions2 = + // + false && + hasBearishTrend && + isNewAnalysePeakUnderLast && + isAnalysePeakDiffPointPassed && + analyseDonCloseUpper > analysePeak + // + ; + if (bearishConditions2) + { + // + conditions.point = analysePeak; + conditions.method = ToString(X_X121SMC_XTWPV_METHOD_2); + } + + // + // Method 3 ... + + // + // Bullish Conditions 3 ... + bool bullishConditions3 = + // + false + // + ; + if (bullishConditions3) + { + // + conditions.point = analyseVale; + conditions.method = ToString(X_X121SMC_XTWPV_METHOD_3); + } + + // + // Bearish Conditions 3 ... + bool bearishConditions3 = + // + false + // + ; + if (bearishConditions3) + { + // + conditions.point = analysePeak; + conditions.method = ToString(X_X121SMC_XTWPV_METHOD_3); + } + + // + // Summary Conditions ... + + // + isBullish = + // + bullishConditions1 || + bullishConditions2 || + bullishConditions3 + // + ; + + // + isBearish = + // + bearishConditions1 || + bearishConditions2 || + bearishConditions3 + // + ; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + conditions.setupTime = cTime; + conditions.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; +} + +// +// Detect Trigger Conditions ... +bool DetectX121SMCXTWPVSiganlTrigger( + // + X121SMCStrategyXTWPVSignalConditions &conditions, + // + string _symbol, + ENUM_TIMEFRAMES _period, + // + XC121SMCCycleHelper *triggerCycleHelper, + XC121SMCCycleHelper *decisionCycleHelper, + XC121SMCCycleHelper *analyseCycleHelper, + XC121SMCCycleHelper *verificationCycleHelper, + XC121SMCCycleHelper *consolidationCycleHelper, + XC121SMCCycleHelper *visionCycleHelper, + // + int maxAllowedSetupAge = 60 // + // +) +{ + // + bool result = false; + + // + result = conditions.IsSetuped(); + if (!result) + { + return result; + } + + // + datetime setupTime = conditions.setupTime; + ENUM_X_DIRECTION setupDir = conditions.dir; + + // + bool isBullish = IsBullish(setupDir); + bool isBearish = IsBearish(setupDir); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + int loopback = 10; + + // + string symbol = _symbol; + ENUM_TIMEFRAMES period = _period; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + double points = GetPoints(symbol); + + // + int swingLoopback = 9; + double ll = cBar.FindLowest(swingLoopback, MODE_LOW); + double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); + double llDown = cBar.FindLowesttDown(swingLoopback); + double hhUp = cBar.FindHighestUp(swingLoopback); + + // + // Cycles Conditions ... + + // + // Trigger ... + ENUM_XPOI_EVENTS triggerPoiEvents[]; + ENUM_X_CYCLE_EVENTS triggerCycleEvents[]; + X121SMCCycleConditions triggerConditions; + result = triggerCycleHelper.GetConditions( + triggerCycleEvents, + triggerPoiEvents, + triggerConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Decision ... + ENUM_XPOI_EVENTS decisionPoiEvents[]; + ENUM_X_CYCLE_EVENTS decisionCycleEvents[]; + X121SMCCycleConditions decisionConditions; + result = decisionCycleHelper.GetConditions( + decisionCycleEvents, + decisionPoiEvents, + decisionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Analyse ... + ENUM_XPOI_EVENTS analysePoiEvents[]; + ENUM_X_CYCLE_EVENTS analyseCycleEvents[]; + X121SMCCycleConditions analyseConditions; + result = analyseCycleHelper.GetConditions( + analyseCycleEvents, + analysePoiEvents, + analyseConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Verification ... + ENUM_XPOI_EVENTS verificationPoiEvents[]; + ENUM_X_CYCLE_EVENTS verificationCycleEvents[]; + X121SMCCycleConditions verificationConditions; + result = verificationCycleHelper.GetConditions( + verificationCycleEvents, + verificationPoiEvents, + verificationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Consolidation ... + ENUM_XPOI_EVENTS consolidationPoiEvents[]; + ENUM_X_CYCLE_EVENTS consolidationCycleEvents[]; + X121SMCCycleConditions consolidationConditions; + result = consolidationCycleHelper.GetConditions( + consolidationCycleEvents, + consolidationPoiEvents, + consolidationConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Vision ... + ENUM_XPOI_EVENTS visionPoiEvents[]; + ENUM_X_CYCLE_EVENTS visionCycleEvents[]; + X121SMCCycleConditions visionConditions; + result = visionCycleHelper.GetConditions( + visionCycleEvents, + visionPoiEvents, + visionConditions, + zIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + // Cycles POI States ... + XPOIState triggerState = triggerConditions.state; + XPOIState decisionState = decisionConditions.state; + XPOIState analyseState = analyseConditions.state; + XPOIState verificationState = verificationConditions.state; + XPOIState consolidationState = consolidationConditions.state; + XPOIState visionState = visionConditions.state; + + // + // Trigger Conditions ... + + // + result = isBullish || + isBearish; + if (!result) + { + // + // Cleanup Setup Conditions ... + int setupAge = conditions.GetSetupAge(); + if (IsValidSize(setupAge) && + IsValidSize(maxAllowedSetupAge) && + setupAge >= maxAllowedSetupAge) + { + conditions.Clean(); + } + + // + return result; + } + + // + // Detect Nearest Pivot Point ... + XPVPivotPoint pivotPoints[]; + XPVPivotPoint nearestPivotPoint; + bool hasNearestPivotPoint = false; + int pivotPointsCount = triggerCycleHelper + .FillPivotPoints(pivotPoints); + if (IsValidSize(pivotPointsCount)) + { + // + for (int i = 0; i < pivotPointsCount; i++) + { + // + XPVPivotPoint iPoint = pivotPoints[i]; + + // + bool canSet = + (isBullish + ? iPoint.value < conditions.point + : iPoint.value > conditions.point) + // + && + // + (!nearestPivotPoint.IsValid() + ? true + : isBullish + ? nearestPivotPoint.value > iPoint.value + : nearestPivotPoint.value < iPoint.value); + if (canSet) + { + nearestPivotPoint = iPoint; + } + } + + // + hasNearestPivotPoint = nearestPivotPoint.IsValid(); + } + + // + // Detect Target ... + double target = CalculateTarget( + cBar, + analyseState, + setupDir // + ); + if (target == 0) + { + // + target = CalculateTarget( + cBar, + verificationState, + setupDir // + ); + } + + // + double oppositTarget = CalculateTarget( + cBar, + analyseState, + Opposit(setupDir) // + ); + + // + double entry = GetEntry( + conditions.symbol, + setupDir // + ); + + // + // Filling SL Candidates ... + double atr = triggerConditions.x121Conditions.atrBuffer[1]; + + // + double sls[]; + + // + bool hasConsolidationZone = conditions.HasConsolidationZone(); + if (hasConsolidationZone) + { + // + if (isBullish) + { + Add( + conditions.consolidationZone.lower, + sls // + ); + } + else + { + Add( + conditions.consolidationZone.upper, + sls // + ); + } + } + if (hasNearestPivotPoint) + { + Add( + nearestPivotPoint.value, + sls // + ); + } + if (ArraySize(sls) == 0) + { + // + double pointsDiff = (10 * points); + double pointsPlus = conditions.point + pointsDiff; + double pointsMinus = conditions.point - pointsDiff; + + // + // Force SL ... + Add( + conditions.point, + sls // + ); + + // + Add( + pointsPlus, + sls // + ); + + // + Add( + pointsMinus, + sls // + ); + + // + Add( + oppositTarget, + sls // + ); + } + + // + bool hasPriceInsideZones = conditions.HasPriceInsideZones(); + bool hasBullishPriceInsideZone = conditions.HasBullishPriceInsideZone(); + bool hasBearishPriceInsideZone = conditions.HasBearishPriceInsideZone(); + + // + if ( + isBullish && + hasPriceInsideZones && + hasBullishPriceInsideZone // + ) + { + // + // Demand ... + if (conditions.hasDemandZone) + { + // + Add( + conditions.demandZone.Lower(), + sls // + ); + } + + // + // Support ... + if (conditions.hasSupportZone) + { + // + Add( + conditions.supportZone.Lower(), + sls // + ); + } + + // + // Order Block ... + if (conditions.hasOrderBlock) + { + // + Add( + conditions.orderBlock.Lower(), + sls // + ); + } + + // + // Fair Value Gap ... + if (conditions.hasFairValueGap) + { + // + Add( + conditions.fairValueGap.Lower(), + sls // + ); + } + } + + // + if ( + isBearish && + hasPriceInsideZones && + hasBearishPriceInsideZone // + ) + { + // + // Supply ... + if (conditions.hasSupplyZone) + { + // + Add( + conditions.supplyZone.Upper(), + sls // + ); + } + + // + // Resistance ... + if (conditions.hasResistanceZone) + { + // + Add( + conditions.resistanceZone.Upper(), + sls // + ); + } + + // + // Order Block ... + if (conditions.hasOrderBlock) + { + // + Add( + conditions.orderBlock.Upper(), + sls // + ); + } + + // + // Fair Value Gap ... + if (conditions.hasFairValueGap) + { + // + Add( + conditions.fairValueGap.Upper(), + sls // + ); + } + } + + // + double slsMin = GetMin(sls); + double slsMax = GetMax(sls); + + // + double sl = isBullish + ? slsMin - atr + : slsMax + atr; + double risk = MathAbs(entry - sl); + double targetDelta = 2 * (risk / 3); + if (target == 0) + { + // + int minTargetPint = 50; + double minTargetPointValue = minTargetPint * points; + if (targetDelta < minTargetPointValue) + { + targetDelta = minTargetPointValue; + } + + // + // Force Target On Half Risk ... + target = + isBullish + ? entry + targetDelta + : entry - targetDelta; + + // + } + + // + conditions.sl = sl; + conditions.target = 0; // target; + conditions.triggerTime = cTime; + conditions.type = isBullish + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + return result; +} + +/** + * Draw Conditions Pivot Zone ... + * + * @param conditions: X121SMCStrategyXTWPVSignalConditions instance Reference ... + * @param drawer: XCPOIDrawer pointer ... + * @param drawnObjects: XCBaseObject instance Reference Collection ... + * @param drawState: Boolean ... + * @param drawTicksZone: 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 ... + * + * @return ( int ) + */ +int DrawXTWPVPivotZone( + X121SMCStrategyXTWPVSignalConditions &conditions, + XCPOIDrawer *drawer, + XCBaseObject *&drawnObjects[], + bool drawState = false, + bool drawTicksZone = 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 // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (drawer == NULL || + !conditions.HasPivot()) + { + return result; + } + + // + drawer.DrawPivot( + // + conditions.pivot, + drawnObjects, + // + drawState, + drawTicksZone, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + + // + result = ArraySize(drawnObjects); + + // + return result; +} + +/** + * Drw Conditions Price Inside Zones ... + * + * @param conditions: X121SMCStrategyXTWPVSignalConditions instance Reference ... + * @param drawer: XCPOIDrawer pointer ... + * @param drawnObjects: XCBaseObject instance Reference Collection ... + * + * @return ( int ) + */ +int DrawTWPVPriceInsideZones( + X121SMCStrategyXTWPVSignalConditions &conditions, + XCPOIDrawer *drawer, + XCBaseObject *&drawnObjects[] // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if ( + drawer == NULL || + !conditions.HasPriceInsideZones()) + { + return result; + } + + // + // Support ... + if (conditions.hasSupportZone) + { + // + XCSupportZoneObject *iObj; + bool isCreated = drawer.CreateSupportZone( + conditions.supportZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // Resistance ... + if (conditions.hasResistanceZone) + { + // + XCResistanceZoneObject *iObj; + bool isCreated = drawer.CreateResistanceZone( + conditions.resistanceZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // Supply ... + if (conditions.hasSupplyZone) + { + // + XCSupplyZoneObject *iObj; + bool isCreated = drawer.CreateSupplyZone( + conditions.supplyZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // Demand ... + if (conditions.hasDemandZone) + { + // + XCDemandZoneObject *iObj; + bool isCreated = drawer.CreateDemandZone( + conditions.demandZone, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + + // + // Order Block ... + if (conditions.hasOrderBlock) + { + // + bool isBullish = conditions.orderBlock.IsBullish(); + if (isBullish) + { + // + XCBullishOrderBlockObject *iObj; + bool isCreated = drawer.CreateBullishOrderBlock( + conditions.orderBlock, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + else + { + // + XCBearishOrderBlockObject *iObj; + bool isCreated = drawer.CreateBearishOrderBlock( + conditions.orderBlock, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + // FairValueGap ... + if (conditions.hasFairValueGap) + { + // + bool isBullish = conditions.fairValueGap.IsBullish(); + if (isBullish) + { + // + XCBullishFairValueGapObject *iObj; + bool isCreated = drawer.CreateBullishFairValueGap( + conditions.fairValueGap, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + else + { + // + XCBearishFairValueGapObject *iObj; + bool isCreated = drawer.CreateBearishFairValueGap( + conditions.fairValueGap, + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; +} + +// diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index 22310419..cbb3bf10 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -1851,6 +1851,222 @@ class XCX121Helper : public XCBaseHelper ); } + // + // + // + + // + double GetHigherPeak( + double peak, // Peak Source + int barIndex = 0, // Bar Index + int loopback = 576 // Max Allowed Loopback + ) + { + // + double result = 0; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (loopback < 576) + { + loopback = 576; + } + + // + if (peak <= 0) + { + return result; + } + + // + double iValue = 0; + int index = barIndex; + bool canContinue = true; + while (canContinue) + { + // + iValue = GetPeak(index); + if (iValue > peak) + { + // + result = iValue; + break; + } + + // + canContinue = index < barIndex + loopback; + index++; + } + + // + return result; + } + + // + double GetLowerPeak( + double peak, // Peak Source + int barIndex = 0, // Bar Index + int loopback = 576 // Max Allowed Loopback + ) + { + // + double result = 0; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (loopback < 576) + { + loopback = 576; + } + + // + if (peak <= 0) + { + return result; + } + + // + double iValue = 0; + int index = barIndex; + bool canContinue = true; + while (canContinue) + { + // + iValue = GetPeak(index); + if (iValue < peak) + { + // + result = iValue; + break; + } + + // + canContinue = index < barIndex + loopback; + index++; + } + + // + return result; + } + + // + double GetHigherVale( + double vale, // Vale Source + int barIndex = 0, // Bar Index + int loopback = 576 // Max Allowed Loopback + ) + { + // + double result = 0; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (loopback < 576) + { + loopback = 576; + } + + // + if (vale <= 0) + { + return result; + } + + // + double iValue = 0; + int index = barIndex; + bool canContinue = true; + while (canContinue) + { + // + iValue = GetVale(index); + if (iValue > vale) + { + // + result = iValue; + break; + } + + // + canContinue = index > barIndex + loopback; + index++; + } + + // + return result; + } + + // + double GetLowerVale( + double vale, // Vale Source + int barIndex = 0, // Bar Index + int loopback = 576 // Max Allowed Loopback + ) + { + // + double result = 0; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (loopback < 576) + { + loopback = 576; + } + + // + if (vale <= 0) + { + return result; + } + + // + double iValue = 0; + int index = barIndex; + bool canContinue = true; + while (canContinue) + { + // + iValue = GetVale(index); + if (iValue < vale) + { + // + result = iValue; + break; + } + + // + canContinue = index > barIndex + loopback; + index++; + } + + // + return result; + } + + // + // + // + // double GetLowestPeak( int barIndex, @@ -1872,6 +2088,12 @@ class XCX121Helper : public XCBaseHelper barIndex = 0; } + // + if (loopback < 576) + { + loopback = 576; + } + // Calculate(); @@ -1921,6 +2143,12 @@ class XCX121Helper : public XCBaseHelper barIndex = 0; } + // + if (loopback < 576) + { + loopback = 576; + } + // Calculate(); @@ -1970,6 +2198,12 @@ class XCX121Helper : public XCBaseHelper barIndex = 0; } + // + if (loopback < 576) + { + loopback = 576; + } + // Calculate(); @@ -2019,6 +2253,12 @@ class XCX121Helper : public XCBaseHelper barIndex = 0; } + // + if (loopback < 576) + { + loopback = 576; + } + // Calculate(); 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 5046288d..82e31f10 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -105,89 +105,6 @@ class XC121SMCCycleHelper : public XCBase // // 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; - } - - /** - * Get Valid Pivot Points Repetition Length ... - * min => 7 - * - * @return ( int ) - */ - int ValidPivotRepetition() - { - return mValidPivotRepetition; - } - - /** - * Set Valid Pivot Points Repetition Length ... - * - * @param value: Integer ... - * min => 7 - */ - void ValidPivotRepetition(int value) - { - // - if (value < 7) - { - value = 7; - } - - // - mValidPivotRepetition = value; - } - // // Actions ... @@ -498,23 +415,6 @@ class XC121SMCCycleHelper : public XCBase // result = conditions.IsValid(); - // - if (result) - { - // - if (!IsValidSize(ArraySize(mPivots))) - { - Detect(barIndex); - } - - // - Calculate( - barIndex, - events, - conditions // - ); - } - // return result; } @@ -960,14 +860,6 @@ class XC121SMCCycleHelper : public XCBase // result = model.IsValid(); - // - // TODO: Remove this ... - XCBaseObject *objects[]; - int dObjects = mPOIDetector.mDrawer.DrawMarketStructure( - model, - objects // - ); - // return result; } @@ -975,1605 +867,6 @@ class XC121SMCCycleHelper : public XCBase // // Tools ... - /** - * 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; - } - - /** - * Validate Specified Pivot's State ... - * - * @param pivot: XPVPivot instance Reference ... - * @param barIndex: Integer ... - */ - void ValidatePivotState( - XPVPivot &pivot, - int barIndex = 0 // - ) - { - // - if (!pivot.IsValid() || - !pivot.state.IsValid() || - !pivot.state.HasChild()) - { - return; - } - - // - double upperr = pivot.upper; - double lower = pivot.lower; - - // - XOHCL cBar; - bool isInited = cBar.Init( - pivot.symbol, - pivot.period, - barIndex // - ); - if (!isInited) - { - return; - } - - // - int count = 0; - - // - double ask = GetAsk(pivot.symbol); - double bid = GetBid(pivot.symbol); - - // - double pivotMid = pivot.CalculateMid(); - - // - // Try to Validate States ... - - // - bool isPriceInPremium = - // - ask > pivotMid && - bid > pivotMid && - cBar.low > pivotMid - // - ; - - // - bool isPriceInDiscount = - // - ask < pivotMid && - bid < pivotMid && - cBar.high < pivotMid - // - ; - - // - // Swings ... - XCSwing *tmpSwings[]; - - // - // Swing Highs ... - Clean(tmpSwings); - count = pivot.state.CountSwingHighs(); - if (IsValidSize(count)) - { - // - if (isPriceInPremium) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = pivot.state.swingHighs[i]; - - // - bool isValid = - // - iSwing.GetTime() >= pivot.from && - iSwing.GetTime() <= pivot.to && - iSwing.GetValue() > pivotMid - // - ; - if (isValid) - { - // - Add( - iSwing, - tmpSwings // - ); - } - } - - // - Copy( - tmpSwings, - pivot.state.swingHighs // - ); - } - } - - // - // Swing Lows ... - Clean(tmpSwings); - count = pivot.state.CountSwingLows(); - if (IsValidSize(count)) - { - // - if (isPriceInDiscount) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing *iSwing = pivot.state.swingLows[i]; - - // - bool isValid = - // - iSwing.GetTime() >= pivot.from && - iSwing.GetTime() <= pivot.to && - iSwing.GetValue() < pivotMid - // - ; - if (isValid) - { - // - Add( - iSwing, - tmpSwings // - ); - } - } - - // - Copy( - tmpSwings, - pivot.state.swingLows // - ); - } - } - - // - Clean(tmpSwings); - - // - // Rejection Bars ... - XCRejectionBar *tmpRejections[]; - - // - // Bullish ... - Clean(tmpRejections); - count = pivot.state.CountBullishRejectionBars(); - if (IsValidSize(count)) - { - // - if (isPriceInDiscount) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iRejection = pivot.state.bullishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isValid = - // - iRejection.BarTime() >= pivot.from && - iBar.high < pivotMid - // - ; - if (isValid) - { - // - Add( - iRejection, - tmpRejections // - ); - } - } - - // - Copy( - tmpRejections, - pivot.state.bullishRejectionBars // - ); - } - } - - // - // Bearish ... - Clean(tmpRejections); - count = pivot.state.CountBearishRejectionBars(); - if (IsValidSize(count)) - { - // - if (isPriceInPremium) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar *iRejection = pivot.state.bearishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isValid = - // - iRejection.BarTime() >= pivot.from && - iBar.low > pivotMid - // - ; - if (isValid) - { - // - Add( - iRejection, - tmpRejections // - ); - } - } - - // - Copy( - tmpRejections, - pivot.state.bearishRejectionBars // - ); - } - } - - // - Clean(tmpRejections); - - // - // Support Zone ... - XCSupportZone *tmpSupports[]; - count = pivot.state.CountSupportZones(); - if (IsValidSize(count)) - { - // - if (isPriceInDiscount) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone *iZone = pivot.state.supportZones[i]; - - // - bool isValid = - // - iZone.Upper() < pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpSupports // - ); - } - } - - // - Copy( - tmpSupports, - pivot.state.supportZones // - ); - } - } - - // - Clean(tmpSupports); - - // - // Resistance Zone ... - XCResistanceZone *tmpResistances[]; - count = pivot.state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - if (isPriceInPremium) - { - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone *iZone = pivot.state.resistanceZones[i]; - - // - bool isValid = - // - iZone.Lower() > pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpResistances // - ); - } - } - - // - Copy( - tmpResistances, - pivot.state.resistanceZones // - ); - } - } - - // - Clean(tmpResistances); - - // - // Supply Zones ... - XCSupplyZone *tmpSupplies[]; - count = pivot.state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - if (isPriceInPremium) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone *iZone = pivot.state.supplyZones[i]; - - // - bool isValid = - // - iZone.Lower() > pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpSupplies // - ); - } - } - - // - Copy( - tmpSupplies, - pivot.state.supplyZones // - ); - } - } - - // - Clean(tmpSupplies); - - // - // Demand Zones ... - XCDemandZone *tmpDemands[]; - count = pivot.state.CountDemandZones(); - if (IsValidSize(count)) - { - // - if (isPriceInDiscount) - { - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone *iZone = pivot.state.demandZones[i]; - - // - bool isValid = - // - iZone.Upper() < pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpDemands // - ); - } - } - - // - Copy( - tmpDemands, - pivot.state.demandZones // - ); - } - } - - // - Clean(tmpDemands); - - // - // Order Blocks ... - XCOrderBlock *tmpOrderBlocks[]; - - // - // Bullish ... - Clean(tmpOrderBlocks); - count = pivot.state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - if (isPriceInDiscount) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iZone = pivot.state.bullishOrderBlocks[i]; - - // - bool isValid = - // - iZone.Upper() < pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpOrderBlocks // - ); - } - } - - // - Copy( - tmpOrderBlocks, - pivot.state.bullishOrderBlocks // - ); - } - } - - // - // Bearish ... - Clean(tmpOrderBlocks); - count = pivot.state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - if (isPriceInPremium) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock *iZone = pivot.state.bearishOrderBlocks[i]; - - // - bool isValid = - // - iZone.Lower() > pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpOrderBlocks // - ); - } - } - - // - Copy( - tmpOrderBlocks, - pivot.state.bearishOrderBlocks // - ); - } - } - - // - Clean(tmpOrderBlocks); - - // - // Fair Value Gaps ... - XCFVG *tmpFVGs[]; - - // - // Bullish ... - Clean(tmpFVGs); - count = pivot.state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - if (isPriceInDiscount) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iZone = pivot.state.bullishFairValueGaps[i]; - - // - bool isValid = - // - iZone.Upper() < pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpFVGs // - ); - } - } - - // - Copy( - tmpFVGs, - pivot.state.bullishFairValueGaps // - ); - } - } - - // - // Bearish ... - Clean(tmpFVGs); - count = pivot.state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - if (isPriceInPremium) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG *iZone = pivot.state.bearishFairValueGaps[i]; - - // - bool isValid = - // - iZone.Lower() > pivotMid - // - ; - if (isValid) - { - // - Add( - iZone, - tmpFVGs // - ); - } - } - - // - Copy( - tmpFVGs, - pivot.state.bearishFairValueGaps // - ); - } - } - - // - Clean(tmpFVGs); - - // - } - - /** - * Detect Cycle Trend Based On Pivots ... - * - * @param dir: ENUM_X_DIRECTION member Reference ... - * @param numberOfPivots: Integer ... - * @param maxAllowedLoopback: Integer ... - * @param minRequiredPivotVerification: Integer ... - * - * @return ( bool ) - */ - bool DetectTrend( - ENUM_X_DIRECTION &dir, - int numberOfPivots = 3, - int maxAllowedLoopback = 576, - int minRequiredPivotVerification = 5 // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - if (numberOfPivots < 3) - { - numberOfPivots = 3; - } - - // - int index = 0; - double peaks[]; - double vales[]; - double peak = 0; - double vale = 0; - int peaksVerified = 0; - int valesVerified = 0; - bool canContinue = true; - while (canContinue) - { - // - // Peak ... - bool lookupPeak = ArraySize(peaks) < numberOfPivots; - if (lookupPeak) - { - // - double iPeak = mX121Helper.GetPeak(index); - if (iPeak == peak) - { - peaksVerified++; - } - else - { - // - if (peaksVerified >= minRequiredPivotVerification) - { - // - Add( - iPeak, - peaks // - ); - - // - peaksVerified = 0; - lookupPeak = ArraySize(peaks) < numberOfPivots; - } - else - { - peak = iPeak; - } - } - } - - // - // Vale ... - bool lookupVale = ArraySize(vales) < numberOfPivots; - if (lookupVale) - { - // - double iVale = mX121Helper.GetVale(index); - if (iVale == vale) - { - valesVerified++; - } - else - { - // - if (valesVerified >= minRequiredPivotVerification) - { - // - Add( - iVale, - vales // - ); - - // - valesVerified = 0; - lookupVale = ArraySize(vales) < numberOfPivots; - } - else - { - vale = iVale; - } - } - } - - // - canContinue = index < maxAllowedLoopback && - (lookupPeak || - lookupVale); - if (canContinue) - { - index++; - } - } - - // - int verifications = 0; - - // - // Peaks ... - int peaksCount = ArraySize(peaks); - if (!result && - peaksCount == numberOfPivots) - { - // - verifications = 0; - for (int i = 0; i < peaksCount - 1; i++) - { - // - double iValue = peaks[i]; - double nValue = peaks[i + 1]; - if (iValue < nValue) - { - verifications++; - } - } - - // - result = verifications == numberOfPivots - 1; - if (result) - { - dir = X_DIRECTION_BEARISH; - } - } - - // - // Vales ... - int valesCount = ArraySize(vales); - if (!result && - valesCount == numberOfPivots) - { - // - verifications = 0; - for (int i = 0; i < valesCount - 1; i++) - { - // - double iValue = vales[i]; - double nValue = vales[i + 1]; - if (iValue > nValue) - { - verifications++; - } - } - - // - result = verifications == numberOfPivots - 1; - if (result) - { - dir = X_DIRECTION_BULLISH; - } - } - - // - return result; - } - - /** - * Detect Market Structure based on Peaks and Vales ... - * - * @param dir: ENUM_X_DIRECTION member Reference ... - * @param minVerification: Integer ... - * - * @return ( bool ) - */ - bool HasPVDirection( - ENUM_X_DIRECTION &dir, - int minVerification = 12 // - ) - { - // - bool result = false; - - // - if (minVerification < 7) - { - minVerification = 7; - } - - // - dir = X_DIRECTION_NONE; - - // - int bullishSum = mBullishPeaks + mBullishVales; - int bearishSum = mBearishPeaks + mBearishVales; - - // - int diff = MathAbs(bullishSum - bearishSum); - bool isDiffPassed = diff >= minVerification; - result = isDiffPassed; - if (!result) - { - return result; - } - - // - dir = bullishSum > bearishSum - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - 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 FillPivotPoints(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; - } - - /** - * Get Last Peaks Pivot Point ... - * - * @param pivot: XPVPivotPoint instance Reference ... - * - * @return ( bool ) - */ - bool GetLastPeakPivotPoint(XPVPivotPoint &pivot) - { - // - bool result = false; - - // - pivot.Clean(); - - // - XPVPivotPoint pivots[]; - int count = FillPeakPivotPoints(pivots); - result = IsValidSize(count); - if (!result) - { - return result; - } - - // - pivot = pivots[count - 1]; - - // - 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 Last Vale Pivot Point ... - * - * @param pivot: XPVPivotPoint instance Reference ... - * - * @return ( bool ) - */ - bool GetLastValePivotPoint(XPVPivotPoint &pivot) - { - // - bool result = false; - - // - pivot.Clean(); - - // - XPVPivotPoint pivots[]; - int count = FillValePivotPoints(pivots); - result = IsValidSize(count); - if (!result) - { - return result; - } - - // - pivot = pivots[count - 1]; - - // - return result; - } - - /** - * 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; - } - - /** - * Retrieve Last Pivot ... - * - * @param pivot: XPVPivot instance Reference ... - * - * @return ( bool ) - */ - bool GetLastPivot(XPVPivot &pivot) - { - // - bool result = false; - - // - pivot.Clean(); - - // - XPVPivot pivots[]; - int count = FillPivots(pivots); - if (IsValidSize(count)) - { - pivot = pivots[count - 1]; - } - - // - result = pivot.IsValid(); - - // - return result; - } - - /** - * Retrieve Active Peak Pivot ... - * - * @param pivot: XPVPivot instance Reference ... - * - * @return ( bool ) - */ - bool GetActivePeakPivot(XPVPivot &pivot) - { - // - bool result = false; - - // - pivot.Clean(); - - // - pivot = mActivePeakPivot; - - // - result = pivot.IsValid(); - - // - return result; - } - - /** - * Retrieve Active Vale Pivot ... - * - * @param pivot: XPVPivot instance Reference ... - * - * @return ( bool ) - */ - bool GetActiveValePivot(XPVPivot &pivot) - { - // - bool result = false; - - // - pivot.Clean(); - - // - pivot = mActiveValePivot; - - // - result = pivot.IsValid(); - - // - return result; - } - // // Virtuals ... @@ -2582,1035 +875,17 @@ class XC121SMCCycleHelper : public XCBase */ virtual void Default() { - // - ValidPivotRepetition(21); - 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); - - // - if (isInited) - { - // - Add( - SAR_CHANGE_DETECTED, - events // - ); - } - } - } - - // - // Detect Peaks Changes ... - - // - bool isNewPeak = conditions.x121Conditions.isNewPeak; - double peak = conditions.x121Conditions.peaksBuffer[1]; - double peakPrev = conditions.x121Conditions.peaksBuffer[2]; - bool isPeakSameAsPrev = peak == peakPrev; - 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); - - // - if (isInited) - { - // - Add( - NEW_PEAK_DETECTED, - events // - ); - } - } - } - - // - // Detect Vales Changes ... - - // - bool isNewVale = conditions.x121Conditions.isNewVale; - double vale = conditions.x121Conditions.valesBuffer[1]; - double valePrev = conditions.x121Conditions.valesBuffer[2]; - bool isValeSameAsPrev = vale == valePrev; - 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); - - // - if (isInited) - { - // - Add( - NEW_VALE_DETECTED, - events // - ); - } - } - } - - // - // Count Bullish / Bearish Peaks and Vales ... - - // - // Peaks ... - - // - if (isNewPeakOverLast) - { - // - mBullishPeaks++; - mIsLastPeakBullish = true; - } - - // - if (isNewPeakUnderLast) - { - // - mBearishPeaks++; - mIsLastPeakBullish = false; - } - - // - if (isPeakSameAsPrev) - { - // - if (mIsLastPeakBullish) - { - // - mBullishPeaks++; - mBearishPeaks--; - if (mBearishPeaks < 0) - { - mBearishPeaks = 0; - } - } - else - { - // - mBullishPeaks--; - mBearishPeaks++; - if (mBullishPeaks < 0) - { - mBullishPeaks = 0; - } - } - } - - // - // Vales ... - - // - if (isNewValeOverLast) - { - // - mBullishVales++; - mIsLastValeBullish = true; - } - - // - if (isNewValeUnderLast) - { - // - mBearishVales++; - mIsLastValeBullish = false; - } - - // - if (isValeSameAsPrev) - { - // - if (mIsLastValeBullish) - { - // - mBullishVales++; - mBearishVales--; - if (mBearishVales < 0) - { - mBearishVales = 0; - } - } - else - { - // - mBullishVales--; - mBearishVales++; - if (mBullishVales < 0) - { - mBullishVales = 0; - } - } - } - - // - // 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); - - // - if (isInited) - { - // - 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); - - // - if (isInited) - { - // - 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 && - !mActiveConsolidationZone.IsValid()) - { - // - // Initialize Consolidation Zone ... - bool isInited = mActiveConsolidationZone.Init( - changeBar.symbol, - changeBar.period, - upper, - lower, - consolidationLoopback // - ); - } - - // - if (!hasConsolidation && - mActiveConsolidationZone.IsValid()) - { - // - mActiveConsolidationZone.Update(); - bool isBreaked = mActiveConsolidationZone.IsBreaked(); - - // - if (isBreaked) - { - // - // Add Active to List ... - bool isInited = AddConsolidationZone(mActiveConsolidationZone); - if (isInited) - { - // - // Clean Active Zone ... - mActiveConsolidationZone.Clean(); - - // - Add( - CONSOLIDATION_BREAKED_DETECTED, - events // - ); - } - } - } - - // - // Draw ... - // if (mActiveConsolidationZone.IsValid()) - // { - // // - // if (mActiveConsolidationZoneObj != NULL) - // { - // mActiveConsolidationZoneObj.Delete(); - // } - - // // - // bool isCreated = mPOIDetector.mDrawer.CreateConsolidationZone( - // mActiveConsolidationZone, - // mActiveConsolidationZoneObj // - // ); - // } - } - - // - // 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 = ValidPivotRepetition(); - 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; - - // - bool isInited = AddPivotPoint(pivotPoint); - if (isInited) - { - // - Add( - PIVOT_POINT_DETECTED, - events // - ); - } - } - } - } - - // - // Calculate XPVPivot ... - int pvValidation = ValidPivotRepetition(); - if (IsValidSize(pvValidation)) - { - // - // Peak ... - mActivePeakPivot.symbol = symbol; - mActivePeakPivot.period = period; - mActivePeakPivot.type = XPV_PEAK; - - // - if (mActivePeakPivot.upper == 0 && peak > 0) - { - // - mActivePeakPivot.upper = peak; - mActivePeakPivot.lower = vale; - mActivePeakPivot.from = changeBar.time; - - // - Add( - PEAK_PIVOT_STARTED, - events // - ); - } - else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper == peak) - { - // - mActivePeakPivot.repetition++; - mActivePeakPivot.to = changeBar.time; - - // - if (mActivePeakPivot.IsValid()) - { - // - FillPivotState(mActivePeakPivot); - ValidatePivotState(mActivePeakPivot, barIndex); - } - } - else if (mActivePeakPivot.upper > 0 && mActivePeakPivot.upper != peak) - { - // - if (mActivePeakPivot.repetition >= pvValidation) - { - // - bool isInited = AddPivot(mActivePeakPivot); - if (isInited) - { - // - Add( - PEAK_PIVOT_ENDED, - events // - ); - - // - mActivePeakPivot.Clean(); - } - } - else - { - // - mActivePeakPivot.upper = peak; - mActivePeakPivot.lower = vale; - mActivePeakPivot.repetition = 0; - mActivePeakPivot.from = changeBar.time; - - // - Add( - PEAK_PIVOT_STARTED, - events // - ); - } - } - - // - // Vale ... - mActiveValePivot.symbol = symbol; - mActiveValePivot.period = period; - mActiveValePivot.type = XPV_VALE; - - // - // Peak ... - if (mActiveValePivot.lower == 0 && vale > 0) - { - // - mActiveValePivot.lower = vale; - mActiveValePivot.upper = peak; - mActiveValePivot.from = changeBar.time; - - // - Add( - VALE_PIVOT_STARTED, - events // - ); - } - else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower == vale) - { - // - mActiveValePivot.repetition++; - mActiveValePivot.to = changeBar.time; - - // - if (mActiveValePivot.IsValid()) - { - // - FillPivotState(mActiveValePivot); - ValidatePivotState(mActiveValePivot, barIndex); - } - } - else if (mActiveValePivot.lower > 0 && mActiveValePivot.lower != vale) - { - // - if (mActiveValePivot.repetition >= pvValidation) - { - // - bool isInited = AddPivot(mActiveValePivot); - if (isInited) - { - // - Add( - VALE_PIVOT_ENDED, - events // - ); - - // - mActiveValePivot.Clean(); - } - } - else - { - // - mActiveValePivot.lower = vale; - mActiveValePivot.upper = peak; - mActiveValePivot.repetition = 0; - mActiveValePivot.from = changeBar.time; - - // - Add( - VALE_PIVOT_STARTED, - events // - ); - } - } - } - } - - /** - * Detect Requirements ... - */ - void Detect(int barIndex) - { - // - if (isDetecting) - { - return; - } - - // - int start = barIndex; - int max = 576; - int validPivotRepetition = ValidPivotRepetition(); - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - // Try To Detect Valid Peaks or Vales ... - double peak = 0; - double vale = 0; - int peakRepetition = 0; - int valeRepetition = 0; - - // - int from = start; - int index = from; - int count = start + max; - - // - bool canContinue = true; - - // - // Loop Throug Peaks and Vales ... - while (canContinue) - { - // - datetime toTime = iTime( - symbol, - period, - index // - ); - - // - double iPeak = mX121Helper.GetPeak(index); - double iVale = mX121Helper.GetVale(index); - - // - // Peak ... - if (peak == 0 && iPeak > 0) - { - // - peak = iPeak; - peakRepetition = 0; - } - else if (peak > 0 && iPeak > 0 && peak == iPeak) - { - peakRepetition++; - } - else if (peak > 0 && iPeak > 0 && peak != iPeak) - { - // - if (peakRepetition >= validPivotRepetition) - { - // - datetime fromTime = iTime( - symbol, - period, - index - peakRepetition // - ); - - // - // Create XPVPivotPoint ... - XPVPivotPoint pivotPoint; - pivotPoint.value = iPeak; - pivotPoint.time = toTime; - pivotPoint.type = XPV_PEAK; - pivotPoint.repetition = peakRepetition; - if (pivotPoint.IsValid()) - { - // - AddRef( - pivotPoint, - mPivotPoints // - ); - } - - // - // Create XPVPivot ... - XPVPivot pivot; - pivot.symbol = symbol; - pivot.period = period; - pivot.from = fromTime; - pivot.to = toTime; - pivot.repetition = peakRepetition; - pivot.type = XPV_PEAK; - pivot.upper = peak; - pivot.lower = iVale; - FillPivotState(pivot); - - // - if (pivot.IsValid()) - { - // - AddRef( - pivot, - mPivots // - ); - } - } - - // - peak = iPeak; - peakRepetition = 0; - } - - // - // Vale ... - if (vale == 0 && iVale > 0) - { - // - vale = iVale; - valeRepetition = 0; - } - else if (vale > 0 && iVale > 0 && vale == iVale) - { - valeRepetition++; - } - else if (vale > 0 && iVale > 0 && vale != iVale) - { - // - if (valeRepetition >= validPivotRepetition) - { - // - datetime fromTime = iTime( - symbol, - period, - index - valeRepetition // - ); - - // - // Create XPVPivotPoint ... - XPVPivotPoint pivotPoint; - pivotPoint.value = iVale; - pivotPoint.time = toTime; - pivotPoint.type = XPV_VALE; - pivotPoint.repetition = valeRepetition; - if (pivotPoint.IsValid()) - { - // - AddRef( - pivotPoint, - mPivotPoints // - ); - } - - // - // Create XPVPivot ... - XPVPivot pivot; - pivot.symbol = symbol; - pivot.period = period; - pivot.from = fromTime; - pivot.to = toTime; - pivot.repetition = valeRepetition; - pivot.type = XPV_VALE; - pivot.upper = iPeak; - pivot.lower = vale; - FillPivotState(pivot); - - // - if (pivot.IsValid()) - { - // - AddRef( - pivot, - mPivots // - ); - } - } - - // - vale = iVale; - valeRepetition = 0; - } - - // - index++; - canContinue = index < count; - } - - // - int pivotsCount = ArraySize(mPivots); - if (IsValidSize(mPivots)) - { - ArrayReverse(mPivots); - } - - // - isDetecting = false; - } - // private: // // Props ... - // - bool mIsLastPeakBullish; - int mBullishPeaks; // Count Bullish Peaks ... - int mBearishPeaks; // Count Bearish Peaks ... - - // - bool mIsLastValeBullish; - int mBullishVales; // Count Bullish Vales ... - int mBearishVales; // Count Bearish Vales ... - - // - // 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 mActiveConsolidationZone; // Holds Actiove Consolidation Zone ... - // XCConsolidationZoneObject *mActiveConsolidationZoneObj; - - // - int mValidPivotRepetition; // Valid Pivot Point's Repetition ... - XPVPivotPoint mPivotPoints[]; // Holds Pivots ... - - // - bool isDetecting; - XPVPivot mActivePeakPivot; // Active Pivots ... - XPVPivot mActiveValePivot; // Active Pivots ... - XPVPivot mPivots[]; // Holds Active Pivot ... - // // Actions ... @@ -3766,386 +1041,5 @@ class XC121SMCCycleHelper : public XCBase 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; - } - - /** - * Add Specified Consolidation Zone to List ... - * - * @param zone: XConsolidationZone instance Reference ... - * - * @return ( bool ) - */ - bool AddConsolidationZone(XConsolidationZone &zone) - { - // - bool result = false; - - // - result = zone.IsValid(); - - // - int beforeCount = CountConsolidationZones(); - - // - AddRef( - zone, - mConsolidationZones // - ); - - // - int afterCount = CountConsolidationZones(); - - // - result = afterCount == beforeCount + 1; - if (result) - { - // - // Cleaning Up Unused Items ... - int maxAllowed = MaxAllowedSavedChanges(); - CleanupArray( - mConsolidationZones, - maxAllowed // - ); - } - - // - return result; - } - - /** - * Add Specified Pivot Point to List ... - * - * @param pivotPoint: XPVPivotPoint instance Reference ... - * - * @return ( bool ) - */ - bool AddPivotPoint(XPVPivotPoint &pivotPoint) - { - // - bool result = false; - - // - if (!pivotPoint.IsValid()) - { - return result; - } - - // - int beforeCount = CountPivotPoints(); - - // - AddRef( - pivotPoint, - mPivotPoints // - ); - - // - int afterCount = CountPivotPoints(); - - // - result = afterCount == beforeCount + 1; - if (result) - { - // - // Cleaning Up Unused Items ... - int maxAllowed = MaxAllowedSavedChanges(); - CleanupArray( - mPivotPoints, - maxAllowed // - ); - } - - // - return result; - } - - /** - * Add Specified Pivot to List ... - * - * @param pivot: XPVPivot instance Reference ... - * - * @return ( bool ) - */ - bool AddPivot(XPVPivot &pivot) - { - // - bool result = false; - - // - if (!pivot.IsValid()) - { - return result; - } - - // - int beforeCount = CountPivots(); - - // - AddRef( - pivot, - mPivots // - ); - - // - int afterCount = CountPivots(); - - // - result = afterCount == beforeCount + 1; - if (result) - { - // - // Cleaning Up Unused Items ... - int maxAllowed = MaxAllowedSavedChanges(); - CleanupArray( - mPivots, - maxAllowed // - ); - } - - // - return result; - } - // }; diff --git a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 index 4964121e..3f6ec205 100644 --- a/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.x-tradehandler.class.mq5 @@ -27,6 +27,7 @@ #include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../../Classes/x-saherelm.x-trade.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" // // Definitions ... @@ -3196,6 +3197,120 @@ class XC121SMCTradeHandler : public XCBaseAlert return result; } + /** + * Execute Specific Signal using Trade Handler ... + * + * @param signal: XSignal instance Reference ... + * @param state: ENUM_X_SIGNAL_EXECUTION_RESULT Reference for olding Signal Execution Result Reason ... + * @param ignorePolicies: Boolean ... + * + * @return ( bool ) + */ + bool ExecuteSignal( + XSignal &signal, // Signal for Execution + X121SMCStrategyConditions &conditions, // Signal Conditions + ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Execution State + bool ignorePolicies = false // Ignore Execution Policies + ) + { + // + bool result = false; + + // + // Check Signal Validation ... + result = signal.IsValid() && + conditions.IsValid(); + if (!result) + { + return result; + } + + // + // Check Policies ... + if (!ignorePolicies) + { + // + // Filter Signals if Necessary ... + result = CanExecute( + signal, + state // + ); + if (!result) + { + // + AlertSignalExecutionFailed( + signal, + state // + ); + + // + return result; + } + } + + // + // Apply Additional Volume to Signal if Provided ... + double additionalVolume = AdditionalVolume(); + if (additionalVolume > 0) + { + signal.volume += mAdditionalVolume; + } + + // + // Execute Signal ... + result = mTrader.ExecuteSignal( + signal, + state // + ); + if (result) + { + // + // Add XTradeHandler Data ... + Add(signal); + if (CanDraw()) + { + // + XCSignalObject *iObj; + mDrawer.DrawSignal(signal, iObj); + + // + XCBaseObject *conditionsObjects[]; + DrawX121SMCStrategyConditions( + conditions, + conditionsObjects, + mDrawer // + ); + } + + // + // Handle Last Executed Signal ... + HandleSignalExecuted(signal); + + // + // Alert Executed Signal ... + string msg = (signal.type == POSITION_TYPE_BUY ? "Long" : "Short") + + " Signal Provided by: " + signal.provider + + (signal.pushers > 1 ? " Pushers: " + ToString(signal.pushers) : "") + + " on: " + signal.symbol + + " in: " + ToString(signal.period) + + " Executed Successfully ..."; + Alert(msg); + } + + // + if (!result) + { + // + AlertSignalExecutionFailed( + signal, + state // + ); + } + + // + return result; + } + // // Timing Actions ... diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index ef63e458..27c444d8 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -810,6 +810,7 @@ class XC121SMCExpert : public XCBaseExpert ENUM_X_SIGNAL_EXECUTION_RESULT state; bool isExecuted = mTradeHandler.ExecuteSignal( signal, + conditions, state, false // ignore Policies ... ); diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index c7ada0df..d36aa3e7 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -22,6 +22,7 @@ // // Imports ... #include "../../Classes/x-saherelm.base.class.mq5" +#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../../Helpers/x-saherelm.x121.helper.mq5" #include "../../Libraries/x-saherelm.common.lib.mq5" #include "../../Libraries/x-saherelm.x-poi.lib.mq5" @@ -35,12 +36,7 @@ const string X121SMCStrategyToken = "X121SMC"; // const string X121SMCXTestToken = "X121XTest"; -const string X121SMCXPVOBToken = "X121XPVOB"; -const string X121SMCXPVDPToken = "X121XPVDP"; -const string X121SMCXVWPBToken = "X121XVWPB"; const string X121SMCXTWPVToken = "X121XTWPV"; -const string X121SMCXOEPVToken = "X121XOEPV"; -const string X121SMCXPVSupDemToken = "X121XPVSUPDEM"; // // X121 SMC Providers ... @@ -49,12 +45,7 @@ enum ENUM_X_121_SMC_PROVIDERS // X_121_SMC_PROVIDER_NONE, X_121_SMC_PROVIDER_XTEST, - X_121_SMC_PROVIDER_XPVOB, - X_121_SMC_PROVIDER_XPVDP, - X_121_SMC_PROVIDER_XVWPB, X_121_SMC_PROVIDER_XTWPV, - X_121_SMC_PROVIDER_XOEPV, - X_121_SMC_PROVIDER_XPVSUPDEM, }; // @@ -264,9 +255,11 @@ struct X121SMCStrategyConditions double target; string provider; ENUM_X_DIRECTION signalDir; - ENUM_X_DIRECTION marketStructureDir; // + XPriceZones priceZones; + XPriceZones decisionZones; + XMarketStructure marketStructure; // void X121SMCStrategyConditions() @@ -292,7 +285,11 @@ struct X121SMCStrategyConditions tp = 0; provider = NULL; signalDir = X_DIRECTION_NONE; - marketStructureDir = X_DIRECTION_NONE; + + // + priceZones.Clean(); + decisionZones.Clean(); + marketStructure.Clean(); } /** @@ -503,6 +500,115 @@ struct X121SMCStrategyConditions // }; +/** + * Draw X121 SMC Conditions ... + * + * @param conditions: X121SMCStrategyConditions instance Reference ... + * @param drawMarketStructure: Boolean ... + * @param drawPriceZones: Boolean ... + * @param drawDecisionZones: Boolean ... + * + * @return ( int ) + */ +int DrawX121SMCStrategyConditions( + X121SMCStrategyConditions &conditions, + XCBaseObject *&drawnObjects[], + XCPOIDrawer *drawer, + bool drawMarketStructure = true, + bool drawPriceZones = true, + bool drawDecisionZones = true // +) +{ + // + int result = 0; + + // + Clean(drawnObjects); + + // + if (drawer == NULL || + !conditions.IsValid() || + !HasDirection(conditions.signalDir)) + { + return result; + } + + // + bool isBullish = IsBullish(conditions.signalDir); + + // + bool hasPriceZones = conditions.priceZones.IsValid(); + if (hasPriceZones && + drawPriceZones) + { + // + XCBaseObject *objects[]; + int objectsCount = drawer.DrawPriceZone( + conditions.priceZones, + objects // + ); + if (IsValidSize(objectsCount)) + { + // + Copy( + objects, + drawnObjects, + false // + ); + } + } + + // + bool hasDecisionZones = conditions.decisionZones.IsValid(); + if (hasDecisionZones && + drawDecisionZones) + { + // + XCBaseObject *objects[]; + int objectsCount = drawer.DrawPriceZone( + conditions.decisionZones, + objects // + ); + if (IsValidSize(objectsCount)) + { + // + Copy( + objects, + drawnObjects, + false // + ); + } + } + + // + bool hasMarketStructure = conditions.marketStructure.IsValid(); + if (hasMarketStructure && + drawMarketStructure) + { + // + XCBaseObject *objects[]; + int objectsCount = drawer.DrawMarketStructure( + conditions.marketStructure, + objects // + ); + if (IsValidSize(objectsCount)) + { + // + Copy( + objects, + drawnObjects, + false // + ); + } + } + + // + result = ArraySize(drawnObjects); + + // + return result; +} + // // // @@ -560,35 +666,10 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) result = X121SMCXTestToken; break; - // - case X_121_SMC_PROVIDER_XPVOB: - result = X121SMCXPVOBToken; - break; - - // - case X_121_SMC_PROVIDER_XPVDP: - result = X121SMCXPVDPToken; - break; - - // - case X_121_SMC_PROVIDER_XVWPB: - result = X121SMCXVWPBToken; - break; - // case X_121_SMC_PROVIDER_XTWPV: result = X121SMCXTWPVToken; break; - - // - case X_121_SMC_PROVIDER_XOEPV: - result = X121SMCXOEPVToken; - break; - - // - case X_121_SMC_PROVIDER_XPVSUPDEM: - result = X121SMCXPVSupDemToken; - break; } // @@ -618,30 +699,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) { result = X_121_SMC_PROVIDER_XTEST; } - else if (Contains(X121SMCXPVOBToken, value)) - { - result = X_121_SMC_PROVIDER_XPVOB; - } - else if (Contains(X121SMCXPVDPToken, value)) - { - result = X_121_SMC_PROVIDER_XPVDP; - } - else if (Contains(X121SMCXVWPBToken, value)) - { - result = X_121_SMC_PROVIDER_XVWPB; - } else if (Contains(X121SMCXTWPVToken, value)) { result = X_121_SMC_PROVIDER_XTWPV; } - else if (Contains(X121SMCXOEPVToken, value)) - { - result = X_121_SMC_PROVIDER_XOEPV; - } - else if (Contains(X121SMCXPVSupDemToken, value)) - { - result = X_121_SMC_PROVIDER_XPVSUPDEM; - } // return result; diff --git a/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 index ba1637da..0bff4b7c 100644 --- a/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xtwpv.signal.lib.mq5 @@ -24,76 +24,6 @@ #include "../Classes/x-121.smc.market.cycle.helper.class.mq5" #include "../Libraries/x-121.smc.lib.mq5" -// -const string X121SMCXTWPV_Method_1_Token = "X121SMCXTWPV_1"; -const string X121SMCXTWPV_Method_2_Token = "X121SMCXTWPV_2"; -const string X121SMCXTWPV_Method_3_Token = "X121SMCXTWPV_3"; - -// -enum ENUM_X_X121SMC_XTWPV_METHODS -{ - X_X121SMC_XTWPV_METHOD_UNKNOWN, - X_X121SMC_XTWPV_METHOD_1, - X_X121SMC_XTWPV_METHOD_2, - X_X121SMC_XTWPV_METHOD_3, -}; - -// -string ToString(ENUM_X_X121SMC_XTWPV_METHODS value) -{ - // - string result = NULL; - - // - if (value == X_X121SMC_XTWPV_METHOD_UNKNOWN) - { - return result; - } - - // - switch (value) - { - // - case X_X121SMC_XTWPV_METHOD_1: - result = "Method_1"; - break; - - // - case X_X121SMC_XTWPV_METHOD_2: - result = "Method_2"; - break; - } - - // - return result; -} - -// -ENUM_X_X121SMC_XTWPV_METHODS ParseMethod(string value) -{ - // - ENUM_X_X121SMC_XTWPV_METHODS result = X_X121SMC_XTWPV_METHOD_UNKNOWN; - - // - if (!IsValid(value)) - { - return result; - } - - // - if (Contains(X121SMCXTWPV_Method_1_Token, value)) - { - result = X_X121SMC_XTWPV_METHOD_1; - } - else if (Contains(X121SMCXTWPV_Method_2_Token, value)) - { - result = X_X121SMC_XTWPV_METHOD_2; - } - - // - return result; -} - // // Definitions ... struct X121SMCStrategyXTWPVSignalConditions @@ -119,28 +49,21 @@ struct X121SMCStrategyXTWPVSignalConditions datetime triggerTime; // - double point; - XPVPivot pivot; + XMarketStructure consolidationMarketStructure; + XMarketStructure analyseMarketStructure; // - XConsolidationZone consolidationZone; + datetime newPeakAboveAtrUpperAt; + datetime newValeBelowAtrLowerAt; + datetime sarSiwtchedToBullishAt; + datetime sarSiwtchedToBearishAt; + datetime rsiCrossedOverOverSoldAt; + datetime rsiCrossedUnderOverBoughtAt; // - string method; - - // - bool hasSupportZone; - bool hasResistanceZone; - bool hasSupplyZone; - bool hasDemandZone; - bool hasOrderBlock; - bool hasFairValueGap; - XCSupportZone *supportZone; - XCResistanceZone *resistanceZone; - XCSupplyZone *supplyZone; - XCDemandZone *demandZone; - XCOrderBlock *orderBlock; - XCFVG *fairValueGap; + XPriceZones decisionZone; + XPriceZones peakPriceZone; + XPriceZones valePriceZone; // // Constructor ... @@ -257,112 +180,29 @@ struct X121SMCStrategyXTWPVSignalConditions void ExtensionClean() { // - point = 0; - pivot.Clean(); - consolidationZone.Clean(); + decisionZone.Clean(); + peakPriceZone.Clean(); + valePriceZone.Clean(); // - method = NULL; + analyseMarketStructure.Clean(); + consolidationMarketStructure.Clean(); // - CleanPriceInsideZones(); + newPeakAboveAtrUpperAt = NULL; + newValeBelowAtrLowerAt = NULL; + sarSiwtchedToBullishAt = NULL; + sarSiwtchedToBearishAt = NULL; + rsiCrossedOverOverSoldAt = NULL; + rsiCrossedUnderOverBoughtAt = NULL; } /** - * Clean Price Insie Zones ... - */ - void CleanPriceInsideZones() - { - // - hasSupportZone = false; - hasResistanceZone = false; - hasSupplyZone = false; - hasDemandZone = false; - hasOrderBlock = false; - hasFairValueGap = false; - - // - supportZone = NULL; - resistanceZone = NULL; - supplyZone = NULL; - demandZone = NULL; - orderBlock = NULL; - fairValueGap = NULL; - } - - /** - * Count Price Inside Zones ... - * - * @return ( int ) - */ - int CountPriceInsideZones() - { - // - int result = 0; - - // - if (hasSupportZone) - { - result++; - } - - // - if (hasResistanceZone) - { - result++; - } - - // - if (hasSupplyZone) - { - result++; - } - - // - if (hasDemandZone) - { - result++; - } - - // - if (hasOrderBlock) - { - result++; - } - - // - if (hasFairValueGap) - { - result++; - } - - // - return result; - } - - /** - * Check Conditions Has Price Inside Zones ... + * Check Required Market Strucutre Exists or not ... * * @return ( bool ) */ - bool HasPriceInsideZones() - { - // - bool result = false; - - // - result = IsValidSize(CountPriceInsideZones()); - - // - return result; - } - - /** - * Check Conditions Has Bullish Price Inside Zone ... - * - * @return ( bool ) - */ - bool HasBullishPriceInsideZone() + bool HasMarketStrucutre() { // bool result = false; @@ -370,14 +210,17 @@ struct X121SMCStrategyXTWPVSignalConditions // result = // - HasPriceInsideZones() && + analyseMarketStructure.IsValid() && + consolidationMarketStructure.IsValid() // - (hasDemandZone || - hasSupportZone || - (hasOrderBlock && - orderBlock.IsBullish()) || - (hasFairValueGap && - fairValueGap.IsBullish())) + && + // + analyseMarketStructure.HasTrend() && + consolidationMarketStructure.HasTrend() + // + && + // + analyseMarketStructure.bias == consolidationMarketStructure.bias // ; @@ -386,51 +229,78 @@ struct X121SMCStrategyXTWPVSignalConditions } /** - * Check Conditions Has Bearish Price Inside Zone ... + * Check if Conditions Filled ... * * @return ( bool ) */ - bool HasBearishPriceInsideZone() + bool IsFilled() { // bool result = false; + // + result = HasMarketStrucutre(); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(analyseMarketStructure.bias); + // result = - // - HasPriceInsideZones() && - // - (hasSupplyZone || - hasResistanceZone || - (hasOrderBlock && - orderBlock.IsBearish()) || - (hasFairValueGap && - fairValueGap.IsBearish())) - // - ; + isBullish + ? IsValid(newValeBelowAtrLowerAt) && + IsValid(sarSiwtchedToBullishAt) && + IsValid(rsiCrossedOverOverSoldAt) + : IsValid(newPeakAboveAtrUpperAt) && + IsValid(sarSiwtchedToBearishAt) && + IsValid(rsiCrossedUnderOverBoughtAt); // return result; } /** - * Check has Vald Pivot or not ... + * Check if Has Price Zones ... * * @return ( bool ) */ - bool HasPivot() + bool HasPriceZone() { - return pivot.IsValid(); + // + bool result = false; + + // + result = HasMarketStrucutre(); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(analyseMarketStructure.bias); + + // + result = + isBullish + ? valePriceZone.IsValid() + : peakPriceZone.IsValid(); + + // + return result; } /** - * Check Model Has Consolidation Zone or not ... + * Check if Has Decision Zones ... * * @return ( bool ) */ - bool HasConsolidationZone() + bool HasDecisionZone() { - return consolidationZone.IsValid(); + return HasPriceZone() && + decisionZone.IsValid(); } // @@ -647,134 +517,22 @@ bool DetectX121SMCXTWPVSiganlSetup( // Setup Conditions ... // - XMarketStructure consolidationMarketStructure; - bool hasConsolidationMarketStructure = - consolidationCycleHelper - .DetectMarketStructure(consolidationMarketStructure); - - // - XMarketStructure analyseMarketStructure; - bool hasAnalyseMarketStructure = - analyseCycleHelper - .DetectMarketStructure(analyseMarketStructure); - - // - // Check Same Bias ... - result = - hasAnalyseMarketStructure && - hasConsolidationMarketStructure && - analyseMarketStructure.HasTrend() && - consolidationMarketStructure.HasTrend() && - analyseMarketStructure.bias == consolidationMarketStructure.bias; - if (!result) - { - return result; - } - - // - XOHCL analyseCBar; - result = analyseCycleHelper.GetBar( - cBar, - analyseCBar // - ); - if (!result) - { - return result; - } - - // - XOHCL analysePBar; - result = analyseCBar.GetPreviousBar(analysePBar); - if (!result) - { - return result; - } - - // - double bullishFib = GetFibonacciLevel( - analyseCBar.high, - analyseCBar.low, - GetFiboLevelValue(X_FIBO_LEVEL_382), - -1 // - ); - - // - double bearishFib = GetFibonacciLevel( - analyseCBar.high, - analyseCBar.low, - GetFiboLevelValue(X_FIBO_LEVEL_382), - 1 // - ); - - // - // Detect Market Trend ... - // ENUM_X_DIRECTION trend; - // bool hasTrend = verificationCycleHelper - // .DetectTrend(trend); - // bool hasBullishTrend = hasTrend && - // IsBullish(trend); - // bool hasBearishTrend = hasTrend && - // IsBearish(trend); - // result = hasBullishTrend || - // hasBearishTrend; - // if (!result) - // { - // return result; - // } - - // - // Detect Trend Based On Peaks and Vales ... - ENUM_X_DIRECTION trend; - bool hasTrend = triggerCycleHelper - .HasPVDirection(trend); - bool hasBullishTrend = hasTrend && - IsBullish(trend); - bool hasBearishTrend = hasTrend && - IsBearish(trend); - - // - // Retrieve Active Pivots ... - - // - XPVPivot peakPivot; - bool hasPeakPivot = analyseCycleHelper - .GetActivePeakPivot(peakPivot); - - // - XPVPivot valePivot; - bool hasValePivot = analyseCycleHelper - .GetActiveValePivot(valePivot); - - // - // Check Pivot ... - bool hasPivot = conditions.HasPivot(); - if (!hasPivot) + bool hasMarketStructure = conditions.HasMarketStrucutre(); + if (!hasMarketStructure) { // - if (hasPeakPivot && !hasValePivot) - { - conditions.pivot = peakPivot; - } - else if (hasValePivot && !hasPeakPivot) - { - conditions.pivot = valePivot; - } - else if (hasPeakPivot && hasValePivot) - { - // - if (peakPivot.from > valePivot.from) - { - conditions.pivot = peakPivot; - } - else if (valePivot.from > peakPivot.from) - { - conditions.pivot = valePivot; - } - } + bool hasConsolidationMarketStructure = + consolidationCycleHelper + .DetectMarketStructure(conditions.consolidationMarketStructure); // - hasPivot = conditions.HasPivot(); - result = hasPivot; + bool hasAnalyseMarketStructure = + analyseCycleHelper + .DetectMarketStructure(conditions.analyseMarketStructure); + + // + hasMarketStructure = conditions.HasMarketStrucutre(); + result = hasMarketStructure; if (!result) { return result; @@ -782,449 +540,326 @@ bool DetectX121SMCXTWPVSiganlSetup( } // - // Update Pivot States ... - if (hasPivot) + // We Are Sure we Have Direct Structure Bias ... + isBullish = IsBullish(conditions.analyseMarketStructure.bias); + isBearish = IsBearish(conditions.analyseMarketStructure.bias); + + // + // RSI ... + double rsi = triggerConditions.x121Conditions.rsiBuffer[1]; + + // + bool isRSICrossedOverOverBought = triggerConditions.x121Conditions.isRSICrossedOverOverBought; + bool isRSICrossedUnderOverBought = triggerConditions.x121Conditions.isRSICrossedUnderOverBought; + + // + bool isRSICrossedOverOverSold = triggerConditions.x121Conditions.isRSICrossedOverOverSold; + bool isRSICrossedUnderOverSold = triggerConditions.x121Conditions.isRSICrossedUnderOverSold; + + // + // PV ... + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + bool isNewPeak = triggerConditions.x121Conditions.isNewPeak; + bool isNewVale = triggerConditions.x121Conditions.isNewVale; + + // + // ATR ... + double atr = triggerConditions.x121Conditions.atrBuffer[1]; + double atrUpper = triggerConditions.x121Conditions.atrUpperBuffer[1]; + double atrLower = triggerConditions.x121Conditions.atrLowerBuffer[1]; + + // + // SAR ... + double sar = triggerConditions.x121Conditions.sarBuffer[1]; + + // + bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish; + + // + // Complex Conditions ... + + // + bool isNewPeakAboveAtrUpper = + isNewPeak && + peak > atrUpper; + + // + bool isNewValeBelowAtrLower = + isNewVale && + vale < atrLower; + + // + // Fill Conditions ... + bool isConditionsFilled = conditions.IsFilled(); + if (!isConditionsFilled) { // - conditions.pivot.to = cTime; - analyseCycleHelper.FillPivotState(conditions.pivot); + // Cleanup ... // - // Check Pivot Renewation ... - bool hasNewPivot = - // - (hasPeakPivot && - peakPivot.from > conditions.pivot.from) || - (hasValePivot && - valePivot.from > conditions.pivot.from) - // - ; - result = !hasNewPivot; + // Sar ... + + // + // Bullish ... + if (isBullish && + isSarSwitchedToBearish && + IsValid(conditions.sarSiwtchedToBullishAt)) + { + conditions.sarSiwtchedToBullishAt = NULL; + } + + // + // Bearish ... + if (isBearish && + isSarSwitchedToBullish && + IsValid(conditions.sarSiwtchedToBearishAt)) + { + conditions.sarSiwtchedToBearishAt = NULL; + } + + // + // Rsi ... + + // + // Bullish ... + if (isBullish && + isRSICrossedUnderOverSold && + IsValid(conditions.rsiCrossedOverOverSoldAt)) + { + conditions.rsiCrossedOverOverSoldAt = NULL; + } + + // + // Bearish ... + if (isBearish && + isRSICrossedOverOverBought && + IsValid(conditions.rsiCrossedUnderOverBoughtAt)) + { + conditions.rsiCrossedUnderOverBoughtAt = NULL; + } + + // + // Atr Change ... + + // + // Bullish ... + if (isBullish && + isNewPeak && + IsValid(conditions.newValeBelowAtrLowerAt)) + { + conditions.newValeBelowAtrLowerAt = NULL; + } + + // + // Bearish ... + if (isBearish && + isNewVale && + IsValid(conditions.newPeakAboveAtrUpperAt)) + { + conditions.newPeakAboveAtrUpperAt = NULL; + } + + // + // Filling Up ... + + // + // Sar Change ... + + // + // Bullish ... + if (isBullish && + isSarSwitchedToBullish && + !IsValid(conditions.sarSiwtchedToBullishAt)) + { + conditions.sarSiwtchedToBullishAt = cTime; + } + + // + // Bearish ... + if (isBearish && + isSarSwitchedToBearish && + !IsValid(conditions.sarSiwtchedToBearishAt)) + { + conditions.sarSiwtchedToBearishAt = cTime; + } + + // + // Rsi Change ... + + // + // Bullish ... + if (isBullish && + isRSICrossedOverOverSold && + !IsValid(conditions.rsiCrossedOverOverSoldAt)) + { + conditions.rsiCrossedOverOverSoldAt = cTime; + } + + // + // Bearish ... + if (isBearish && + isRSICrossedUnderOverBought && + !IsValid(conditions.rsiCrossedUnderOverBoughtAt)) + { + conditions.rsiCrossedUnderOverBoughtAt = cTime; + } + + // + // Atr Change ... + // New Peaks and Vale ... + + // + // Bullish ... + if (isBullish && + isNewValeBelowAtrLower && + !IsValid(conditions.newValeBelowAtrLowerAt)) + { + conditions.newValeBelowAtrLowerAt = cTime; + } + + // + // Bearish ... + if (isBearish && + isNewPeakAboveAtrUpper && + !IsValid(conditions.newPeakAboveAtrUpperAt)) + { + conditions.newPeakAboveAtrUpperAt = cTime; + } + + // + isConditionsFilled = conditions.IsFilled(); + result = isConditionsFilled; if (!result) { - // - conditions.pivot.Clean(); return result; } } // - // XOHCL Conditions ... - - // - // Fibo Pressure ... - ENUM_X_DIRECTION pBarFiboPressureDir; - bool pBarHasFiboPressure = triggerCycleHelper - .mBarAnalyser - .HasFiboPressure( - pBar, - pBarFiboPressureDir // - ); - bool isPBarHasBullishFiboPressure = - pBarHasFiboPressure && - IsBullish(pBarFiboPressureDir); - bool isPBarHasBearishFiboPressure = - pBarHasFiboPressure && - IsBearish(pBarFiboPressureDir); - - // - // Rejection ... - ENUM_X_DIRECTION pBarRejectionDir; - bool isPBarRejected = triggerCycleHelper - .mBarAnalyser - .IsRejectionBar( - pBar, - pBarRejectionDir, - 0 // - ); - bool isPBarBullishRejected = - isPBarRejected && - IsBullish(pBarRejectionDir); - bool isPBarBearishRejected = - isPBarRejected && - IsBearish(pBarRejectionDir); - - // - // Momentum ... - ENUM_X_DIRECTION cBarMomentumDir; - bool isCBarMomentumBar = triggerCycleHelper - .mBarAnalyser - .IsMomentumBar( - cBar, - cBarMomentumDir, - 0 // - ); - bool isCBarBullishMomentumBar = - isCBarMomentumBar && - IsBullish(cBarMomentumDir); - bool isCBarBearishMomentumBar = - isCBarMomentumBar && - IsBearish(cBarMomentumDir); - - // - // Engulfing ... - ENUM_X_DIRECTION cBarEngulfDir; - bool isCBarEngulfed = triggerCycleHelper - .mBarAnalyser - .IsEngulfBar( - cBar, - cBarEngulfDir, - 0 // - ); - bool isCBarBullishEngulfed = - isCBarEngulfed && - IsBullish(cBarEngulfDir); - bool isCBarBearishEngulfed = - isCBarEngulfed && - IsBearish(cBarEngulfDir); - - // - // Helper cBar Conditions ... - bool isBearishFiboPassed = bullishFib <= conditions.pivot.lower; - bool isBullishFiboPassed = bearishFib >= conditions.pivot.upper; - - // - // Detect a Zone Which Price Inside it ... - // Helper (Optional) ... - conditions.CleanPriceInsideZones(); - bool hasPriceInsideZones = conditions.HasPriceInsideZones(); - int priceInsideZonesCount = conditions.CountPriceInsideZones(); - if (!hasPriceInsideZones) + // Fill Price Zones ... + bool hasPriceZone = conditions.HasPriceZone(); + if (!hasPriceZone) { // - hasPriceInsideZones = DetectPriceInsideZones( - verificationState, - cBar, - priceInsideZonesCount, - conditions.hasSupportZone, - conditions.supportZone, - conditions.hasResistanceZone, - conditions.resistanceZone, - conditions.hasSupplyZone, - conditions.supplyZone, - conditions.hasDemandZone, - conditions.demandZone, - conditions.hasOrderBlock, - conditions.orderBlock, - conditions.hasFairValueGap, - conditions.fairValueGap // - ); - - // - priceInsideZonesCount = conditions.CountPriceInsideZones(); - } - - // - // Check Price Inside Consolidation Zone ... - XConsolidationZone cZone; - bool hasConsolidationZone = conditions - .HasConsolidationZone(); - if (!hasConsolidationZone) - { - // - hasConsolidationZone = triggerCycleHelper - .GetLastConsolidationZone(cZone); - // - if (!hasConsolidationZone) + if (isBullish) { // - XConsolidationZone cZones[]; - int count = triggerCycleHelper - .FillConsolidationZones(cZones); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XConsolidationZone iZone = cZones[i]; - - // - XCZone *iCZone; - bool isInited = ToZone(iZone, iCZone); - if (!isInited) - { - continue; - } - - // - bool isValid = IsPriceInsideZone( - cBar, - iCZone // - ); - if (isValid) - { - cZone = iZone; - } - } - } + XPriceZones vPZone; + bool hasValeInsideZone = CalculatePriceInsideZones( + vPZone, + analyseState, + vale // + ); // - conditions.consolidationZone = cZone; - hasConsolidationZone = conditions - .HasConsolidationZone(); + XPriceZones cbPZone; + bool hasPriceInsideZone = CalculatePriceInsideZones( + cbPZone, + analyseState, + cBar // + ); + + // + if (hasValeInsideZone && + hasPriceInsideZone && + vPZone.IsBullish() && + cbPZone.IsBullish()) + { + conditions.valePriceZone = cbPZone; + } + } + else if (isBearish) + { + // + XPriceZones pPZone; + bool hasPeakInsideZone = CalculatePriceInsideZones( + pPZone, + analyseState, + peak // + ); + + // + XPriceZones cbPZone; + bool hasPriceInsideZone = CalculatePriceInsideZones( + cbPZone, + analyseState, + cBar // + ); + + // + if ( + hasPeakInsideZone && + hasPriceInsideZone && + pPZone.IsBearish() && + cbPZone.IsBearish()) + { + conditions.peakPriceZone = cbPZone; + } + } + + // + hasPriceZone = conditions.HasPriceZone(); + result = hasPriceZone; + if (!result) + { + return result; } } - if (hasConsolidationZone) - { - conditions.consolidationZone = cZone; - } // - // PV Conditions ... - - // - double analysePeak = analyseConditions.x121Conditions.peaksBuffer[1]; - double analysePeakPrev = analyseConditions.x121Conditions.peaksBuffer[2]; - double analysePeakDiff = MathAbs(analysePeakPrev - analysePeak); - - // - bool isNewAnalysePeak = analyseConditions.x121Conditions.isNewPeak; - bool isNewAnalysePeakOverLast = analyseConditions.x121Conditions.isNewPeakOverLast; - bool isNewAnalysePeakUnderLast = analyseConditions.x121Conditions.isNewPeakUnderLast; - - // - double analyseVale = analyseConditions.x121Conditions.valesBuffer[1]; - double analyseValePrev = analyseConditions.x121Conditions.valesBuffer[2]; - double analyseValeDiff = MathAbs(analyseValePrev - analyseVale); - - // - bool isNewAnalyseVale = analyseConditions.x121Conditions.isNewVale; - bool isNewAnalyseValeOverLast = analyseConditions.x121Conditions.isNewValeOverLast; - bool isNewAnalyseValeUnderLast = analyseConditions.x121Conditions.isNewValeUnderLast; - - // - double triggerPeak = triggerConditions.x121Conditions.peaksBuffer[1]; - double triggerVale = triggerConditions.x121Conditions.valesBuffer[1]; - - // - bool isNewTriggerPeak = triggerConditions.x121Conditions.isNewPeak; - bool isNewTriggerPeakOverLast = triggerConditions.x121Conditions.isNewPeakOverLast; - bool isNewTriggerPeakUnderLast = triggerConditions.x121Conditions.isNewPeakUnderLast; - - // - bool isNewTriggerVale = triggerConditions.x121Conditions.isNewVale; - bool isNewTriggerValeOverLast = triggerConditions.x121Conditions.isNewValeOverLast; - bool isNewTriggerValeUnderLast = triggerConditions.x121Conditions.isNewValeUnderLast; - - // - int condition2MinPVDiffPoint = 30; - bool isAnalysePeakDiffPointPassed = analysePeakDiff >= (condition2MinPVDiffPoint * points); - bool isAnalyseValeDiffPointPassed = analyseValeDiff >= (condition2MinPVDiffPoint * points); - - // - // DONCHAIN Conditions ... - - // - double analyseDonOpenUpper = analyseConditions.x121Conditions.donOpenUpperBuffer[1]; - double analyseDonOpenLower = analyseConditions.x121Conditions.donOpenLowerBuffer[1]; - - // - double analyseDonHighUpper = analyseConditions.x121Conditions.donHighUpperBuffer[1]; - double analyseDonHighLower = analyseConditions.x121Conditions.donHighLowerBuffer[1]; - - // - double analyseDonCloseUpper = analyseConditions.x121Conditions.donCloseUpperBuffer[1]; - double analyseDonCloseLower = analyseConditions.x121Conditions.donCloseLowerBuffer[1]; - - // - double analyseDonLowUpper = analyseConditions.x121Conditions.donLowUpperBuffer[1]; - double analyseDonLowLower = analyseConditions.x121Conditions.donLowLowerBuffer[1]; - - // - // OPEN ... - double triggerDonOpenUpper = triggerConditions.x121Conditions.donOpenUpperBuffer[1]; - double triggerDonOpenLower = triggerConditions.x121Conditions.donOpenLowerBuffer[1]; - double triggerDonOpenUpperPrev = triggerConditions.x121Conditions.donOpenUpperBuffer[2]; - double triggerDonOpenLowerPrev = triggerConditions.x121Conditions.donOpenLowerBuffer[2]; - - // - // HIGH ... - double triggerDonHighUpper = triggerConditions.x121Conditions.donHighUpperBuffer[1]; - double triggerDonHighLower = triggerConditions.x121Conditions.donHighLowerBuffer[1]; - double triggerDonHighUpperPrev = triggerConditions.x121Conditions.donHighUpperBuffer[2]; - double triggerDonHighLowerPrev = triggerConditions.x121Conditions.donHighLowerBuffer[2]; - - // - // CLOSE ... - double triggerDonCloseUpper = triggerConditions.x121Conditions.donCloseUpperBuffer[1]; - double triggerDonCloseLower = triggerConditions.x121Conditions.donCloseLowerBuffer[1]; - double triggerDonCloseUpperPrev = triggerConditions.x121Conditions.donCloseUpperBuffer[2]; - double triggerDonCloseLowerPrev = triggerConditions.x121Conditions.donCloseLowerBuffer[2]; - - // - // LOW ... - double triggerDonLowUpper = triggerConditions.x121Conditions.donLowUpperBuffer[1]; - double triggerDonLowLower = triggerConditions.x121Conditions.donLowLowerBuffer[1]; - double triggerDonLowUpperPrev = triggerConditions.x121Conditions.donLowUpperBuffer[2]; - double triggerDonLowLowerPrev = triggerConditions.x121Conditions.donLowLowerBuffer[2]; - - // - double triggerAtr = triggerConditions.x121Conditions.atrBuffer[1]; - double triggerUpperAtr = triggerConditions.x121Conditions.atrUpperBuffer[1]; - double triggerLowerAtr = triggerConditions.x121Conditions.atrLowerBuffer[1]; - - // - bool isNewTriggerPeakOverAtrUpper = - // - isNewTriggerPeak && - triggerPeak > triggerUpperAtr - // - ; - - // - bool isNewTriggerValeUnderAtrLower = - // - isNewTriggerVale && - triggerVale < triggerLowerAtr - // - ; - - // - if (isNewTriggerPeakOverAtrUpper || - isNewTriggerValeUnderAtrLower) - { - Print("ATR Break ..."); - } - - // - // Method 1 ... - - // - // Bullish Conditions 1 ... - bool bullishConditions1 = - // - false && - hasBullishTrend && - isBullishFiboPassed && - hasConsolidationZone && - analyseCBar.IsBullish() && - isNewAnalysePeakOverLast && - conditions.pivot.upper < analysePeak && - conditions.pivot.upper < analyseCBar.GetUp() && - conditions.pivot.upper > analyseCBar.GetDown() - // - ; - if (bullishConditions1) + // Check for Decision ... + bool hasDecision = conditions.HasDecisionZone(); + if (!hasDecision) { // - conditions.point = conditions.pivot.upper; - conditions.method = ToString(X_X121SMC_XTWPV_METHOD_1); + if (isBullish) + { + // + XPriceZones pZone; + bool hasPZone = CalculatePriceInsideZones( + pZone, + decisionState, + vale // + ); + + // + if (hasPZone && + pZone.IsBullish()) + { + conditions.decisionZone = pZone; + } + } + else if (isBearish) + { + // + XPriceZones pZone; + bool hasPZone = CalculatePriceInsideZones( + pZone, + decisionState, + peak // + ); + + // + if (hasPZone && + pZone.IsBearish()) + { + conditions.decisionZone = pZone; + } + } + + // + hasDecision = conditions.HasDecisionZone(); + result = hasDecision; + if (!result) + { + return result; + } } - // - // Bearish Conditions 1 ... - bool bearishConditions1 = - // - false && - hasBearishTrend && - isBearishFiboPassed && - hasConsolidationZone && - analyseCBar.IsBearish() && - isNewAnalyseValeUnderLast && - conditions.pivot.lower > analyseVale && - conditions.pivot.lower < analyseCBar.GetUp() && - conditions.pivot.lower > analyseCBar.GetDown() - // - ; - if (bearishConditions1) - { - // - conditions.point = conditions.pivot.lower; - conditions.method = ToString(X_X121SMC_XTWPV_METHOD_1); - } - - // - // Method 2 ... - - // - // Bullish Conditions 2 ... - bool bullishConditions2 = - // - false && - hasBullishTrend && - isNewAnalyseValeOverLast && - isAnalyseValeDiffPointPassed && - analyseDonCloseLower > analyseVale - // - ; - if (bullishConditions2) - { - // - conditions.point = analyseVale; - conditions.method = ToString(X_X121SMC_XTWPV_METHOD_2); - } - - // - // Bearish Conditions 2 ... - bool bearishConditions2 = - // - false && - hasBearishTrend && - isNewAnalysePeakUnderLast && - isAnalysePeakDiffPointPassed && - analyseDonCloseUpper > analysePeak - // - ; - if (bearishConditions2) - { - // - conditions.point = analysePeak; - conditions.method = ToString(X_X121SMC_XTWPV_METHOD_2); - } - - // - // Method 3 ... - - // - // Bullish Conditions 3 ... - bool bullishConditions3 = - // - false - // - ; - if (bullishConditions3) - { - // - conditions.point = analyseVale; - conditions.method = ToString(X_X121SMC_XTWPV_METHOD_3); - } - - // - // Bearish Conditions 3 ... - bool bearishConditions3 = - // - false - // - ; - if (bearishConditions3) - { - // - conditions.point = analysePeak; - conditions.method = ToString(X_X121SMC_XTWPV_METHOD_3); - } - - // - // Summary Conditions ... - - // - isBullish = - // - bullishConditions1 || - bullishConditions2 || - bullishConditions3 - // - ; - - // - isBearish = - // - bearishConditions1 || - bearishConditions2 || - bearishConditions3 - // - ; - // result = isBullish || isBearish; @@ -1482,41 +1117,6 @@ bool DetectX121SMCXTWPVSiganlTrigger( // // Detect Nearest Pivot Point ... - XPVPivotPoint pivotPoints[]; - XPVPivotPoint nearestPivotPoint; - bool hasNearestPivotPoint = false; - int pivotPointsCount = triggerCycleHelper - .FillPivotPoints(pivotPoints); - if (IsValidSize(pivotPointsCount)) - { - // - for (int i = 0; i < pivotPointsCount; i++) - { - // - XPVPivotPoint iPoint = pivotPoints[i]; - - // - bool canSet = - (isBullish - ? iPoint.value < conditions.point - : iPoint.value > conditions.point) - // - && - // - (!nearestPivotPoint.IsValid() - ? true - : isBullish - ? nearestPivotPoint.value > iPoint.value - : nearestPivotPoint.value < iPoint.value); - if (canSet) - { - nearestPivotPoint = iPoint; - } - } - - // - hasNearestPivotPoint = nearestPivotPoint.IsValid(); - } // // Detect Target ... @@ -1550,178 +1150,46 @@ bool DetectX121SMCXTWPVSiganlTrigger( // // Filling SL Candidates ... - double atr = triggerConditions.x121Conditions.atrBuffer[1]; // double sls[]; // - bool hasConsolidationZone = conditions.HasConsolidationZone(); - if (hasConsolidationZone) + double atr = triggerConditions.x121Conditions.atrBuffer[1]; + double peak = triggerConditions.x121Conditions.peaksBuffer[1]; + double vale = triggerConditions.x121Conditions.valesBuffer[1]; + + // + if (isBullish) { // - if (isBullish) + double lowerVale = triggerCycleHelper.mX121Helper.GetLowerVale(vale); + if (lowerVale > 0) { + // Add( - conditions.consolidationZone.lower, - sls // - ); - } - else - { - Add( - conditions.consolidationZone.upper, + lowerVale, sls // ); } } - if (hasNearestPivotPoint) + else if (isBearish) { - Add( - nearestPivotPoint.value, - sls // - ); + // + double higherPeak = triggerCycleHelper.mX121Helper.GetHigherPeak(peak); + if (higherPeak > 0) + { + // + Add( + higherPeak, + sls // + ); + } } + + // if (ArraySize(sls) == 0) { - // - double pointsDiff = (10 * points); - double pointsPlus = conditions.point + pointsDiff; - double pointsMinus = conditions.point - pointsDiff; - - // - // Force SL ... - Add( - conditions.point, - sls // - ); - - // - Add( - pointsPlus, - sls // - ); - - // - Add( - pointsMinus, - sls // - ); - - // - Add( - oppositTarget, - sls // - ); - } - - // - bool hasPriceInsideZones = conditions.HasPriceInsideZones(); - bool hasBullishPriceInsideZone = conditions.HasBullishPriceInsideZone(); - bool hasBearishPriceInsideZone = conditions.HasBearishPriceInsideZone(); - - // - if ( - isBullish && - hasPriceInsideZones && - hasBullishPriceInsideZone // - ) - { - // - // Demand ... - if (conditions.hasDemandZone) - { - // - Add( - conditions.demandZone.Lower(), - sls // - ); - } - - // - // Support ... - if (conditions.hasSupportZone) - { - // - Add( - conditions.supportZone.Lower(), - sls // - ); - } - - // - // Order Block ... - if (conditions.hasOrderBlock) - { - // - Add( - conditions.orderBlock.Lower(), - sls // - ); - } - - // - // Fair Value Gap ... - if (conditions.hasFairValueGap) - { - // - Add( - conditions.fairValueGap.Lower(), - sls // - ); - } - } - - // - if ( - isBearish && - hasPriceInsideZones && - hasBearishPriceInsideZone // - ) - { - // - // Supply ... - if (conditions.hasSupplyZone) - { - // - Add( - conditions.supplyZone.Upper(), - sls // - ); - } - - // - // Resistance ... - if (conditions.hasResistanceZone) - { - // - Add( - conditions.resistanceZone.Upper(), - sls // - ); - } - - // - // Order Block ... - if (conditions.hasOrderBlock) - { - // - Add( - conditions.orderBlock.Upper(), - sls // - ); - } - - // - // Fair Value Gap ... - if (conditions.hasFairValueGap) - { - // - Add( - conditions.fairValueGap.Upper(), - sls // - ); - } } // @@ -1751,12 +1219,15 @@ bool DetectX121SMCXTWPVSiganlTrigger( ? entry + targetDelta : entry - targetDelta; + // + target = 0; + // } // conditions.sl = sl; - conditions.target = 0; // target; + conditions.target = target; conditions.triggerTime = cTime; conditions.type = isBullish ? X_POSITION_TYPE_LONG @@ -1766,51 +1237,12 @@ bool DetectX121SMCXTWPVSiganlTrigger( return result; } -/** - * Draw Conditions Pivot Zone ... - * - * @param conditions: X121SMCStrategyXTWPVSignalConditions instance Reference ... - * @param drawer: XCPOIDrawer pointer ... - * @param drawnObjects: XCBaseObject instance Reference Collection ... - * @param drawState: Boolean ... - * @param drawTicksZone: 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 ... - * - * @return ( int ) - */ -int DrawXTWPVPivotZone( +// +// Draw Signal ... +int DrawX121SMCXTWPVSiganl( X121SMCStrategyXTWPVSignalConditions &conditions, - XCPOIDrawer *drawer, XCBaseObject *&drawnObjects[], - bool drawState = false, - bool drawTicksZone = 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 // + XCPOIDrawer *drawer // ) { // @@ -1820,34 +1252,92 @@ int DrawXTWPVPivotZone( Clean(drawnObjects); // - if (drawer == NULL || - !conditions.HasPivot()) + if (drawer == NULL) { return result; } // - drawer.DrawPivot( + bool isSetuped = conditions.IsSetuped(); + if (!isSetuped) + { + return result; + } + + // + bool isBullish = IsBullish(conditions.dir); + + // + XCBaseObject *priceZoneObjs[]; + XCBaseObject *decisionZoneObjs[]; + XCBaseObject *marketStructureObjs[]; + + // + bool hasMarketStructure = conditions.HasMarketStrucutre(); + if (hasMarketStructure) + { + // // + // drawer.DrawMarketStructure( + // conditions.analyseMarketStructure, + // marketStructureObjs // + // ); + } + + // + bool hasPriceZone = conditions.HasPriceZone(); + if (hasPriceZone) + { // - conditions.pivot, + XPriceZones pZone; + if (isBullish) + { + pZone = conditions.valePriceZone; + } + else + { + pZone = conditions.peakPriceZone; + } + + // + drawer.DrawPriceZone( + pZone, + priceZoneObjs, + conditions.dir // + ); + } + + // + bool hasDecisionZone = conditions.HasDecisionZone(); + if (hasDecisionZone) + { + // + drawer.DrawPriceZone( + conditions.decisionZone, + decisionZoneObjs + // , + // conditions.dir // + ); + } + + // + Copy( + priceZoneObjs, drawnObjects, - // - drawState, - drawTicksZone, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // + false // + ); + + // + Copy( + decisionZoneObjs, + drawnObjects, + false // + ); + + // + Copy( + marketStructureObjs, + drawnObjects, + false // ); // @@ -1857,204 +1347,4 @@ int DrawXTWPVPivotZone( return result; } -/** - * Drw Conditions Price Inside Zones ... - * - * @param conditions: X121SMCStrategyXTWPVSignalConditions instance Reference ... - * @param drawer: XCPOIDrawer pointer ... - * @param drawnObjects: XCBaseObject instance Reference Collection ... - * - * @return ( int ) - */ -int DrawTWPVPriceInsideZones( - X121SMCStrategyXTWPVSignalConditions &conditions, - XCPOIDrawer *drawer, - XCBaseObject *&drawnObjects[] // -) -{ - // - int result = 0; - - // - Clean(drawnObjects); - - // - if ( - drawer == NULL || - !conditions.HasPriceInsideZones()) - { - return result; - } - - // - // Support ... - if (conditions.hasSupportZone) - { - // - XCSupportZoneObject *iObj; - bool isCreated = drawer.CreateSupportZone( - conditions.supportZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // Resistance ... - if (conditions.hasResistanceZone) - { - // - XCResistanceZoneObject *iObj; - bool isCreated = drawer.CreateResistanceZone( - conditions.resistanceZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // Supply ... - if (conditions.hasSupplyZone) - { - // - XCSupplyZoneObject *iObj; - bool isCreated = drawer.CreateSupplyZone( - conditions.supplyZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // Demand ... - if (conditions.hasDemandZone) - { - // - XCDemandZoneObject *iObj; - bool isCreated = drawer.CreateDemandZone( - conditions.demandZone, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - - // - // Order Block ... - if (conditions.hasOrderBlock) - { - // - bool isBullish = conditions.orderBlock.IsBullish(); - if (isBullish) - { - // - XCBullishOrderBlockObject *iObj; - bool isCreated = drawer.CreateBullishOrderBlock( - conditions.orderBlock, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - else - { - // - XCBearishOrderBlockObject *iObj; - bool isCreated = drawer.CreateBearishOrderBlock( - conditions.orderBlock, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - - // - // FairValueGap ... - if (conditions.hasFairValueGap) - { - // - bool isBullish = conditions.fairValueGap.IsBullish(); - if (isBullish) - { - // - XCBullishFairValueGapObject *iObj; - bool isCreated = drawer.CreateBullishFairValueGap( - conditions.fairValueGap, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - else - { - // - XCBearishFairValueGapObject *iObj; - bool isCreated = drawer.CreateBearishFairValueGap( - conditions.fairValueGap, - iObj // - ); - if (isCreated) - { - // - Add( - (XCBaseObject *)iObj, - drawnObjects // - ); - } - } - } - - // - result = ArraySize(drawnObjects); - - // - return result; -} - // diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 248785d0..ced2eb0a 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -285,9 +285,9 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy { // // TODO: Remove this ... - XCSignalObject *iObj; - mPOIDrawer.DrawSignal(signal, iObj); - Print(""); + // XCSignalObject *iObj; + // mPOIDrawer.DrawSignal(signal, iObj); + // Print(""); } // @@ -495,82 +495,6 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy setupDir = mXTWPVConditions.dir; setupTime = mXTWPVConditions.setupTime; } - - // - // Handle Required Drawings ... - bool hasPivot = mXTWPVConditions.HasPivot(); - bool hasPriceInsideZone = mXTWPVConditions.HasPriceInsideZones(); - bool hasConsolidationZone = mXTWPVConditions.HasConsolidationZone(); - bool canDraw = hasPivot || - hasPriceInsideZone || - hasConsolidationZone; - if (canDraw) - { - // - ClearDraws(); - - // - // Draw Consolidation Zone ... - if (hasConsolidationZone) - { - // - XCConsolidationZoneObject *iObj; - bool isCreated = mPOIDrawer.CreateConsolidationZone( - mXTWPVConditions.consolidationZone, - iObj // - ); - if (isCreated) - { - AddObjectIfNotExists(iObj); - } - } - - // - // Draw Pivot Zone ... - if (hasPivot) - { - // - XCBaseObject *drawnObjects[]; - int drawnObjectsCount = DrawXTWPVPivotZone( - mXTWPVConditions, - mPOIDrawer, - drawnObjects, - false, // Draw State ... - false, // Draw Ticks Zone ... - true, // Ignore SwingHighs ... - true, // Ignore SwingLows ... - true, // Ignore SupportZones ... - true, // Ignore ResistanceZones ... - true, // Ignore SupplyZones ... - true, // Ignore DemandZones ... - true, // Ignore BullishOrderBlocks ... - true, // Ignore BearishOrderBlocks ... - true, // Ignore BullishFairValueGaps ... - true, // Ignore BearishFairValueGaps ... - true, // Ignore BullishRejectionBars ... - true, // Ignore BearishRejectionBars ... - true, // Ignore BullishMomentumBars ... - true // Ignore BearishMomentumBars ... - ); - AddObjectsIfNotExists(drawnObjects); - } - - // - // Draw Price Inside Zones ... - if (hasPriceInsideZone) - { - // - XCBaseObject *drawnObjects[]; - int drawnObjectsCount = DrawTWPVPriceInsideZones( - mXTWPVConditions, - mPOIDrawer, - drawnObjects // - ); - AddObjectsIfNotExists(drawnObjects); - } - } - - // result = isSetuped; if (!result) { @@ -628,6 +552,18 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy conditions.sl = mXTWPVConditions.sl; conditions.target = mXTWPVConditions.target; + // + conditions.decisionZones = mXTWPVConditions.decisionZone; + conditions.marketStructure = mXTWPVConditions.analyseMarketStructure; + if (isBullish) + { + conditions.priceZones = mXTWPVConditions.valePriceZone; + } + else + { + conditions.priceZones = mXTWPVConditions.peakPriceZone; + } + // mXTWPVConditions.Clean();