From 2c4a4dc5e5cb5615f59ba96ee7a99c6a9f051c16 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 30 Oct 2025 23:48:14 +0330 Subject: [PATCH] last ... --- ...-saherelm.xfima.signaller.class copy 3.mq5 | 3780 +++++++++++++++++ .../Classes/x-saherelm.xfima.parser.class.mq5 | 241 ++ .../x-saherelm.xfima.signaller.class.mq5 | 1222 ++++-- .../x-saherelm.xfima.x-poi.detector.class.mq5 | 114 +- 4 files changed, 4992 insertions(+), 365 deletions(-) create mode 100644 Documents/BKP/XFIMA Signals/x-saherelm.xfima.signaller.class copy 3.mq5 diff --git a/Documents/BKP/XFIMA Signals/x-saherelm.xfima.signaller.class copy 3.mq5 b/Documents/BKP/XFIMA Signals/x-saherelm.xfima.signaller.class copy 3.mq5 new file mode 100644 index 00000000..6283fb86 --- /dev/null +++ b/Documents/BKP/XFIMA Signals/x-saherelm.xfima.signaller.class copy 3.mq5 @@ -0,0 +1,3780 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class +// ------------------------------------------------- +// Name: XCXFIMASignaller ... +// Description: XFIMA Signaller Class ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFIMA Signaller Class" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.x-signaller.class.mq5" +#include "../../Helpers/x-saherelm.xfima.helper.mq5" +#include "../Classes/x-saherelm.xfima.parser.class.mq5" +#include "../Classes/x-saherelm.xfima.x-poi.detector.class.mq5" +#include "../Classes/x-saherelm.xfima.x-poi.drawer.class.mq5" + +// +// Implementation ... + +// +// Base XFIMA base Signaller ... +class XCXFIMABaseSignaller : public XCBaseSignaller +{ + // + // Public ... + public: + // + // Props ... + + // + CArrayObj drawnObjects; // Drawing Objects Holder ... + XFIMAInputs fimaInputs; // XFIMA Inputs ... + XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... + XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ... + XCXFIMAHelperParser *fimaParser; // XFIMA Helper Parser ... + XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ... + XFIMAMarketStructureConfig structureConfig; // XFIMA Market Structure Detector Config ... + XFIMAMarketStructureDrawerConfig structureDrawConfig; // XFIMA Market Structure Draw Config ... + + // + // Constructor ... + XCXFIMABaseSignaller( + string _name, // Name ... + string _symbol, // Symbol ... + ENUM_TIMEFRAMES _period, // Period ... + XFIMAInputs &_fimaInputs, // XFIMAInputs ... + bool _processAllTicks = false, // Process All Ticks ... + double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... + double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... + double _defaultSignalVolume = 0.01 // Default Signal Volume ... + ) : XCBaseSignaller(_name, + _symbol, + _period, + _processAllTicks, + _defaultSignalR2R, + _defaultSignalRiskInPoint, + _defaultSignalVolume // + ) + { + // + // Instantiating XFIMA Indicator Helper Class ... + if (_fimaInputs.IsValid()) + { + // + fimaHelper = new XCXFIMAHelper(); + bool isInited = fimaHelper.Init( + _symbol, + _period, + _fimaInputs // + ); + if (isInited) + { + fimaInputs = _fimaInputs; + } + else + { + // + delete fimaHelper; + ZeroMemory(fimaHelper); + } + } + + // + // Instantiate XFIMA Helper Parser ... + fimaParser = new XCXFIMAHelperParser(fimaHelper); + + // + poiDrawer = new XCXFIMAPOIDrawer(); + poiDetector = new XCXFIMAPOIDetector(fimaHelper, fimaParser); + + // + // Configure ... + structureConfig.Default(); + structureDrawConfig.Default(); + } + + // + // Deconstructor ... + ~XCXFIMABaseSignaller() + { + Destroy(); + } + + // + // Overrides ... + + // + // Actions ... + + /** + * Destroy ... + */ + void Destroy() + { + // + BeforeDestroy(); + + // + fimaInputs.Clean(); + + // + delete fimaHelper; + ZeroMemory(fimaHelper); + + // + delete poiDrawer; + ZeroMemory(poiDrawer); + + // + delete poiDetector; + ZeroMemory(poiDetector); + + // + structureConfig.Clean(); + structureDrawConfig.Clean(); + } + + // + // Virtuals ... + + /** + * Before Destroy ... + */ + void virtual BeforeDestroy() + { + } + + /** + * Processing Tick ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessTick(int barIndex = 0) + { + } + + /** + * Processing New Bar ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessNewBar(int barIndex = 0) + { + } + + /** + * Check Guards Based on MarketConditions ... + * + * @param guards: XGuard, reference collection to holds result ... + * @param positions: XPosition, reference collection to provides positions ... + * @param barIndex: int + * + * @return ( int ) + */ + int virtual CheckForGuard( + XGuard &guards[], + XPosition &positions[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + SpecifiedClean(guards); + + // + result = ArraySize(guards); + + // + return result; + } + + /** + * Check Additional Validations on Childs Instances ... + * + * @return ( bool virtual ) + */ + bool virtual CheckAdditionslSignallerValidations() + { + // + bool result = false; + + // + // Validate Fima Helper Requirements ... + result = fimaInputs.IsValid() && + fimaHelper != NULL && + poiDetector != NULL; + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Normalizing Signal by Signaller Custom Props ... + * + * @param signal: XSignal ... + */ + void virtual NormalizeSignal(XSignal &signal) + { + } + + // + // Protected ... + protected: + // + + // + // Protected Actions ... + + // + // Private ... + private: + // +}; + +// +// XFIMA Strategy 2 Signaller Class ... +class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructor ... + XCXFIMAStrategy1Signaller( + string _symbol, // Symbol ... + ENUM_TIMEFRAMES _period, // Period ... + XFIMAInputs &_fimaInputs, // XFIMAInputs ... + bool _processAllTicks = false, // Process All Ticks ... + double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... + double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... + double _defaultSignalVolume = 0.01 // Default Signal Volume ... + ) : XCXFIMABaseSignaller("XFIMA1", + _symbol, + _period, + _fimaInputs, + _processAllTicks, + _defaultSignalR2R, + _defaultSignalRiskInPoint, + _defaultSignalVolume // + ) + { + // + // Configure ... + drawZones = false; + drawIZones = false; + drawTrends = false; + drawSCTrend = false; + drawMCTrend = false; + drawLCTrend = false; + drawHCTrend = false; + drawSupport = false; + drawISupport = false; + drawOrderFlow = false; + drawResistance = false; + drawIResistance = false; + + // + manageZones = true; + manageIZones = true; + manageTrends = false; + manageOrderFlow = true; + + // + structureConfig.Default(); + structureDrawConfig.Default(); + } + + // + // Deconstructor ... + ~XCXFIMAStrategy1Signaller() + { + // + Destroy(); + } + + // + // Overrides ... + + /** + * Processing Tick ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessTick(int barIndex = 0) + { + } + + /** + * Processing New Bar ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessNewBar(int barIndex = 0) + { + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + XOHCL iBar; + XBoxZone iZone; + XSignal iSignal; + bool has = false; + XTarget iTargets[]; + bool isBullish = false; + bool isBearish = false; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Initialize Bar as CBar ... + has = iBar.Init( + symbol, + period, + barIndex // + ); + if (!has) + { + // + iBar.Clean(); + return; + } + + // + // Manage ... + Manage(iBar); + + // + // Strategy X ... + has = HasSignal( + iBar, + iZone, + iTargets, + iDir // + ); + + // + // Handle Resting Signals ... + has = HasDirection(iDir) && + iZone.IsValid(); + + // + // Prepare Signal ... + if (has) + { + // + isBullish = IsXBullish(iDir); + isBearish = IsXBearish(iDir); + + // + // Provided SL ... + double points = GetPoints(symbol); + double spread = GetSpread(symbol); + double entry = GetEntry(symbol, iDir); + + // + // Calculate SL Addition ... + double slAddition = + slAdditionDistance <= 0 + ? 0 + : slAdditionDistance * points; + + // + // Calculate SL Price ... + double sl = + isBullish + ? iZone.lower - slAddition + : iZone.upper + slAddition; + + // + // Prepare Signal ... + has = PrepareSignal( + iSignal, + iDir, + iTargets, + 0, // Use Default R2R ... + sl, // Provided Price for SL ... + 0 // Specified Risk in Point .... + ); + } + + // + // Notify On Signal Event ... + if (has) + { + NotifySignalEventListeners(iSignal); + } + + // + // Cleanup ... + iBar.Clean(); + iZone.Clean(); + iSignal.Clean(); + XClean(iTargets); + } + + /** + * Check Guards Based on MarketConditions ... + * + * @param guards: XGuard, reference collection to holds result ... + * @param positions: XPosition, reference collection to provides positions ... + * @param barIndex: int + * + * @return ( int ) + */ + int virtual CheckForGuard( + XGuard &guards[], + XPosition &positions[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + XClean(guards); + return result; + + // + int positionsCount = ArraySize(positions); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + // Requirements ... + XGuard iGuard; + bool has = false; + int samePeaks = 0; + int sameVales = 0; + double iValue = 0; + double points10 = 0; + double points50 = 0; + double points100 = 0; + int samePVValidation = 5; + bool isPeakOverLast = false; + bool isValeUnderLast = false; + + // + for (int i = 0; i < positionsCount; i++) + { + // + points10 = 10 * positions[i].GetPointsValue(); + points50 = 50 * positions[i].GetPointsValue(); + points100 = 100 * positions[i].GetPointsValue(); + + // + // Near to TP Guard ... + has = positions[i].profit > 0; + if (has) + { + // + // Has Same Peaks or Vales ... + samePeaks = fimaParser.CountSamePeaks(barIndex); + sameVales = fimaParser.CountSameVales(barIndex); + isPeakOverLast = (fimaParser.IsPeakOverLast(barIndex) || + fimaParser.IsPeakOverLast(barIndex + 1)); + isValeUnderLast = (fimaParser.IsValeUnderLast(barIndex) || + fimaParser.IsValeUnderLast(barIndex + 1)); + has = (positions[i].IsBullish() + ? ( + isPeakOverLast && + sameVales >= samePVValidation && + fimaHelper.GetVale(barIndex) > positions[i].sl) + : positions[i].IsBearish() + ? ( + isValeUnderLast && + samePeaks >= samePVValidation && + fimaHelper.GetPeak(barIndex) < positions[i].sl) + : false); + if (has) + { + // + iGuard.Clean(); + iGuard.time = TimeCurrent(); + iGuard.symbol = positions[i].symbol; + iGuard.period = positions[i].period; + iGuard.ticket = positions[i].ticket; + iGuard.provider = positions[i].provider; + iGuard.sl = positions[i].IsBullish() + ? fimaHelper.GetVale(barIndex) - points10 + : fimaHelper.GetPeak(barIndex) + points10; + iGuard.action = X_GUARD_ACTION_TRAIL_STOP; + + // + has = iGuard.IsValid(); + if (has) + { + AddRef(iGuard, guards); + + // + // Remove TP if in Profit SL ... + iValue = (positions[i].IsBullish() ? positions[i].entry + points10 : positions[i].entry - points10); + has = + (positions[i].IsBullish() && HasResistance()) + ? (iGuard.sl >= iValue && + positions[i].tp < resistance.lower) + : (positions[i].IsBearish() && HasSupport()) + ? (iGuard.sl <= iValue && + positions[i].tp > support.upper) + : false; + if (has) + { + // + iGuard.Clean(); + iGuard.force = false; + iGuard.tp = positions[i].IsBullish() + ? resistance.lower + : support.upper; + iGuard.time = TimeCurrent(); + iGuard.symbol = positions[i].symbol; + iGuard.period = positions[i].period; + iGuard.ticket = positions[i].ticket; + iGuard.provider = positions[i].provider; + iGuard.action = X_GUARD_ACTION_TRAIL_TARGET; + + // + has = iGuard.IsValid(); + if (has) + { + AddRef(iGuard, guards); + } + } + } + } + } + } + + // + result = ArraySize(guards); + + // + // Cleanup ... + iGuard.Clean(); + + // + return result; + } + + // + // Protected ... + protected: + // + + // + void Manage(XOHCL &bar) + { + // + bool has = bar.IsValid(); + if (!has) + { + return; + } + + // + XOHCL pBar; + XOHCL p2Bar; + XOHCL p3Bar; + has = bar.GetPreviousBar(pBar); + has = has && + pBar.GetPreviousBar(p2Bar); + has = has && + p2Bar.GetPreviousBar(p3Bar); + if (!has) + { + // + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + } + + // + ManageTrends(bar); + ManageZones(p2Bar); + ManageIZones(p2Bar); + ManageOrderFlow(p3Bar); + + // + // Cleanup ... + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + } + + // + // Private ... + private: + // + // Props ... + + // + // Order Flow ... + + // + bool drawOrderFlow; + XBoxZone orderFlow[]; + bool manageOrderFlow; + ENUM_X_DIRECTION orderFlowDir; + + // + bool HasOrderFlow() + { + // + return HasChild(orderFlow) && + HasDirection(orderFlowDir); + } + + // + bool HasBullishOrderFlow() + { + return HasOrderFlow() && + IsXBullish(orderFlowDir); + } + + // + bool HasBearishOrderFlow() + { + return HasOrderFlow() && + IsXBearish(orderFlowDir); + } + + // + bool GetOrderFlowBoundary( + double &upper, + double &lower // + ) + { + // + bool result = false; + + // + // Prepare ... + upper = EMPTY_VALUE; + lower = EMPTY_VALUE; + + // + // Validate ... + result = HasOrderFlow(); + if (!result) + { + return result; + } + + // + int idx = -1; + + // + // Upper ... + idx = GetHighest(orderFlow); + if (IsValidIndex(idx)) + { + upper = orderFlow[idx].upper; + } + + // + // Lower ... + idx = GetLowest(orderFlow); + if (IsValidIndex(idx)) + { + lower = orderFlow[idx].lower; + } + + // + result = NotEmptyZero(upper) && + NotEmptyZero(lower) && + upper > lower; + + // + // Cleanup ... + if (!result) + { + // + upper = EMPTY_VALUE; + lower = EMPTY_VALUE; + } + + // + return result; + } + + // + bool ValidateOrderFlow(XOHCL &bar) + { + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + HasOrderFlow(); + if (!result) + { + return result; + } + + // + double upper = EMPTY_VALUE; + double lower = EMPTY_VALUE; + result = GetOrderFlowBoundary(upper, lower); + result = result && + HasBullishOrderFlow() + ? bar.low > lower + : bar.high < upper; + + // + return result; + } + + // + void DrawOrderFlow() + { + // + if (!drawOrderFlow || !HasOrderFlow()) + { + return; + } + + // + poiDrawer.DrawZones(orderFlow, structureDrawConfig.drawConfig); + } + + // + void ManageOrderFlow(XOHCL &bar) + { + // + // Validate Exists ... + if (HasOrderFlow()) + { + // + if (!ValidateOrderFlow(bar)) + { + // + // Invalidate OrderFlow ... + XClean(orderFlow); + orderFlowDir = X_DIRECTION_NONE; + } + } + + // + // Detect New ... + if (!HasOrderFlow()) + { + // + XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig; + // patternConfig.Default(); + // patternConfig.supportAndResistanceLoopbackLength = 21; + // patternConfig.supportAndResistanceValidationLength = 7; + + // + poiDetector.HasOrderFlow( + bar, + orderFlowDir, + orderFlow, + structureConfig.orderFlowValidation, + structureConfig.orderFlowUseOB, + structureConfig.orderFlowUseFVG, + structureConfig.orderFlowUseSupportAndResistance, + patternConfig.supportAndResistanceLoopbackLength, + patternConfig.supportAndResistanceValidationLength, + structureConfig.loopback // + ); + } + + // + // Update Exists ... + if (HasOrderFlow()) + { + // + // Update to Times ... + UpdateToTime(orderFlow, TimeCurrent()); + + // + DrawOrderFlow(); + } + } + + // + // Zone ... + + // + XBoxZone support; + XBoxZone resistance; + bool drawZones; + bool drawSupport; + bool manageZones; + bool drawResistance; + + // + bool HasZones() + { + return HasSupport() || + HasResistance(); + } + + // + bool HasSupport() + { + return support.IsValid(); + } + + // + bool HasResistance() + { + return resistance.IsValid(); + } + + // + bool ValidateZones(XOHCL &bar) + { + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + HasZones(); + if (!result) + { + return result; + } + + // + // Support ... + bool hasSupport = HasSupport(); + if (hasSupport) + { + // + result = bar.close > support.lower && + !IsBreaked(support, X_PRICE_CLOSE); + if (!result) + { + // + iResistance = support; + iResistance.breakAt = NULL; + iResistance.dir = X_DIRECTION_BEARISH; + iResistance.to = bar.time + (PeriodSeconds(bar.period)); + iResistance.from = bar.time - (PeriodSeconds(bar.period)); + + // + support.breakAt = bar.time; + support.Clean(); + } + } + + // + // Resistance ... + bool hasResistance = HasResistance(); + if (hasResistance) + { + // + result = bar.close < resistance.upper && + !IsBreaked(resistance, X_PRICE_CLOSE); + if (!result) + { + // + iSupport = resistance; + iSupport.breakAt = NULL; + iSupport.dir = X_DIRECTION_BULLISH; + iSupport.to = bar.time + (PeriodSeconds(bar.period)); + iSupport.from = bar.time - (PeriodSeconds(bar.period)); + + // + resistance.breakAt = bar.time; + resistance.Clean(); + } + } + + // + result = + (hasSupport && !HasSupport()) || + (hasResistance && !HasResistance()); + + // + return result; + } + + // + void DrawZones() + { + // + if (!drawZones || !HasZones()) + { + return; + } + + // + if (drawSupport && HasSupport()) + { + poiDrawer.DrawZone(support, structureDrawConfig.drawConfig); + } + + // + if (drawResistance && HasResistance()) + { + poiDrawer.DrawZone(resistance, structureDrawConfig.drawConfig); + } + } + + // + void ManageZones(XOHCL &bar) + { + // + // Validate Exists ... + if (HasZones()) + { + // + if (!ValidateZones(bar)) + { + // + // Invalidate Zones ... + + // + // Support ... + if (IsXValid(support.breakAt)) + { + // + iResistance = support; + iResistance.breakAt = NULL; + iResistance.dir = X_DIRECTION_BEARISH; + iResistance.to = bar.time + (PeriodSeconds(bar.period)); + iResistance.from = bar.time - (PeriodSeconds(bar.period)); + + // + support.Clean(); + } + + // + // Resistance ... + if (IsXValid(resistance.breakAt)) + { + // + iSupport = resistance; + iSupport.breakAt = NULL; + iSupport.dir = X_DIRECTION_BULLISH; + iSupport.to = bar.time + (PeriodSeconds(bar.period)); + iSupport.from = bar.time - (PeriodSeconds(bar.period)); + + // + resistance.Clean(); + } + } + } + + // + // Detect New ... + XOHCL tmpBar; + bool has = false; + + // + // Detect Support ... + if (!HasSupport()) + { + // + has = poiDetector.HasSupport( + bar, + tmpBar, + structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength, + structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength // + ); + if (has) + { + // + has = ToSupportBox(tmpBar, support, bar.time); + has = + has && + !IsBreaked(support, X_PRICE_CLOSE); + if (!has) + { + // + if (support.IsValid()) + { + // + iResistance = support; + iResistance.breakAt = NULL; + iResistance.dir = X_DIRECTION_BEARISH; + iResistance.to = bar.time + (PeriodSeconds(bar.period)); + iResistance.from = bar.time - (PeriodSeconds(bar.period)); + } + + // + support.Clean(); + } + } + } + + // + // Detect Resistance ... + if (!HasResistance()) + { + // + has = poiDetector.HasResistance( + bar, + tmpBar, + structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength, + structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength // + ); + if (has) + { + // + has = ToResistanceBox(tmpBar, resistance, bar.time); + has = + has && + !IsBreaked(resistance, X_PRICE_CLOSE); + if (!has) + { + // + if (resistance.IsValid()) + { + // + iSupport = resistance; + iSupport.breakAt = NULL; + iSupport.dir = X_DIRECTION_BULLISH; + iSupport.to = bar.time + (PeriodSeconds(bar.period)); + iSupport.from = bar.time - (PeriodSeconds(bar.period)); + } + + // + resistance.Clean(); + } + } + } + + // + // Update Exists ... + if (HasZones()) + { + // + if (HasSupport()) + { + // + support.to = bar.time; + support.type = "XFIMASup"; + } + + // + if (HasResistance()) + { + // + resistance.to = bar.time; + resistance.type = "XFIMARes"; + } + + // + DrawZones(); + } + + // + // Cleanup ... + tmpBar.Clean(); + } + + // + XBoxZone iSupport; + XBoxZone iResistance; + bool drawIZones; + bool drawISupport; + bool manageIZones; + bool drawIResistance; + + // + bool HasIZones() + { + // + return HasISupport() || + HasIResistance(); + } + + // + bool HasISupport() + { + return iSupport.IsValid(); + } + + // + bool HasIResistance() + { + return iResistance.IsValid(); + } + + // + void DrawIZones() + { + // + if (!drawIZones || !HasIZones()) + { + return; + } + + // + if (drawISupport && HasISupport()) + { + poiDrawer.DrawZone(iSupport, structureDrawConfig.drawConfig); + } + + // + if (drawIResistance && HasIResistance()) + { + poiDrawer.DrawZone(iResistance, structureDrawConfig.drawConfig); + } + } + + // + bool ValidateIZones(XOHCL &bar) + { + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + HasIZones(); + if (!result) + { + return result; + } + + // + + // + // Support ... + bool hasSupport = HasISupport(); + if (hasSupport) + { + // + result = bar.close > iSupport.lower && + !IsBreaked(iSupport, X_PRICE_CLOSE); + if (!result) + { + // + iSupport.breakAt = bar.time; + iSupport.Clean(); + } + } + + // + // Resistance ... + bool hasResistance = HasIResistance(); + if (hasResistance) + { + // + result = bar.close < iResistance.upper && + !IsBreaked(iResistance, X_PRICE_CLOSE); + if (!result) + { + // + iResistance.breakAt = bar.time; + iResistance.Clean(); + } + } + + // + result = + (hasSupport && !HasISupport()) || + (hasResistance && !HasIResistance()); + + // + return result; + } + + // + void ManageIZones(XOHCL &bar) + { + // + // Validate Exists ... + if (HasIZones()) + { + // + if (!ValidateIZones(bar)) + { + // + // Invalidate Zones ... + + // + // Support ... + if (IsXValid(iSupport.breakAt)) + { + iSupport.Clean(); + } + + // + // Resistance ... + if (IsXValid(iResistance.breakAt)) + { + iResistance.Clean(); + } + } + } + + // + // Update Exists ... + if (HasIZones()) + { + // + if (HasISupport()) + { + // + iSupport.to = bar.time; + iSupport.type = "XFIMAISup"; + } + + // + if (HasIResistance()) + { + // + iResistance.to = bar.time; + iResistance.type = "XFIMAIRes"; + } + + // + DrawIZones(); + } + } + + // + // Trends ... + + // + XTrend scTrend; + XTrend mcTrend; + XTrend lcTrend; + XTrend hcTrend; + + // + bool drawTrends; + bool drawSCTrend; + bool drawMCTrend; + bool drawLCTrend; + bool drawHCTrend; + bool manageTrends; + + // + bool HasTrend() + { + // + bool result = + HasSCTrend() || + HasMCTrend() || + HasLCTrend() || + HasHCTrend(); + + // + return result; + } + + // + bool HasSCTrend() + { + return scTrend.IsValid() && + scTrend.HasTrend(); + } + + // + bool HasMCTrend() + { + return mcTrend.IsValid() && + mcTrend.HasTrend(); + } + + // + bool HasLCTrend() + { + return lcTrend.IsValid() && + lcTrend.HasTrend(); + } + + // + bool HasHCTrend() + { + return hcTrend.IsValid() && + hcTrend.HasTrend(); + } + + // + void DrawTrends() + { + // + if (!drawTrends || !HasTrend()) + { + return; + } + + // + // SC ... + if (drawSCTrend && HasSCTrend()) + { + poiDrawer.DrawTrendLine(scTrend, structureDrawConfig.drawConfig); + } + + // + // MC ... + if (drawMCTrend && HasMCTrend()) + { + poiDrawer.DrawTrendLine(mcTrend, structureDrawConfig.drawConfig); + } + + // + // LC ... + if (drawLCTrend && HasLCTrend()) + { + poiDrawer.DrawTrendLine(lcTrend, structureDrawConfig.drawConfig); + } + + // + // HC ... + if (drawHCTrend && HasHCTrend()) + { + poiDrawer.DrawTrendLine(hcTrend, structureDrawConfig.drawConfig); + } + } + + // + void ManageTrends(XOHCL &bar) + { + // + // Validate ... + bool has = bar.IsValid(); + if (!has) + { + return; + } + + // + XTrend tmpTrend; + + // + // SC ... + tmpTrend.Clean(); + has = fimaParser.HasSCTrend(tmpTrend, bar.Index()); + if (has) + { + scTrend = tmpTrend; + } + + // + // MC ... + tmpTrend.Clean(); + has = fimaParser.HasMCTrend(tmpTrend, bar.Index()); + if (has) + { + mcTrend = tmpTrend; + } + + // + // LC ... + tmpTrend.Clean(); + has = fimaParser.HasLCTrend(tmpTrend, bar.Index()); + if (has) + { + lcTrend = tmpTrend; + } + + // + // HC ... + tmpTrend.Clean(); + has = fimaParser.HasHCTrend(tmpTrend, bar.Index()); + if (has) + { + hcTrend = tmpTrend; + } + + // + DrawTrends(); + + // + // Cleanup ... + tmpTrend.Clean(); + } + + // + // Implementing Strategies ... + + /** + * Check Bar Has Signal Based on Strategy X ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * + * @return ( bool ) + */ + bool HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + // Configuration Flags ... + + // + // Signaller Flags ... + bool useSignaller1 = true; + bool useSignaller2 = false; + bool useSignaller3 = false; + bool useSignaller4 = false; + + // + XBoxZone tmpZone; + string provider = NULL; + ENUM_X_DIRECTION tmpDir; + + // + bool signaller1HasSignal = false; + bool signaller2HasSignal = false; + bool signaller3HasSignal = false; + bool signaller4HasSignal = false; + + // + // Validator Flags ... + bool validateByOrderFlow = false; + + // + // Target Flags ... + bool hasPartialCloseOnTp1 = false; + + // + bool doRFOnEntryOnTP1 = false; + + // + // Draw Flags ... + bool draw = true; + bool drawZone = true; + bool drawMarketStructurePivots = false; + bool drawMarketStructureAnalysis = false; + bool drawMarketStructureOrderFlow = false; + XPOIDrawConfig iDrawConfig; + + // + drawZones = false; + drawIZones = false; + drawTrends = false; + drawSCTrend = false; + drawMCTrend = false; + drawLCTrend = false; + drawHCTrend = false; + drawSupport = false; + drawISupport = false; + drawOrderFlow = false; + drawResistance = false; + drawIResistance = false; + + // + // Signal Checking ... + + // + // Analyse Market Strucutre ... + XFIMAMarketStructure marketStructure; + + // + // Signal Detection Flags ... + + // + // Signaller 1 ... + if (useSignaller1) + { + // + signaller1HasSignal = Strategy1HasSignal( + bar, + tmpZone, + targets, + tmpDir // + ); + + // + if (signaller1HasSignal) + { + // + provider += "1"; + + // + if (!zone.IsValid()) + { + // + dir = tmpDir; + zone = tmpZone; + } + } + + // + tmpZone.Clean(); + tmpDir = X_DIRECTION_NONE; + } + + // + // Signaller 2 ... + if (useSignaller2) + { + // + signaller2HasSignal = Strategy2HasSignal( + bar, + tmpZone, + targets, + tmpDir // + ); + + // + if (signaller2HasSignal) + { + // + provider += "2"; + + // + if (!zone.IsValid()) + { + // + dir = tmpDir; + zone = tmpZone; + } + } + + // + tmpZone.Clean(); + tmpDir = X_DIRECTION_NONE; + } + + // + // Signaller 3 ... + if (useSignaller3) + { + // + signaller3HasSignal = Strategy3HasSignal( + bar, + tmpZone, + targets, + tmpDir // + ); + + // + if (signaller3HasSignal) + { + // + provider += "3"; + + // + if (!zone.IsValid()) + { + // + dir = tmpDir; + zone = tmpZone; + } + } + + // + tmpZone.Clean(); + tmpDir = X_DIRECTION_NONE; + } + + // + // Signaller 4 ... + if (useSignaller4) + { + // + signaller4HasSignal = Strategy4HasSignal( + bar, + tmpZone, + targets, + tmpDir // + ); + + // + if (signaller4HasSignal) + { + // + provider += "4"; + + // + if (!zone.IsValid()) + { + // + dir = tmpDir; + zone = tmpZone; + } + } + + // + tmpZone.Clean(); + tmpDir = X_DIRECTION_NONE; + } + + // + // Summarize Signallers Result ... + result = signaller1HasSignal || + signaller2HasSignal || + signaller3HasSignal || + signaller4HasSignal; + + // + // Signal Validating ... + + // + // Validate Signals by Order Flow ... + if (result && validateByOrderFlow) + { + // + // Analyse Market Structure if Required ... + if (!marketStructure.IsValid()) + { + // + poiDetector.AnalyseMarket( + marketStructure, + structureConfig, + bar.Index() // + ); + } + + // + bool isBullish = IsXBullish(dir) && + marketStructure.HasBullishOrderFlow(); + + // + bool isBearish = IsXBearish(dir) && + marketStructure.HasBearishOrderFlow(); + + // + // Summarizing result ... + result = isBullish || + isBearish; + } + + // + // Targets, Restrictions and Risk Management ... + if (result) + { + // + // Requirements ... + XTarget iTarget; + + // + // Checking Direction of Signal ... + bool isBullish = IsXBullish(dir); + bool isBearish = IsXBearish(dir); + + // + // Provided SL ... + double points = GetPoints(symbol); + double spread = GetSpread(symbol); + double entry = GetEntry(symbol, dir); + + // + // Calculate SL Addition ... + double slAddition = + slAdditionDistance <= 0 + ? 0 + : slAdditionDistance * points; + + // + // Calculate SL Price ... + double sl = + isBullish + ? zone.lower - slAddition + : zone.upper + slAddition; + + // + // Calculate Risk ... + double risk = MathAbs(entry - sl); + + // + // Calculate Reward ... + double reward = defaultSignalR2R * risk; + + // + // Calculate TP1 ... + double tp1 = isBullish + ? entry + risk + : entry - risk; + double tp2 = isBullish + ? entry + (2 * risk) + : entry - (2 * risk); + + // + // Calculate TP ... + double tp = isBullish + ? entry + reward + : entry - reward; + + // + // Check Max Allowed Risk ... + bool hasTooMuchRisk = maxAllowedRiskDistance <= 0 + ? false + : risk >= (maxAllowedRiskDistance * points); + if (hasTooMuchRisk) + { + // + // Clean Signal if Too much Risk ... + zone.Clean(); + dir = X_DIRECTION_NONE; + } + + // + // Common Targets ... + + // + // Partial Close on TP 1 ... + if (hasPartialCloseOnTp1) + { + // + iTarget.Clean(); + iTarget.target = tp1; + iTarget.actingDistance = 5; + iTarget.volumeMultiplier = 0.8; + iTarget.doRFOnEntry = doRFOnEntryOnTP1; + + // + AddRef(iTarget, targets); + } + + // + // Custom Signaller Targets ... + + // + // Restrictions Handling ... + if (risk > 0 && HasRestrictions()) + { + // + // Reset Restricitons if necessary ... + ResetRestrictions(); + + // + // Handle Custom Restrictions Senario ... + } + + // + // Ignore Targets ... + if (ignoreTargets) + { + XClean(targets); + } + + // + // Summarize Result ... + result = zone.IsValid() && + HasDirection(dir); + + // + // Cleanup ... + iTarget.Clean(); + } + + // + // Draws ... + if (result && draw) + { + // + // Prepare Draw Config ... + iDrawConfig = structureDrawConfig.drawConfig; + iDrawConfig.zonesWidth = 3; + iDrawConfig.zonesStyle = STYLE_DASH; + iDrawConfig.bullishColor = clrYellow; + iDrawConfig.bearishColor = clrDarkOrange; + + // + // Draw Zone ... + if (drawZone) + { + poiDrawer.DrawZone(zone, iDrawConfig); + } + + // + // Draw Market Structure ... + + // + // Analyse Market Structure if Required ... + if (!marketStructure.IsValid()) + { + // + poiDetector.AnalyseMarket( + marketStructure, + structureConfig, + bar.Index() // + ); + } + if (marketStructure.IsValid()) + { + // + // Order Flow ... + if (drawMarketStructureOrderFlow && marketStructure.HasOrderFlow()) + { + poiDrawer.DrawZones(marketStructure.orderFlow, iDrawConfig); + } + + // + // Pivots ... + if (drawMarketStructurePivots) + { + // + XPivot pivots[]; + int pivotsCount = marketStructure.CollectPivots( + pivots, + true // Contains Patterns ... + ); + if (IsValidSize(pivotsCount)) + { + poiDrawer.DrawPivots(pivots, iDrawConfig); + } + + // + XClean(pivots); + } + + // + // Analysis ... + if (drawMarketStructureAnalysis) + { + // + } + } + + // + // Other Drawing Materials ... + Print("Signaller Providers: ", provider); + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + + // + // Cleanup ... + tmpZone.Clean(); + iDrawConfig.Clean(); + marketStructure.Clean(); + + // + return result; + } + + // + // Custom Signal Strategies ... + + /** + * Check Bar Has Signal Based on Strategy 3 ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * + * @return ( bool ) + */ + bool Strategy1HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Define Requirements ... + + // + XOHCL pBar; + XOHCL p2Bar; + XOHCL p3Bar; + XOHCL tmpBar; + XPivot tmpPivot; + XBoxZone atrBox; + XBoxZone zones[]; + XBoxZone tmpZone; + XBoxZone scPVZone; + XBoxZone mcPVZone; + XBoxZone lcPVZone; + XBoxZone hcPVZone; + XBoxZone tmpZones[]; + XBoxZone pinBarZone; + XBoxZone supports[]; + XBoxZone resistances[]; + XBoxZone affectedZone; + XTrend pinBarZoneTrend; + bool isBullish = false; + bool isBearish = false; + ENUM_X_DIRECTION tmpDir; + XPatternAnalysis pBarPatterns; + XPatternAnalysis p2BarPatterns; + XPatternAnalysis p3BarPatterns; + XPatternAnalysisConfig iPatternsConfig; + + // + // Reading Bars ... + result = bar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + result = result && + p2Bar.GetPreviousBar(p3Bar); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + + // + return result; + } + + // + // Reading Bar Patterns ... + iPatternsConfig.Default(); + iPatternsConfig.FullPattern(); + result = + result && + poiDetector.AnalyseBarPatterns( + pBar, + pBarPatterns, + iPatternsConfig // + ); + result = + result && + poiDetector.AnalyseBarPatterns( + p2Bar, + p2BarPatterns, + iPatternsConfig // + ); + result = + result && + poiDetector.AnalyseBarPatterns( + p3Bar, + p3BarPatterns, + iPatternsConfig // + ); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + pBarPatterns.Clean(); + p2BarPatterns.Clean(); + p3BarPatterns.Clean(); + iPatternsConfig.Clean(); + + // + return result; + } + + // + // Detect Directional Candlestic Patterns ... + + // + // Bullish ... + bool isPBarHasBullishPatterns = + (bar.close > pBar.low || + bar.open > pBar.low) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BULLISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isP2BarHasBullishPatterns = + (bar.close > p2Bar.low || + bar.open > p2Bar.low) && + ( + // + p2BarPatterns.IsPinned(X_DIRECTION_BULLISH) || + p2BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + p2BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + p2BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + p2BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isP3BarHasBullishPatterns = + (bar.close > p3Bar.low || + bar.open > p3Bar.low) && + ( + // + p3BarPatterns.IsPinned(X_DIRECTION_BULLISH) || + p3BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + p3BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + p3BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + p3BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + + // + // Bearish ... + bool isPBarHasBearishPatterns = + (bar.close < pBar.high || + bar.open < pBar.high) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BEARISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + bool isP2BarHasBearishPatterns = + (bar.close < p2Bar.high || + bar.open < p2Bar.high) && + ( + // + p2BarPatterns.IsPinned(X_DIRECTION_BEARISH) || + p2BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + p2BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + p2BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + p2BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + bool isP3BarHasBearishPatterns = + (bar.close < p3Bar.high || + bar.open < p3Bar.high) && + ( + // + p3BarPatterns.IsPinned(X_DIRECTION_BEARISH) || + p3BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + p3BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + p3BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + p3BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + // Checking Support and Resistances ... + + // + // Support ... + bool hasSupport = pBarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = pBarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p2BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p3BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p3BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + + // + // Resistance ... + bool hasResistance = pBarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = pBarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p2BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p3BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p3BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + + // + // Collecting Zones ... + + // + int collectedZonesCount = poiDetector.DetectZones( + bar, + zones, + true, // Validated Zones ... + false, // Remove Used Zones ... + false, // Contains Order Blocks ... + true, // Contains Fair Value Gaps ... + true, // Contains Supports ... + true, // Contains Resistances ... + X_DIRECTION_NONE, // For Dir (Contains All Direction Zones) ... + X_SORT_BY_DATE, // Sort By ... + X_DIRECTION_BEARISH, // Sort Dir ... + 3, // Zones Loopback ... + 3, // Zones Validation Length ... + 0, // Count (All Zones) ... + 100 // Loop back for Detection ... + ); + bool hasCollectedZones = IsValidSize(collectedZonesCount) && + collectedZonesCount > 1; + int affectedZonesCount = 0; + bool hasAffectedZone = false; + int collectedZonesBullishCount = 0; + int collectedZonesBearishCount = 0; + bool hasBullishAffectedZone = false; + bool hasBearishAffectedZone = false; + bool hasBullishCollectedZones = false; + bool hasBearishCollectedZones = false; + if (hasCollectedZones) + { + // + // Bullish ... + XClean(tmpZones); + collectedZonesBullishCount = ExtractByDirection(tmpZones, zones, X_DIRECTION_BULLISH); + hasBullishCollectedZones = IsValidSize(collectedZonesBullishCount); + + // + // Bearish ... + XClean(tmpZones); + collectedZonesBearishCount = ExtractByDirection(tmpZones, zones, X_DIRECTION_BEARISH); + hasBearishCollectedZones = IsValidSize(collectedZonesBearishCount); + + // + // Extract Affected Zones ... + XClean(tmpZones); + int affectedZonesCount = ExtractAffectedZones(p2Bar, zones, tmpZones); + int idx = GetYoungest(tmpZones); + if (IsValidIndex(idx)) + { + affectedZone = tmpZones[idx]; + } + hasAffectedZone = affectedZone.IsValid(); + hasBullishAffectedZone = hasAffectedZone && affectedZone.IsBullish(); + hasBearishAffectedZone = hasAffectedZone && affectedZone.IsBearish(); + } + + // + // Reading Cycle PVS ... + bool hasSCPV = poiDetector.GetSCZone(pBar, scPVZone); + bool hasMCPV = poiDetector.GetMCZone(pBar, mcPVZone); + bool hasLCPV = poiDetector.GetLCZone(pBar, lcPVZone); + bool hasHCPV = poiDetector.GetHCZone(pBar, hcPVZone); + bool isCyclePVBullish = + hasMCPV && mcPVZone.IsBullish() && + hasLCPV && lcPVZone.IsBullish() && + hasHCPV && hcPVZone.IsBullish(); + bool isCyclePVBearish = + hasMCPV && mcPVZone.IsBearish() && + hasLCPV && lcPVZone.IsBearish() && + hasHCPV && hcPVZone.IsBearish(); + + // + // Validating Market Direction ... + // by Checking HC and LC States ... + + // + bool isLCBullish = fimaParser.IsLCMABullish(pBar.Index()); + bool isHCBullish = fimaParser.IsHCMABullish(pBar.Index()); + bool isLCHigherLow = + (fimaParser.IsLCHigherLow(pBar.Index()) || + fimaParser.IsLCHigherLow(p2Bar.Index()) || + fimaParser.IsLCHigherLow(p3Bar.Index())); + bool isCyclesBullish = + isLCBullish && + isHCBullish && + isLCHigherLow; + + // + bool isLCBearish = fimaParser.IsLCMABearish(pBar.Index()); + bool isHCBearish = fimaParser.IsHCMABearish(pBar.Index()); + bool isLCLowerHigh = + (fimaParser.IsLCLowerHigh(pBar.Index()) || + fimaParser.IsLCLowerHigh(p2Bar.Index()) || + fimaParser.IsLCLowerHigh(p3Bar.Index())); + bool isCyclesBearish = + isLCBearish && + isHCBearish && + isLCLowerHigh; + + // + // Looking For a Pin Bar in P2Bar ... + bool isP2BarIsPinBar = poiDetector.IsPinnedBar( + p2Bar, + tmpDir, + 4, // Shadow Multiplier ... + 4, // Minimum Range Multiplier ... + true // Force Pin Bar Direction ... + ); + if (isP2BarIsPinBar) + { + // + isP2BarIsPinBar = ToBox( + p2Bar, + pinBarZone, + tmpDir, + X_BAR_PATTERN_PINNED // + ); + if (isP2BarIsPinBar) + { + // + pinBarZone.to = bar.time; + isP2BarIsPinBar = poiDetector.HasBoundaryTrend( + pinBarZone, + pinBarZoneTrend, + false // + ); + isP2BarIsPinBar = + isP2BarIsPinBar && + tmpDir == pinBarZoneTrend.dir; + } + } + bool isP2BarPinnedBullish = isP2BarIsPinBar && IsXBullish(tmpDir); + bool isP2BarPinnedBearish = isP2BarIsPinBar && IsXBearish(tmpDir); + + // + // Checking ATR Box ... + bool hasATRBox = fimaParser.GetATRBox( + atrBox, + bar.Index() // + ); + bool hasATRBoxBullish = hasATRBox && atrBox.IsBullish(); + bool hasATRBoxBearish = hasATRBox && atrBox.IsBearish(); + + // + // Checking Double Patterns ... + ENUM_X_DIRECTION iDBDir; + XPatternAnalysis iPatterns; + XPatternAnalysis iPPatterns; + ENUM_X_BAR_PATTERN doublePatterns[]; + GetCandlestickPatterns(doublePatterns); + bool hasDoublePatterns = poiDetector.HasDoublePatterns( + pBar, + iDBDir, + iPatterns, + iPPatterns, + doublePatterns, + iPatternsConfig, + 5 // + ); + bool hasBullishDoublePatterns = hasDoublePatterns && IsXBullish(iDBDir); + bool hasBearishDoublePatterns = hasDoublePatterns && IsXBearish(iDBDir); + + // + isBullish = + // + hasSupport && + hasResistance && + isCyclesBullish && + hasATRBoxBullish && + isCyclePVBullish && + isP2BarPinnedBullish && + hasBullishAffectedZone && + isPBarHasBullishPatterns && + hasBullishCollectedZones && + isP2BarHasBullishPatterns && + collectedZonesBullishCount > collectedZonesBearishCount && + true + // + ; + + // + isBearish = + // + hasSupport && + hasResistance && + isCyclesBearish && + hasATRBoxBearish && + isCyclePVBearish && + isP2BarPinnedBearish && + hasBearishAffectedZone && + isPBarHasBearishPatterns && + hasBearishCollectedZones && + isP2BarHasBearishPatterns && + collectedZonesBearishCount > collectedZonesBullishCount && + true + // + ; + + // + // Validate ... + result = isBullish || + isBearish; + if (result) + { + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = HasDirection(dir); + } + + // + // Prepare Zone ... + if (result) + { + // + zone.Clean(); + zone = pinBarZone; + + // + result = zone.IsValid(); + } + + // + // Draws ... + if (result) + { + // + XPOIDrawConfig iConfig = structureDrawConfig.drawConfig; + XPatternAnalysisDrawConfig iPatternsConfig = structureDrawConfig.barAnalysisDrawConfig; + iConfig.trendRayLeft = false; + iConfig.trendRayRight = false; + + // + // poiDrawer.DrawZone(scPVZone, iConfig); + // poiDrawer.DrawZone(mcPVZone, iConfig); + // poiDrawer.DrawZone(lcPVZone, iConfig); + // poiDrawer.DrawZone(hcPVZone, iConfig); + + // + poiDrawer.DrawPatternAnalysis(pBarPatterns, iPatternsConfig); + poiDrawer.DrawPatternAnalysis(p2BarPatterns, iPatternsConfig); + poiDrawer.DrawPatternAnalysis(p3BarPatterns, iPatternsConfig); + + // + poiDrawer.DrawZone(pinBarZone, iConfig); + poiDrawer.DrawZone(affectedZone, iConfig); + poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig); + + // + // poiDrawer.DrawZones(zones, iConfig); + poiDrawer.DrawZones(supports, iConfig); + poiDrawer.DrawZones(resistances, iConfig); + + // + if (hasATRBox) + { + poiDrawer.DrawZone(atrBox, iConfig); + } + + // + if (hasDoublePatterns) + { + // + poiDrawer.DrawPatternAnalysis(iPatterns, iPatternsConfig); + poiDrawer.DrawPatternAnalysis(iPPatterns, iPatternsConfig); + } + + // + iConfig.Clean(); + iPatternsConfig.Clean(); + + // + DebugBreak(); + + // // + // result = false; + // isBullish = false; + // isBearish = false; + // zone.Clean(); + } + + // + // Prepare Targets ... + if (result) + { + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + XClean(zones); + tmpBar.Clean(); + tmpZone.Clean(); + XClean(supports); + XClean(tmpZones); + scPVZone.Clean(); + mcPVZone.Clean(); + lcPVZone.Clean(); + hcPVZone.Clean(); + tmpPivot.Clean(); + pinBarZone.Clean(); + XClean(resistances); + affectedZone.Clean(); + pBarPatterns.Clean(); + p2BarPatterns.Clean(); + p3BarPatterns.Clean(); + pinBarZoneTrend.Clean(); + iPatternsConfig.Clean(); + + // + return result; + } + + /** + * Check Bar Has Signal Based on Strategy 2 ... + * + * Strategy 2: + * =========== + * - Works Based On PBar Patterns Focused on PinBar ... + * - Looking for a Bar Directional Pattern Happens ... + * - Validate Fast Ma Over/Under Slow ... + * - Validate P2Peak/Vale doesnt Under or Over Last (InDirectional) ... + * - Validate P2Bar Has Directional Market Strucuture Zone (OB, FVG, Support/Resistance) ... + * + * Manipulations: + * ================ + * there are Some Flags properties to Change Validations in Strategy ... + * we can use them for Testing Purposes ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * + * @return ( bool ) + */ + bool Strategy2HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Define Requirements ... + + // + XOHCL pBar; + XOHCL p2Bar; + XOHCL p3Bar; + bool isBullish = false; + bool isBearish = false; + + // + // Read PBar ... + result = bar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + result = result && + p2Bar.GetPreviousBar(p3Bar); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + + // + return result; + } + + // + // Reading pBar Patterns ... + XPatternAnalysis pBarPatterns; + poiDetector.AnalyseBarPatterns( + pBar, + pBarPatterns, + structureConfig.barsAnalysisConfig // + ); + bool hasSupport = pBarPatterns.IsSupport(); + bool hasResistance = pBarPatterns.IsResistance(); + + // + // Check Boundary Trend ... + XTrend boundaryTrend; + bool hasBoundaryTrend = fimaParser.HasBoundaryTrend(boundaryTrend, pBar.Index()); + bool hasBoundaryBullishTrend = hasBoundaryTrend && boundaryTrend.IsBullish(); + bool hasBoundaryBearishTrend = hasBoundaryTrend && boundaryTrend.IsBearish(); + + // + // Check Bar Patterns ... + + // + // Bars Sequences ... + bool hasBullishSequence = p3Bar.IsBearish() && + pBar.IsBullish(); + bool hasBearishSequence = p3Bar.IsBullish() && + pBar.IsBearish(); + + // + // Bullish ... + bool isPBarHasBullishPatterns = + (bar.close > pBar.low || + bar.open > pBar.low) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BULLISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + + // + // Bearish ... + bool isPBarHasBearishPatterns = + (bar.close < pBar.high || + bar.open < pBar.high) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BEARISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + double peak = fimaHelper.GetPeak(bar.Index()); + double vale = fimaHelper.GetVale(bar.Index()); + double pPeak = fimaHelper.GetPeak(pBar.Index()); + double pVale = fimaHelper.GetVale(pBar.Index()); + double p2Peak = fimaHelper.GetPeak(p2Bar.Index()); + double p2Vale = fimaHelper.GetVale(p2Bar.Index()); + bool isPPeakOverLast = fimaParser.IsPeakOverLast(pBar.Index()); + bool isPValeUnderLast = fimaParser.IsValeUnderLast(pBar.Index()); + bool isP2PeakOverLast = fimaParser.IsPeakOverLast(p2Bar.Index()); + bool isP2ValeUnderLast = fimaParser.IsValeUnderLast(p2Bar.Index()); + bool isPeakOverLast = isPPeakOverLast || + isP2PeakOverLast; + bool isValeUnderLast = isPValeUnderLast || + isP2ValeUnderLast; + bool isP2ValeOverLast = pVale > p2Vale; + bool isP2PeakUnderLast = pPeak < p2Peak; + + // + // Check PBar Close Over Under Fast Ma ... + bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index()); + bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index()); + bool isFastOverLast = fimaHelper.GetMAFast(pBar.Index()) > fimaHelper.GetMAFast(p2Bar.Index()); + bool isFastUnderLast = fimaHelper.GetMAFast(pBar.Index()) < fimaHelper.GetMAFast(p2Bar.Index()); + + // + // Force P2Bar is Pin Bar ... + ENUM_X_DIRECTION p2Dir; + bool isP2BarPinned = poiDetector.IsPinnedBar( + p2Bar, + p2Dir // + ); + bool isP2BarBullishPinned = + isP2BarPinned && + IsXBullish(p2Dir); + bool isP2BarBearishPinned = + isP2BarPinned && + IsXBearish(p2Dir); + + // + // Check Based On LC and HC MA State ... + + // + bool isLCMABullish = fimaParser.IsLCMABullish(pBar.Index()); + bool isHCMABullish = fimaParser.IsHCMABullish(pBar.Index()); + bool isCycleMABullish = isLCMABullish && isHCMABullish; + + // + bool isLCMABearish = fimaParser.IsLCMABearish(pBar.Index()); + bool isHCMABearish = fimaParser.IsHCMABearish(pBar.Index()); + bool isCycleMABearish = isLCMABearish && isHCMABearish; + + // + // Do ... + + // + isBullish = + // + hasSupport && + isFastOverLast && + isValeUnderLast && + isCycleMABullish && + hasBullishSequence && + !isP2PeakUnderLast && + isPBarCloseOverFast && + isP2BarBullishPinned && + hasBoundaryBullishTrend && + isPBarHasBullishPatterns + // + ; + + // + isBearish = + // + hasResistance && + isPeakOverLast && + isFastUnderLast && + isCycleMABearish && + !isP2ValeOverLast && + hasBearishSequence && + isPBarCloseUnderFast && + isP2BarBearishPinned && + hasBoundaryBearishTrend && + isPBarHasBearishPatterns + // + ; + + // + // Validate ... + result = isBullish || + isBearish; + if (result) + { + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = HasDirection(dir); + } + + // + // Prepare Zone ... + if (result) + { + // + zone.Clean(); + result = ToBox( + p2Bar, + zone, + dir, + X_BAR_PATTERN_PINNED // + ); + + // + // Draws ... + if (result) + { + // + // XPOIDrawConfig iConfig = structureDrawConfig.drawConfig; + // iConfig.trendRayLeft = false; + // iConfig.trendRayRight = false; + // poiDrawer.DrawTrendLine(boundaryTrend, iConfig); + // poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig); + // iConfig.Clean(); + + // + // DebugBreak(); + } + + // + result = zone.IsValid(); + } + + // + // Prepare Targets ... + if (result) + { + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + pBarPatterns.Clean(); + boundaryTrend.Clean(); + + // + return result; + } + + /** + * Check Bar Has Signal Based on Strategy 3 ... + * + * Strategy 3: + * =========== + * - Works Based On Breaked Support or Resistances ... + * - Looking for a Support or Resistance to Breaked ... + * - Validate Breaker Bar to Change Peak or Vale ... + * - Validate Bar Opposit Side of Breaker Bar's Shadow ... + * - Validate by Checking Market Strucutre to Has Directional Zone + * (Support for Resistance Break / Resistance for Support Break) ... + * - Validate Breaker Bar to Has Directional FVG ... + * + * Manipulations: + * ================ + * there are Some Flags properties to Change Validations in Strategy ... + * we can use them for Testing Purposes ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * + * @return ( bool ) + */ + bool Strategy3HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Validation Flags ... + + // + bool validateByPVChanges = true; + bool validateByGapExists = true; + bool validateByBarShadows = true; + bool validateHasDirectionalZone = true; + + // + // Define Requirements ... + + // + XOHCL pBar; + XOHCL p2Bar; + XOHCL p3Bar; + bool isBullish = false; + bool isBearish = false; + + // + // Read PBar ... + result = bar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + result = result && + p2Bar.GetPreviousBar(p3Bar); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + + // + return result; + } + + // + // Do ... + + // + // Retrieve pBar Patterns ... + XBoxZone _fvg; + XBoxZone _support; + XBoxZone _resistance; + XPatternAnalysis pBarPatterns; + XPatternAnalysis p2BarPatterns; + XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig; + + // + poiDetector.AnalyseBarPatterns( + pBar, + pBarPatterns, + patternConfig // + ); + poiDetector.AnalyseBarPatterns( + p2Bar, + p2BarPatterns, + patternConfig // + ); + + // + // Price Must Break Support or Resistance ... + + // + // Extract Support and Resistance ... + bool hasSupport = p2BarPatterns.IsSupport(); + bool hasResistance = p2BarPatterns.IsResistance(); + if (hasSupport) + { + // + XOHCL tmpBar; + XPivot tmpPivot; + hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, _support); + tmpBar.Clean(); + tmpPivot.Clean(); + } + if (hasResistance) + { + // + XOHCL tmpBar; + XPivot tmpPivot; + hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, _resistance); + tmpBar.Clean(); + tmpPivot.Clean(); + } + + // + bool hasBreakedSupport = hasSupport && + pBar.close < _support.lower && + p2Bar.close > _support.lower; + bool hasBreakedResistance = hasResistance && + pBar.close > _resistance.upper && + p2Bar.close < _resistance.upper; + + // + isBullish = hasBreakedResistance; + isBearish = hasBreakedSupport; + + // + result = isBullish || isBearish; + + // + // Validate By PV Changed ... + // Breaker Bar must Change Peak or Value ... + if (result && validateByPVChanges) + { + // + bool isPeakOverLast = fimaParser.IsPeakOverLast(pBar.Index()); + bool isValeUnderLast = fimaParser.IsValeUnderLast(pBar.Index()); + + // + isBullish = + isBullish && + isPeakOverLast; + + // + isBearish = + isBearish && + isValeUnderLast; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate by Bar Shadows ... + // Breakre Bar Side Shadow must not Reached ... + if (result && validateByBarShadows) + { + // + isBullish = + isBullish && + pBar.low > p2Bar.low; + + // + isBearish = + isBearish && + pBar.high < p2Bar.high; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate Has Directional Zone ... + if (result && validateHasDirectionalZone) + { + // + isBullish = + isBullish && + hasSupport; + + // + isBearish = + isBearish && + hasResistance; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate By Gap Exists ... + if (result && validateByGapExists) + { + // + ENUM_X_DIRECTION tmpDir; + bool hasFVG = poiDetector.HasFVG( + pBar, + tmpDir, + _fvg // + ); + + // + isBullish = + isBullish && + hasFVG && + IsXBullish(tmpDir); + + // + isBearish = + isBearish && + hasFVG && + IsXBearish(tmpDir); + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Prepare Direction and Zone ... + if (result) + { + // + if (isBullish) + { + // + zone = _resistance; + zone.dir = Opposit(_resistance.dir); + dir = zone.dir; + zone.upper = MathMax(zone.upper, _fvg.upper); + zone.lower = MathMin(zone.lower, _fvg.lower); + } + + // + if (isBearish) + { + // + zone = _support; + zone.dir = Opposit(_support.dir); + dir = zone.dir; + zone.upper = MathMax(zone.upper, _fvg.upper); + zone.lower = MathMin(zone.lower, _fvg.lower); + } + + // + // Zone Validation Base ... + result = zone.IsValid(); + if (result) + { + // + // Validate By Trend of Zone ... + XTrend zoneTrend; + XTrend zoneToTrend; + + // + // Detecting Trends ... + result = poiDetector.HasBoundaryTrend(zone, zoneTrend, false); + result = result && + poiDetector.HasBoundaryTrend(zone, zoneToTrend, true); + + // + // Validate Trend ... + result = + result && + zone.dir == zoneTrend.dir && + zone.dir == zoneToTrend.dir; + + // + // Draw ... + if (result) + { + // // + // XPOIDrawConfig iConfig = structureDrawConfig.drawConfig; + // iConfig.trendRayLeft = false; + // iConfig.trendRayRight = false; + + // // + // poiDrawer.DrawTrendLine(zoneTrend, iConfig); + // poiDrawer.DrawTrendLine(zoneToTrend, iConfig); + + // // + // iConfig.Clean(); + } + + // + // Cleanup ... + zoneTrend.Clean(); + zoneToTrend.Clean(); + + // + // Reset Flags ... + if (!result) + { + // + zone.Clean(); + isBullish = false; + isBearish = false; + } + } + + // + result = zone.IsValid(); + } + + // + if (result) + { + // + if (_support.IsValid()) + { + poiDrawer.DrawZone(_support, structureDrawConfig.drawConfig); + } + + // + if (_resistance.IsValid()) + { + poiDrawer.DrawZone(_resistance, structureDrawConfig.drawConfig); + } + + // + if (pBarPatterns.IsValid()) + { + poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig); + } + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + pBarPatterns.Clean(); + p2BarPatterns.Clean(); + patternConfig.Clean(); + + // + return result; + } + + /** + * Check Bar Has Signal Based on Strategy 4 ... + * + * Strategy 4: + * =========== + * - Works Based on Order Flow ... + * - Looking for new and Fresh Order Flow ... + * - Validate Bar is Inside Order Flow ... + * - Validate Bar has Proper Pattern ... + * - Validate Bar Based on ATR Band in two Step: + * - Step 1: Bars is Inside ATR Band (Middle) ... + * - Step 2: Trigger Bars Close Price based on ATR Band ... + * - Validate Order Flow based on Market Structure Zone ... + * - Validate Trigger Bar based on InDirectional Market Structure Zones ... + * + * Manipulations: + * ================ + * there are Some Flags properties to Change Validations in Strategy ... + * we can use them for Testing Purposes ... + * + * @param bar: XOHCL, reference to Bar ... + * @param zone: XBoxZone, reference to holds affected zone ... + * @param targets: XTarget, reference to detected Signal's Targets collections ... + * @param dir: ENUM_X_DIRECTION, detected Signal's direction ... + * + * @return ( bool ) + */ + bool Strategy4HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Validation Flags ... + bool validateBarInsideZone = true; + bool validateByBarPatterns = true; + bool validateByXFIMABoundary = true; + bool validateByBarInsideATRBand = true; + bool validateByBarBasedOnATRBand = true; + bool validateByXFIMABoundaryTrend = true; + bool validateMarketStructureHasDirectionalZone = true; + bool validateMarketStructureDirectionalZoneInsideOrderFlow = true; + bool validateMarketStructureHasNotInDirectionalZoneOrUnReachedTP = true; + + // + // Define Requirements ... + + // + XOHCL pBar; + XOHCL p2Bar; + XOHCL p3Bar; + bool isBullish = false; + bool isBearish = false; + + // + // Read PBar ... + result = bar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + result = result && + p2Bar.GetPreviousBar(p3Bar); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + + // + return result; + } + + // + // Do ... + + // + // Retrieve pBar Patterns ... + XPatternAnalysis pBarPatterns; + XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig; + + // + poiDetector.AnalyseBarPatterns( + pBar, + pBarPatterns, + patternConfig // + ); + + // + // Detecting OrderFlow ... + XBoxZone oFlow[]; + bool hasOrderFlow = poiDetector.HasOrderFlow( + p3Bar, + dir, + oFlow, + structureConfig.orderFlowValidation, + structureConfig.orderFlowUseOB, + structureConfig.orderFlowUseFVG, + structureConfig.orderFlowUseSupportAndResistance, + patternConfig.supportAndResistanceLoopbackLength, + patternConfig.supportAndResistanceValidationLength, + structureConfig.loopback // + ); + + // + XTrend boundaryTrend; + XTrend boundaryZoneTrend; + + // + double atrBandUpper = EMPTY_VALUE; + double atrBandLower = EMPTY_VALUE; + double atrBandMiddle = EMPTY_VALUE; + + // + isBullish = hasOrderFlow && + IsXBullish(dir); + + // + isBearish = hasOrderFlow && + IsXBearish(dir); + + // + // Summarize Result ... + result = isBullish || isBearish; + + // + // Force Price of p2Bar is Inside Order Flow ... + if (result && validateBarInsideZone) + { + // + double orderFlowUpper = 0; + double orderFlowLower = 0; + + // + int idx = -1; + idx = GetHighest(oFlow); + if (IsValidIndex(idx)) + { + orderFlowUpper = oFlow[idx].upper; + } + idx = GetLowest(oFlow); + if (IsValidIndex(idx)) + { + orderFlowLower = oFlow[idx].lower; + } + + // + result = NotEmptyZero(orderFlowUpper) && + NotEmptyZero(orderFlowLower) && + orderFlowUpper > orderFlowLower && + (isBullish + ? p2Bar.low < orderFlowUpper + : p2Bar.high > orderFlowLower); + + // + // Reset Flags ... + if (!result) + { + // + isBullish = false; + isBearish = false; + } + } + + // + // Force PBar Has Pattern ... + if (result && validateByBarPatterns) + { + // + // Analyse Bar Patterns ... + result = pBarPatterns.IsValid(); + + // + // Bullish ... + bool isPBarHasBullishPatterns = + result && + // (bar.close > pBar.low || + // bar.open > pBar.low) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BULLISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + + // + // Bearish ... + bool isPBarHasBearishPatterns = + result && + // (bar.close < pBar.high || + // bar.open < pBar.high) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BEARISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + isBullish = + isBullish && + isPBarHasBullishPatterns && + !isPBarHasBearishPatterns; + + // + isBearish = + isBearish && + isPBarHasBearishPatterns && + !isPBarHasBullishPatterns; + + // + // Summarize Result ... + result = isBullish || isBearish; + + // + // Reset Flags ... + if (!result) + { + // + isBullish = false; + isBearish = false; + } + } + + // + // Force P2Bar Place Checking based on ATR Band ... + if (result && validateByBarInsideATRBand) + { + // + atrBandUpper = fimaHelper.GetATRBandUpper(p2Bar.Index()); + atrBandLower = fimaHelper.GetATRBandLower(p2Bar.Index()); + + // + atrBandMiddle = atrBandLower + ((atrBandUpper - atrBandLower) / 2); + + // + isBullish = + isBullish && + NotEmptyZero(atrBandMiddle) && + p2Bar.low < atrBandMiddle; + + // + isBearish = + isBearish && + NotEmptyZero(atrBandMiddle) && + p2Bar.high > atrBandMiddle; + + // + // Summarize Result ... + result = isBullish || isBearish; + + // + // Reset Flags ... + if (!result) + { + // + isBullish = false; + isBearish = false; + } + } + + // + // Force PBar Place Checking based on ATR Band ... + if (result && validateByBarBasedOnATRBand) + { + // + atrBandUpper = fimaHelper.GetATRBandUpper(pBar.Index()); + atrBandLower = fimaHelper.GetATRBandLower(pBar.Index()); + + // + result = + NotEmptyZero(atrBandUpper) && + NotEmptyZero(atrBandLower) && + (isBullish + ? pBar.close > atrBandLower + : pBar.close < atrBandUpper); + + // + // Reset Flags ... + if (!result) + { + // + isBullish = false; + isBearish = false; + } + } + + // + // for Bullish has Support ... + // for Bearish has Resistance ... + if (result && validateMarketStructureHasDirectionalZone) + { + // + XOHCL tmpBar; + XPivot tmpPivot; + XBoxZone _support; + XBoxZone _resistance; + + // + // Check Market Strucutre Has Support / Resistance ... + bool hasSupport = pBarPatterns.IsSupport(); + bool hasResistance = pBarPatterns.IsResistance(); + + // + // Retrieve Support / Resistance Zone ... + if (hasSupport) + { + pBarPatterns.GetSupport(tmpBar, tmpPivot, _support); + } + if (hasResistance) + { + pBarPatterns.GetResistance(tmpBar, tmpPivot, _resistance); + } + + // + // Validate Support and Resistance by Order Flow ... + + // + // Converts Order Flow to Zone ... + XBoxZone ofZone; + bool hasOFBox = ToBox(ofZone, oFlow); + + // + // Check Market Strucutre Support and Resistance Validation ... + if (validateMarketStructureDirectionalZoneInsideOrderFlow) + { + // + hasSupport = + hasOFBox && + hasSupport && + ofZone.lower < _support.lower && + ofZone.upper > _support.upper; + + // + hasResistance = + hasOFBox && + hasResistance && + ofZone.lower < _resistance.lower && + ofZone.upper > _resistance.upper; + } + + // + // Validate Directional Support or Resistance Exists ... + + // + isBullish = + isBullish && + hasSupport; + + // + isBearish = + isBearish && + hasResistance; + + // + // Cleanup ... + ofZone.Clean(); + tmpBar.Clean(); + _support.Clean(); + tmpPivot.Clean(); + _resistance.Clean(); + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate Makret Structure Has Not Indirectional Zone ... + if (result && validateMarketStructureHasNotInDirectionalZoneOrUnReachedTP) + { + // + XOHCL tmpBar; + XPivot tmpPivot; + XBoxZone _support; + XBoxZone _resistance; + + // + // Check Market Strucutre Has Support / Resistance ... + bool hasSupport = pBarPatterns.IsSupport(); + bool hasResistance = pBarPatterns.IsResistance(); + + // + // Retrieve Support / Resistance Zone ... + if (hasSupport) + { + pBarPatterns.GetSupport(tmpBar, tmpPivot, _support); + } + if (hasResistance) + { + pBarPatterns.GetResistance(tmpBar, tmpPivot, _resistance); + } + + // + // Converts Order Flow to Zone ... + XBoxZone ofZone; + bool hasOFBox = ToBox(ofZone, oFlow); + + // + bool hasIndirectionalZone = + (isBullish && hasResistance) || + (isBearish && hasSupport); + if (hasIndirectionalZone) + { + // + // Here we Have to Validate Zone Place ... + + // + double point = GetPoints(bar.symbol); + double entry = GetEntry(bar.symbol, dir); + double slAddition = slAdditionDistance > 0 ? slAdditionDistance : 0; + double risk = MathAbs(entry - (isBullish ? oFlow[0].lower : oFlow[0].upper)) + (slAddition * point); + double reward = (defaultSignalR2R * risk); + double tp = isBullish + ? entry + reward + : entry - reward; + + // + // Bullish ... + if (isBullish && hasResistance) + { + hasResistance = _resistance.lower <= tp; + } + + // + // Bearish ... + if (isBearish && hasSupport) + { + hasSupport = _support.upper >= tp; + } + } + + // + isBullish = + isBullish && + !hasResistance; + + // + isBearish = + isBearish && + !hasSupport; + + // + // Cleanup ... + ofZone.Clean(); + tmpBar.Clean(); + _support.Clean(); + tmpPivot.Clean(); + _resistance.Clean(); + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate ... + result = isBullish || isBearish; + if (result) + { + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = HasDirection(dir); + } + + // + // Prepare Zone and do Zone Based Validations ... + if (result) + { + // + zone.Clean(); + result = ToBox( + p2Bar, + zone, + dir, + X_BAR_PATTERN_PINNED // + ); + + // + // Refine Zone ... + zone.to = bar.time; + zone.upper = MathMax(zone.upper, atrBandMiddle); + zone.lower = MathMin(zone.lower, atrBandMiddle); + + // + // Validate by XFIMA Boundary ... + if (result && validateByXFIMABoundary) + { + // + // Try to Retrieve Boundary To Trend ... + result = poiDetector.HasBoundaryTrend( + zone, + boundaryTrend, + true // + ); + + // + // Try to Retrieve Boundary Zone Trend ... + result = + result && + poiDetector.HasBoundaryTrend( + zone, + boundaryZoneTrend, + false // + ); + + // + // Check and Validate Trend Direction ... + result = + result && + zone.dir == boundaryTrend.dir && + zone.dir == boundaryZoneTrend.dir; + + // + // Reset Flags ... + if (!result) + { + // + zone.Clean(); + result = false; + isBullish = false; + isBearish = false; + } + } + + // + // Manage Stops ... + if (result) + { + // + // Since Stop Management Changes Zones Edge(s) ... + // we do it here for Refining Zone ... + } + + // + result = zone.IsValid(); + } + + // + // Prepare Targets ... + if (result) + { + // + XTarget iTarget; + + // + // Calculate Requirements ... + double point = GetPoints(bar.symbol); + double entry = GetEntry(bar.symbol, dir); + double slAddition = slAdditionDistance > 0 ? slAdditionDistance : 0; + double risk = MathAbs(entry - (isBullish ? zone.lower : zone.upper)) + (slAddition * point); + double reward = (defaultSignalR2R * risk); + double tp = isBullish + ? entry + reward + : entry - reward; + + // + // High Risk Target is Used to Protect In Profit Positiions + // from Reversal Patterns ... + double highRiskR2r = (defaultSignalR2R / 5) * 4; + double highRiskReward = highRiskR2r * risk; + double highRiskTP = isBullish + ? entry + highRiskReward + : entry - highRiskReward; + iTarget.Clean(); + iTarget.actingDistance = 5; + iTarget.doRFOnEntry = true; + iTarget.target = highRiskTP; + iTarget.volumeMultiplier = 0.8; + // AddRef(iTarget, targets); + + // + // Cleanup ... + iTarget.Clean(); + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + XClean(oFlow); + pBarPatterns.Clean(); + boundaryTrend.Clean(); + patternConfig.Clean(); + boundaryZoneTrend.Clean(); + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 index 19296d64..abf7177c 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.parser.class.mq5 @@ -9869,6 +9869,247 @@ class XCXFIMAHelperParser : XCBase // // Other Tools ... + /** + * Reading All Values of XFIMA ... + * + * @param dest: double, collection reference to holds values ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( int ) + */ + int ReadXFIMAValues( + double &dest[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(dest); + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + // Reading Values ... + double sar = helper.GetSAR(barIndex); + double scLL = helper.GetSLL(barIndex); + double scHH = helper.GetSHH(barIndex); + double mcLL = helper.GetMLL(barIndex); + double mcHH = helper.GetMHH(barIndex); + double lcLL = helper.GetLLL(barIndex); + double lcHH = helper.GetLHH(barIndex); + double hcLL = helper.GetHLL(barIndex); + double hcHH = helper.GetHHH(barIndex); + double peak = helper.GetPeak(barIndex); + double vale = helper.GetVale(barIndex); + double scMa = helper.GetSCMA(barIndex); + double mcMa = helper.GetMCMA(barIndex); + double lcMa = helper.GetLCMA(barIndex); + double hcMa = helper.GetHCMA(barIndex); + double maFast = helper.GetMAFast(barIndex); + double maSlow = helper.GetMASlow(barIndex); + double fibLower = helper.GetFiboLower(barIndex); + double fibUpper = helper.GetFiboUpper(barIndex); + double fibMiddle = helper.GetFiboMiddle(barIndex); + double maBandUpper = helper.GetMABandUpper(barIndex); + double maBandLower = helper.GetMABandLower(barIndex); + double hkBandUpper = helper.GetHKBandUpper(barIndex); + double hkBandLower = helper.GetHKBandLower(barIndex); + double pbBandUpper = helper.GetPBBandUpper(barIndex); + double pbBandLower = helper.GetPBBandLower(barIndex); + double atrBandUpper = helper.GetATRBandUpper(barIndex); + double atrBandLower = helper.GetATRBandLower(barIndex); + + // + // Add Values to Dest ... + + // + if (NotEmptyZero(sar)) + { + Add(sar, dest); + } + + // + if (NotEmptyZero(scLL)) + { + Add(scLL, dest); + } + + // + if (NotEmptyZero(scHH)) + { + Add(scHH, dest); + } + + // + if (NotEmptyZero(mcLL)) + { + Add(mcLL, dest); + } + + // + if (NotEmptyZero(mcHH)) + { + Add(mcHH, dest); + } + + // + if (NotEmptyZero(lcLL)) + { + Add(lcLL, dest); + } + + // + if (NotEmptyZero(lcHH)) + { + Add(lcHH, dest); + } + + // + if (NotEmptyZero(hcLL)) + { + Add(hcLL, dest); + } + + // + if (NotEmptyZero(hcHH)) + { + Add(hcHH, dest); + } + + // + if (NotEmptyZero(peak)) + { + Add(peak, dest); + } + + // + if (NotEmptyZero(vale)) + { + Add(vale, dest); + } + + // + if (NotEmptyZero(scMa)) + { + Add(scMa, dest); + } + + // + if (NotEmptyZero(mcMa)) + { + Add(mcMa, dest); + } + + // + if (NotEmptyZero(lcMa)) + { + Add(lcMa, dest); + } + + // + if (NotEmptyZero(hcMa)) + { + Add(hcMa, dest); + } + + // + if (NotEmptyZero(maFast)) + { + Add(maFast, dest); + } + + // + if (NotEmptyZero(maSlow)) + { + Add(maSlow, dest); + } + + // + if (NotEmptyZero(fibLower)) + { + Add(fibLower, dest); + } + + // + if (NotEmptyZero(fibUpper)) + { + Add(fibUpper, dest); + } + + // + if (NotEmptyZero(fibMiddle)) + { + Add(fibMiddle, dest); + } + + // + if (NotEmptyZero(maBandUpper)) + { + Add(maBandUpper, dest); + } + + // + if (NotEmptyZero(maBandLower)) + { + Add(maBandLower, dest); + } + + // + if (NotEmptyZero(hkBandUpper)) + { + Add(hkBandUpper, dest); + } + + // + if (NotEmptyZero(hkBandLower)) + { + Add(hkBandLower, dest); + } + + // + if (NotEmptyZero(pbBandUpper)) + { + Add(pbBandUpper, dest); + } + + // + if (NotEmptyZero(pbBandLower)) + { + Add(pbBandLower, dest); + } + + // + if (NotEmptyZero(atrBandUpper)) + { + Add(atrBandUpper, dest); + } + + // + if (NotEmptyZero(atrBandLower)) + { + Add(atrBandLower, dest); + } + + // + result = ArraySize(dest); + + // + return result; + } + // // Protected ... protected: diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index 6283fb86..8da83db4 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -1915,6 +1915,20 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller return result; } + // + // Validator Flags ... + bool validateByATRZone = false; + bool validateByBarPatterns = false; + bool validateRejectedXFIMA = true; + bool validateByAffectedZone = false; + bool validateStartedPullback = true; + bool validateStartedPinnedBar = true; + bool validateByPinBarZoneTrend = false; + bool validateByDirectionalZones = false; + bool validateByDoubleBarPatterns = false; + bool validateByCycleMAsDirection = true; + bool validateByInDirectionalZones = false; + // // Define Requirements ... @@ -1922,27 +1936,25 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller XOHCL pBar; XOHCL p2Bar; XOHCL p3Bar; - XOHCL tmpBar; - XPivot tmpPivot; XBoxZone atrBox; - XBoxZone zones[]; - XBoxZone tmpZone; - XBoxZone scPVZone; XBoxZone mcPVZone; XBoxZone lcPVZone; XBoxZone hcPVZone; - XBoxZone tmpZones[]; - XBoxZone pinBarZone; + double rejecteds[]; XBoxZone supports[]; - XBoxZone resistances[]; + XBoxZone pinBarZone; + XBoxZone pullbackZone; XBoxZone affectedZone; + XBoxZone resistances[]; XTrend pinBarZoneTrend; bool isBullish = false; bool isBearish = false; - ENUM_X_DIRECTION tmpDir; + XPatternAnalysis iPatterns; + XPatternAnalysis iPPatterns; XPatternAnalysis pBarPatterns; XPatternAnalysis p2BarPatterns; XPatternAnalysis p3BarPatterns; + ENUM_X_BAR_PATTERN doublePatterns[]; XPatternAnalysisConfig iPatternsConfig; // @@ -2003,263 +2015,11 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller return result; } - // - // Detect Directional Candlestic Patterns ... - - // - // Bullish ... - bool isPBarHasBullishPatterns = - (bar.close > pBar.low || - bar.open > pBar.low) && - ( - // - pBarPatterns.IsPinned(X_DIRECTION_BULLISH) || - pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || - pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) || - pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) || - pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH) - // - ); - bool isP2BarHasBullishPatterns = - (bar.close > p2Bar.low || - bar.open > p2Bar.low) && - ( - // - p2BarPatterns.IsPinned(X_DIRECTION_BULLISH) || - p2BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || - p2BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || - p2BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || - p2BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) - // - ); - bool isP3BarHasBullishPatterns = - (bar.close > p3Bar.low || - bar.open > p3Bar.low) && - ( - // - p3BarPatterns.IsPinned(X_DIRECTION_BULLISH) || - p3BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || - p3BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || - p3BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || - p3BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) - // - ); - - // - // Bearish ... - bool isPBarHasBearishPatterns = - (bar.close < pBar.high || - bar.open < pBar.high) && - ( - // - pBarPatterns.IsPinned(X_DIRECTION_BEARISH) || - pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || - pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) || - pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) || - pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH) - // - ); - bool isP2BarHasBearishPatterns = - (bar.close < p2Bar.high || - bar.open < p2Bar.high) && - ( - // - p2BarPatterns.IsPinned(X_DIRECTION_BEARISH) || - p2BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || - p2BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || - p2BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || - p2BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) - // - ); - bool isP3BarHasBearishPatterns = - (bar.close < p3Bar.high || - bar.open < p3Bar.high) && - ( - // - p3BarPatterns.IsPinned(X_DIRECTION_BEARISH) || - p3BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || - p3BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || - p3BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || - p3BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) - // - ); - - // - // Checking Support and Resistances ... - - // - // Support ... - bool hasSupport = pBarPatterns.IsSupport(); - if (hasSupport) - { - // - hasSupport = pBarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); - if (hasSupport) - { - AddIfNotExists(tmpZone, supports); - } - } - hasSupport = p2BarPatterns.IsSupport(); - if (hasSupport) - { - // - hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); - if (hasSupport) - { - AddIfNotExists(tmpZone, supports); - } - } - hasSupport = p3BarPatterns.IsSupport(); - if (hasSupport) - { - // - hasSupport = p3BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); - if (hasSupport) - { - AddIfNotExists(tmpZone, supports); - } - } - - // - // Resistance ... - bool hasResistance = pBarPatterns.IsResistance(); - if (hasResistance) - { - // - hasResistance = pBarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); - if (hasResistance) - { - AddIfNotExists(tmpZone, resistances); - } - } - hasResistance = p2BarPatterns.IsResistance(); - if (hasResistance) - { - // - hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); - if (hasResistance) - { - AddIfNotExists(tmpZone, resistances); - } - } - hasResistance = p3BarPatterns.IsResistance(); - if (hasResistance) - { - // - hasResistance = p3BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); - if (hasResistance) - { - AddIfNotExists(tmpZone, resistances); - } - } - - // - // Collecting Zones ... - - // - int collectedZonesCount = poiDetector.DetectZones( - bar, - zones, - true, // Validated Zones ... - false, // Remove Used Zones ... - false, // Contains Order Blocks ... - true, // Contains Fair Value Gaps ... - true, // Contains Supports ... - true, // Contains Resistances ... - X_DIRECTION_NONE, // For Dir (Contains All Direction Zones) ... - X_SORT_BY_DATE, // Sort By ... - X_DIRECTION_BEARISH, // Sort Dir ... - 3, // Zones Loopback ... - 3, // Zones Validation Length ... - 0, // Count (All Zones) ... - 100 // Loop back for Detection ... - ); - bool hasCollectedZones = IsValidSize(collectedZonesCount) && - collectedZonesCount > 1; - int affectedZonesCount = 0; - bool hasAffectedZone = false; - int collectedZonesBullishCount = 0; - int collectedZonesBearishCount = 0; - bool hasBullishAffectedZone = false; - bool hasBearishAffectedZone = false; - bool hasBullishCollectedZones = false; - bool hasBearishCollectedZones = false; - if (hasCollectedZones) - { - // - // Bullish ... - XClean(tmpZones); - collectedZonesBullishCount = ExtractByDirection(tmpZones, zones, X_DIRECTION_BULLISH); - hasBullishCollectedZones = IsValidSize(collectedZonesBullishCount); - - // - // Bearish ... - XClean(tmpZones); - collectedZonesBearishCount = ExtractByDirection(tmpZones, zones, X_DIRECTION_BEARISH); - hasBearishCollectedZones = IsValidSize(collectedZonesBearishCount); - - // - // Extract Affected Zones ... - XClean(tmpZones); - int affectedZonesCount = ExtractAffectedZones(p2Bar, zones, tmpZones); - int idx = GetYoungest(tmpZones); - if (IsValidIndex(idx)) - { - affectedZone = tmpZones[idx]; - } - hasAffectedZone = affectedZone.IsValid(); - hasBullishAffectedZone = hasAffectedZone && affectedZone.IsBullish(); - hasBearishAffectedZone = hasAffectedZone && affectedZone.IsBearish(); - } - - // - // Reading Cycle PVS ... - bool hasSCPV = poiDetector.GetSCZone(pBar, scPVZone); - bool hasMCPV = poiDetector.GetMCZone(pBar, mcPVZone); - bool hasLCPV = poiDetector.GetLCZone(pBar, lcPVZone); - bool hasHCPV = poiDetector.GetHCZone(pBar, hcPVZone); - bool isCyclePVBullish = - hasMCPV && mcPVZone.IsBullish() && - hasLCPV && lcPVZone.IsBullish() && - hasHCPV && hcPVZone.IsBullish(); - bool isCyclePVBearish = - hasMCPV && mcPVZone.IsBearish() && - hasLCPV && lcPVZone.IsBearish() && - hasHCPV && hcPVZone.IsBearish(); - - // - // Validating Market Direction ... - // by Checking HC and LC States ... - - // - bool isLCBullish = fimaParser.IsLCMABullish(pBar.Index()); - bool isHCBullish = fimaParser.IsHCMABullish(pBar.Index()); - bool isLCHigherLow = - (fimaParser.IsLCHigherLow(pBar.Index()) || - fimaParser.IsLCHigherLow(p2Bar.Index()) || - fimaParser.IsLCHigherLow(p3Bar.Index())); - bool isCyclesBullish = - isLCBullish && - isHCBullish && - isLCHigherLow; - - // - bool isLCBearish = fimaParser.IsLCMABearish(pBar.Index()); - bool isHCBearish = fimaParser.IsHCMABearish(pBar.Index()); - bool isLCLowerHigh = - (fimaParser.IsLCLowerHigh(pBar.Index()) || - fimaParser.IsLCLowerHigh(p2Bar.Index()) || - fimaParser.IsLCLowerHigh(p3Bar.Index())); - bool isCyclesBearish = - isLCBearish && - isHCBearish && - isLCLowerHigh; - // // Looking For a Pin Bar in P2Bar ... bool isP2BarIsPinBar = poiDetector.IsPinnedBar( p2Bar, - tmpDir, + dir, 4, // Shadow Multiplier ... 4, // Minimum Range Multiplier ... true // Force Pin Bar Direction ... @@ -2270,94 +2030,778 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller isP2BarIsPinBar = ToBox( p2Bar, pinBarZone, - tmpDir, + dir, X_BAR_PATTERN_PINNED // ); if (isP2BarIsPinBar) { // pinBarZone.to = bar.time; - isP2BarIsPinBar = poiDetector.HasBoundaryTrend( - pinBarZone, - pinBarZoneTrend, - false // - ); - isP2BarIsPinBar = - isP2BarIsPinBar && - tmpDir == pinBarZoneTrend.dir; + + // + // Validate By PinBar Zone Trend ... + if (validateByPinBarZoneTrend) + { + // + isP2BarIsPinBar = poiDetector.HasBoundaryTrend( + pinBarZone, + pinBarZoneTrend, + false // + ); + + // + isP2BarIsPinBar = + isP2BarIsPinBar && + dir == pinBarZoneTrend.dir; + } + + // + // Validate PinBar Zone By XFIMA ... + if (validateRejectedXFIMA) + { + // + int rejectedsCount = poiDetector.IsRejectXFIMA(p2Bar, rejecteds, pinBarZone.dir); + isP2BarIsPinBar = IsValidSize(rejectedsCount); + } } } - bool isP2BarPinnedBullish = isP2BarIsPinBar && IsXBullish(tmpDir); - bool isP2BarPinnedBearish = isP2BarIsPinBar && IsXBearish(tmpDir); + bool isP2BarPinnedBullish = isP2BarIsPinBar && IsXBullish(dir); + bool isP2BarPinnedBearish = isP2BarIsPinBar && IsXBearish(dir); // - // Checking ATR Box ... - bool hasATRBox = fimaParser.GetATRBox( - atrBox, - bar.Index() // - ); - bool hasATRBoxBullish = hasATRBox && atrBox.IsBullish(); - bool hasATRBoxBearish = hasATRBox && atrBox.IsBearish(); - - // - // Checking Double Patterns ... - ENUM_X_DIRECTION iDBDir; - XPatternAnalysis iPatterns; - XPatternAnalysis iPPatterns; - ENUM_X_BAR_PATTERN doublePatterns[]; - GetCandlestickPatterns(doublePatterns); - bool hasDoublePatterns = poiDetector.HasDoublePatterns( + // Check P2Bar is Pullback Bar ... + bool isPBarIsPullBack = poiDetector.IsPullbackPattern( pBar, - iDBDir, - iPatterns, - iPPatterns, - doublePatterns, - iPatternsConfig, - 5 // + pullbackZone, + dir, + 2, // Pull back Length ... + false // Force Break Pullback ... ); - bool hasBullishDoublePatterns = hasDoublePatterns && IsXBullish(iDBDir); - bool hasBearishDoublePatterns = hasDoublePatterns && IsXBearish(iDBDir); + bool isPBarPullbackBullish = isPBarIsPullBack && pullbackZone.IsBullish(); + bool isPBarPullbackBaerish = isPBarIsPullBack && pullbackZone.IsBearish(); + if (isPBarIsPullBack && validateRejectedXFIMA) + { + // + double iRejecteds[]; + int rejectedCounts = poiDetector.IsRejectXFIMA( + p2Bar, + iRejecteds, + dir, + X_PRICE_CLOSE, + X_PRICE_OPEN, + X_PRICE_OPEN, + X_PRICE_CLOSE, + false // + ); + isPBarIsPullBack = IsValidSize(rejectedCounts); + if (isPBarIsPullBack) + { + // + Copy( + iRejecteds, + rejecteds, + false // + ); + } + } // isBullish = - // - hasSupport && - hasResistance && - isCyclesBullish && - hasATRBoxBullish && - isCyclePVBullish && - isP2BarPinnedBullish && - hasBullishAffectedZone && - isPBarHasBullishPatterns && - hasBullishCollectedZones && - isP2BarHasBullishPatterns && - collectedZonesBullishCount > collectedZonesBearishCount && - true - // - ; + isP2BarPinnedBullish || + isPBarPullbackBullish; // isBearish = - // - hasSupport && - hasResistance && - isCyclesBearish && - hasATRBoxBearish && - isCyclePVBearish && - isP2BarPinnedBearish && - hasBearishAffectedZone && - isPBarHasBearishPatterns && - hasBearishCollectedZones && - isP2BarHasBearishPatterns && - collectedZonesBearishCount > collectedZonesBullishCount && - true - // - ; + isP2BarPinnedBearish || + isPBarPullbackBullish; // - // Validate ... - result = isBullish || - isBearish; + result = isBullish || isBearish; + + // + // Validate Starter Pinned ... + if (result && validateStartedPinnedBar && !validateStartedPullback) + { + // + isBullish = + isBullish && + isP2BarPinnedBullish; + + // + isBearish = + isBearish && + isP2BarPinnedBearish; + + // + result = isBullish || isBearish; + } + + // + // Validate Starter Pullback ... + if (result && !validateStartedPinnedBar && validateStartedPullback) + { + // + isBullish = + isBullish && + isPBarPullbackBullish; + + // + isBearish = + isBearish && + isPBarPullbackBaerish; + + // + result = isBullish || isBearish; + } + + // + // Prepare Zone ... + if (result) + { + // + string type = NULL; + datetime to = NULL; + datetime from = NULL; + double upper = EMPTY_VALUE; + double lower = EMPTY_VALUE; + ENUM_X_DIRECTION zDir = X_DIRECTION_NONE; + + // + zone.at = bar.time; + zone.symbol = bar.symbol; + zone.period = bar.period; + + // + if (pinBarZone.IsValid()) + { + // + upper = + !NotEmptyZero(upper) + ? pinBarZone.upper + : MathMax(upper, pinBarZone.upper); + + // + lower = + !NotEmptyZero(lower) + ? pinBarZone.lower + : MathMin(lower, pinBarZone.lower); + + // + to = bar.time; + from = !IsXValid(from) + ? pinBarZone.from + : MathMin(from, pinBarZone.from); + + // + zDir = pinBarZone.dir; + type = pinBarZone.type; + } + + // + if (pullbackZone.IsValid()) + { + // + upper = + !NotEmptyZero(upper) + ? pullbackZone.upper + : MathMax(upper, pullbackZone.upper); + + // + lower = + !NotEmptyZero(lower) + ? pullbackZone.lower + : MathMin(lower, pullbackZone.lower); + + // + from = !IsXValid(from) + ? pullbackZone.from + : MathMin(from, pullbackZone.from); + + // + if (!HasDirection(zDir)) + { + zDir = pullbackZone.dir; + } + + // + type = + !IsXValid(type) + ? pullbackZone.type + : type + "_" + pullbackZone.type; + } + + // + zone.to = to; + zone.dir = zDir; + zone.from = from; + zone.type = type; + zone.upper = upper; + zone.lower = lower; + + // + result = zone.IsValid(); + if (result) + { + // + int zoneLength = zone.FromIndex() - zone.ToIndex(); + double zoneLL = pBar.FindLowest(zoneLength, MODE_LOW); + double zoneHH = pBar.FindHighest(zoneLength, MODE_HIGH); + + // + if (zone.IsBullish()) + { + zone.lower = MathMin(zone.lower, zoneLL); + } + if (zone.IsBearish()) + { + zone.upper = MathMax(zone.upper, zoneHH); + } + } + + // + if (!result) + { + // + result = false; + isBullish = false; + isBearish = false; + dir = X_DIRECTION_NONE; + } + + // + if (result) + { + // + poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig); + DebugBreak(); + } + + // + zone.Clean(); + result = false; + isBullish = false; + isBearish = false; + dir = X_DIRECTION_NONE; + } + + // + // Validate By Affected Zone ... + if (result && validateByAffectedZone) + { + // + // Prepare Zone ... + + // + XOHCL tmpBar; + XBoxZone tmpZone; + + // + isBullish = + isBullish && + poiDetector.IsSupportTouched( + p2Bar, + tmpBar, + tmpZone, + 5, + 21 // + ); + if (isBullish) + { + affectedZone = tmpZone; + } + + // + isBearish = + isBearish && + poiDetector.IsResistanceTouched( + p2Bar, + tmpBar, + tmpZone, + 5, + 21 // + ); + if (isBearish) + { + affectedZone = tmpZone; + } + + // + tmpBar.Clean(); + tmpZone.Clean(); + + // + result = isBullish || isBearish; + } + + // + // Validate By ATR Zone ... + if (result && validateByATRZone) + { + // + // Checking ATR Box ... + bool hasATRBox = fimaParser.GetATRBox( + atrBox, + bar.Index() // + ); + bool hasATRBoxBullish = hasATRBox && atrBox.IsBullish(); + bool hasATRBoxBearish = hasATRBox && atrBox.IsBearish(); + + // + isBullish = + isBullish && + hasATRBoxBullish; + + // + isBearish = + isBearish && + hasATRBoxBearish; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Detect Directional Candlestic Patterns ... + if (result && validateByBarPatterns) + { + // + // Bullish ... + bool isPBarHasBullishPatterns = + (bar.close > pBar.low || + bar.open > pBar.low) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BULLISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isP2BarHasBullishPatterns = + (bar.close > p2Bar.low || + bar.open > p2Bar.low) && + ( + // + p2BarPatterns.IsPinned(X_DIRECTION_BULLISH) || + p2BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + p2BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + p2BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + p2BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isP3BarHasBullishPatterns = + (bar.close > p3Bar.low || + bar.open > p3Bar.low) && + ( + // + p3BarPatterns.IsPinned(X_DIRECTION_BULLISH) || + p3BarPatterns.IsEngulfed(X_DIRECTION_BULLISH) || + p3BarPatterns.IsMomentum(X_DIRECTION_BULLISH) || + p3BarPatterns.IsPiercing(X_DIRECTION_BULLISH) || + p3BarPatterns.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + + // + // Bearish ... + bool isPBarHasBearishPatterns = + (bar.close < pBar.high || + bar.open < pBar.high) && + ( + // + pBarPatterns.IsPinned(X_DIRECTION_BEARISH) || + pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + bool isP2BarHasBearishPatterns = + (bar.close < p2Bar.high || + bar.open < p2Bar.high) && + ( + // + p2BarPatterns.IsPinned(X_DIRECTION_BEARISH) || + p2BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + p2BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + p2BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + p2BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + bool isP3BarHasBearishPatterns = + (bar.close < p3Bar.high || + bar.open < p3Bar.high) && + ( + // + p3BarPatterns.IsPinned(X_DIRECTION_BEARISH) || + p3BarPatterns.IsEngulfed(X_DIRECTION_BEARISH) || + p3BarPatterns.IsMomentum(X_DIRECTION_BEARISH) || + p3BarPatterns.IsPiercing(X_DIRECTION_BEARISH) || + p3BarPatterns.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + bool hasBullishPatterns = + isPBarHasBullishPatterns && + (isP2BarHasBullishPatterns || + isP3BarHasBullishPatterns); + + // + bool hasBearishPatterns = + isPBarHasBearishPatterns && + (isP2BarHasBearishPatterns || + isP3BarHasBearishPatterns); + + // + isBullish = + isBullish && + hasBullishPatterns; + + // + isBearish = + isBearish && + hasBearishPatterns; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validating Market Direction ... + if (result && validateByCycleMAsDirection) + { + // + // Bullish ... + bool isLCBullish = fimaParser.IsLCMABullish(pBar.Index()); + bool isHCBullish = fimaParser.IsHCMABullish(pBar.Index()); + bool isLCHigherLow = + (fimaParser.IsLCHigherLow(pBar.Index()) || + fimaParser.IsLCHigherLow(p2Bar.Index()) || + fimaParser.IsLCHigherLow(p3Bar.Index())); + bool isCyclesBullish = + isLCBullish && + isHCBullish && + isLCHigherLow; + + // + // Bearish ... + bool isLCBearish = fimaParser.IsLCMABearish(pBar.Index()); + bool isHCBearish = fimaParser.IsHCMABearish(pBar.Index()); + bool isLCLowerHigh = + (fimaParser.IsLCLowerHigh(pBar.Index()) || + fimaParser.IsLCLowerHigh(p2Bar.Index()) || + fimaParser.IsLCLowerHigh(p3Bar.Index())); + bool isCyclesBearish = + isLCBearish && + isHCBearish && + isLCLowerHigh; + + // + isBullish = + isBullish && + isCyclesBullish; + + // + isBearish = + isBearish && + isCyclesBearish; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate By Double Bar Patterns ... + if (result && validateByDoubleBarPatterns) + { + // + GetCandlestickPatterns(doublePatterns); + bool hasDoublePatterns = poiDetector.HasDoublePatterns( + pBar, + dir, + iPatterns, + iPPatterns, + doublePatterns, + iPatternsConfig, + 5 // + ); + bool hasBullishDoublePatterns = hasDoublePatterns && IsXBullish(dir); + bool hasBearishDoublePatterns = hasDoublePatterns && IsXBearish(dir); + + // + isBullish = + isBullish && + hasBullishDoublePatterns; + + // + isBearish = + isBearish && + hasBearishDoublePatterns; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate by Directional Zones ... + if (result && validateByDirectionalZones) + { + // + // Collecting Zones ... + XOHCL tmpBar; + XPivot tmpPivot; + XBoxZone tmpZone; + + // + // Support ... + bool hasSupport = pBarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = pBarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p2BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p3BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p3BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = HasChild(supports); + + // + // Resistance ... + bool hasResistance = pBarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = pBarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p2BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p3BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p3BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = HasChild(resistances); + + // + // Cleanup ... + tmpBar.Clean(); + tmpZone.Clean(); + tmpPivot.Clean(); + + // + // Validating ... + + // + isBullish = + isBullish && + hasSupport; + + // + isBearish = + isBearish && + hasResistance; + + // + // Summarize Result ... + result = isBullish || isBearish; + } + + // + // Validate by InDirectional Zones ... + if (result && validateByInDirectionalZones) + { + // + // Collecting Zones ... + XOHCL tmpBar; + XPivot tmpPivot; + XBoxZone tmpZone; + + // + // Supports ... + bool hasSupport = false; + if (!HasChild(supports)) + { + // + hasSupport = pBarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = pBarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p2BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = p3BarPatterns.IsSupport(); + if (hasSupport) + { + // + hasSupport = p3BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone); + if (hasSupport) + { + AddIfNotExists(tmpZone, supports); + } + } + hasSupport = HasChild(supports); + } + hasSupport = HasChild(supports); + + // + // Resistances ... + bool hasResistance = false; + if (!HasChild(resistances)) + { + // + hasResistance = pBarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = pBarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p2BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = p3BarPatterns.IsResistance(); + if (hasResistance) + { + // + hasResistance = p3BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone); + if (hasResistance) + { + AddIfNotExists(tmpZone, resistances); + } + } + hasResistance = HasChild(resistances); + } + hasResistance = HasChild(resistances); + + // + // Cleanup ... + tmpBar.Clean(); + tmpZone.Clean(); + tmpPivot.Clean(); + + // + // Validate by Not InDirectional Exixsts ... + result = + (isBullish && !hasResistance) || + (isBearish && !hasSupport); + + // + // Validate InDirectional Distance by TP ... + if (!result) + { + // + // Calculate Requirements ... + double points = GetPoints(bar.symbol); + double entry = GetEntry(bar.symbol, (isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH)); + double slAddition = slAdditionDistance <= 0 ? 0 : slAdditionDistance * points; + double sl = isBullish + ? pinBarZone.lower - slAddition + : pinBarZone.upper + slAddition; + double risk = MathAbs(entry - sl); + double tpReward = defaultSignalR2R * risk; + double tp = isBullish + ? entry + tpReward + : entry - tpReward; + + // + int idx = -1; + if (isBullish) + { + idx = GetYoungest(resistances); + } + else if (isBearish) + { + idx = GetYoungest(supports); + } + result = IsValidIndex(idx); + result = + result && + (isBullish + ? tp < resistances[idx].lower + : tp > supports[idx].upper); + } + + // + // Reset Flags ... + if (!result) + { + // + result = false; + isBullish = false; + isBearish = false; + dir = X_DIRECTION_NONE; + } + } + + // + // Detecting Direction ... if (result) { // @@ -2375,10 +2819,8 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller if (result) { // - zone.Clean(); - zone = pinBarZone; - - // + // Since Zone Prepared in Above Steps ... + // here we only Validate it ... result = zone.IsValid(); } @@ -2393,39 +2835,98 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller iConfig.trendRayRight = false; // - // poiDrawer.DrawZone(scPVZone, iConfig); + // PinBar Zone ... + if (pinBarZone.IsValid()) + { + poiDrawer.DrawZone(pinBarZone, iConfig); + } + + // + // Pullback Zone ... + if (pullbackZone.IsValid()) + { + poiDrawer.DrawZone(pullbackZone, iConfig); + } + + // + // PinBar Zone Trend ... + if (pinBarZoneTrend.IsValid()) + { + poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig); + } + + // + // Rejected Values ... + if (HasChild(rejecteds)) + { + // + XTrend iTrend; + bool has = false; + int count = ArraySize(rejecteds); + datetime toTime = zone.to + PeriodSeconds(zone.period); + datetime fromTime = zone.to - PeriodSeconds(zone.period); + for (int i = 0; i < count; i++) + { + // + // Initialize Trend ... + iTrend.Clean(); + has = iTrend.Init( + bar.symbol, + bar.period, + bar.time, + rejecteds[i], + fromTime, + rejecteds[i], + toTime // + ); + if (has) + { + poiDrawer.DrawTrendLine(iTrend, iConfig); + } + } + } + + // + // Draw Zone ... + if (zone.IsValid()) + { + // + iConfig.zonesStyle = STYLE_DASHDOT; + iConfig.bullishColor = clrYellow; + iConfig.bearishColor = clrDarkOrange; + + // + poiDrawer.DrawZone(zone, iConfig); + } + + // // poiDrawer.DrawZone(mcPVZone, iConfig); // poiDrawer.DrawZone(lcPVZone, iConfig); // poiDrawer.DrawZone(hcPVZone, iConfig); + // + // poiDrawer.DrawZone(pinBarZone, iConfig); + // poiDrawer.DrawZone(pullbackZone, iConfig); + // poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig); + // poiDrawer.DrawPatternAnalysis(pBarPatterns, iPatternsConfig); poiDrawer.DrawPatternAnalysis(p2BarPatterns, iPatternsConfig); poiDrawer.DrawPatternAnalysis(p3BarPatterns, iPatternsConfig); // - poiDrawer.DrawZone(pinBarZone, iConfig); - poiDrawer.DrawZone(affectedZone, iConfig); - poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig); + // if (hasATRBox) + // { + // poiDrawer.DrawZone(atrBox, iConfig); + // } // - // poiDrawer.DrawZones(zones, iConfig); - poiDrawer.DrawZones(supports, iConfig); - poiDrawer.DrawZones(resistances, iConfig); - - // - if (hasATRBox) - { - poiDrawer.DrawZone(atrBox, iConfig); - } - - // - if (hasDoublePatterns) - { - // - poiDrawer.DrawPatternAnalysis(iPatterns, iPatternsConfig); - poiDrawer.DrawPatternAnalysis(iPPatterns, iPatternsConfig); - } + // if (hasDoublePatterns) + // { + // // + // poiDrawer.DrawPatternAnalysis(iPatterns, iPatternsConfig); + // poiDrawer.DrawPatternAnalysis(iPPatterns, iPatternsConfig); + // } // iConfig.Clean(); @@ -2459,22 +2960,21 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); - XClean(zones); - tmpBar.Clean(); - tmpZone.Clean(); XClean(supports); - XClean(tmpZones); - scPVZone.Clean(); mcPVZone.Clean(); lcPVZone.Clean(); hcPVZone.Clean(); - tmpPivot.Clean(); + XClean(rejecteds); + iPatterns.Clean(); pinBarZone.Clean(); + iPPatterns.Clean(); XClean(resistances); affectedZone.Clean(); + pullbackZone.Clean(); pBarPatterns.Clean(); p2BarPatterns.Clean(); p3BarPatterns.Clean(); + XClean(doublePatterns); pinBarZoneTrend.Clean(); iPatternsConfig.Clean(); diff --git a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 index 5600e073..866a90c0 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -490,10 +490,10 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector /** * Detect XPV Zone ... - * + * * @param zone: XBoxZone, reference to Holds detected Zone ... * @param barIndex: int, Specified Bar Index ... - * + * * @return ( bool ) */ bool DetectXPVZone( @@ -1610,11 +1610,11 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector /** * Collect Specified ZOnes Boundary Min / Max Values ... - * + * * @param uppers: XPivot, collection reference to holds Peaks of Zone's Boundary ... * @param lowers: XPivot, collection reference to holds Vales of Zone's Boundary ... * @param zone: XBoxZone, reference to Provide Specified Zone for Boundary Detection ... - * + * * @return ( int ) */ int CollectZonesBoundary( @@ -2088,6 +2088,112 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector return result; } + /** + * Check Specified Bar is Rejected Specified XFIMA Values or not ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param rejecteds: double, collection reference to holds Rejected Values ... + * @param forDir: ENUM_X_DIRECTION, Specified required Rejection Direction ... + * @param bullishRejectUpperPriceType: ENUM_X_PRICE, Specified Bullish Rejection Upper Price Type ... + * @param bullishRejectLowerPriceType: ENUM_X_PRICE, Specified Bullish Rejection Lower Price Type ... + * @param bearishRejectUpperPriceType: ENUM_X_PRICE, Specified Bearish Rejection Upper Price Type ... + * @param bearishRejectLowerPriceType: ENUM_X_PRICE, Specified Bearish Rejection Lower Price Type ... + * @param ignoreBoundary: bool, ignoring XFIMA Max and Min Values Rejections ... + * + * @return ( int ) + */ + int IsRejectXFIMA( + XOHCL &bar, + double &rejecteds[], + ENUM_X_DIRECTION forDir, + ENUM_X_PRICE bullishRejectUpperPriceType = X_PRICE_DOWN, + ENUM_X_PRICE bullishRejectLowerPriceType = X_PRICE_LOW, + ENUM_X_PRICE bearishRejectUpperPriceType = X_PRICE_HIGH, + ENUM_X_PRICE bearishRejectLowerPriceType = X_PRICE_UP, + bool ignoreBoundary = false // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(rejecteds); + + // + // Validate ... + bool has = + bar.IsValid() && + fimaParser.IsValid() && + HasDirection(forDir) && + IsXValid(bullishRejectLowerPriceType) && + IsXValid(bullishRejectUpperPriceType) && + IsXValid(bearishRejectUpperPriceType) && + IsXValid(bearishRejectLowerPriceType); + if (!has) + { + return result; + } + + // + int pBarIndex = bar.Index() + 1; + bool isBullish = IsXBullish(forDir); + + // + // Reading Values ... + double values[]; + int count = fimaParser.ReadXFIMAValues(values, pBarIndex); + has = HasChild(values); + + // + // Detect Rejected Prices ... + if (has) + { + // + double min = GetMin(values); + double max = GetMax(values); + + // + for (int i = 0; i < count; i++) + { + // + // Detect Rejection ... + has = + isBullish + ? (bar.GetPrice(bullishRejectLowerPriceType) < values[i] && + bar.GetPrice(bullishRejectUpperPriceType) > values[i]) + : (bar.GetPrice(bearishRejectUpperPriceType) > values[i] && + bar.GetPrice(bearishRejectLowerPriceType) < values[i]); + if (has) + { + // + // Validate Rejection ... + if (ignoreBoundary) + { + // + has = + has && + (values[i] != min && + values[i] != max); + } + + // + // Add Result ... + if (has) + { + Add(values[i], rejecteds); + } + } + } + } + + // + result = ArraySize(rejecteds); + + // + return result; + } + // // Others ...