diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 744a4f85..5b255076 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -1430,6 +1430,36 @@ class XCPOIDrawer : public XCBase ZeroMemory(iObj); } + /** + * Draw Specified Zones ... + * + * @param _zone: XBozxZone, reference to Collection Specified Zone ... + * @param config: XPOIDrawConfig, Darwing Configuration ... + */ + void DrawZones( + XBoxZone &_zones[], + XPOIDrawConfig &config // + ) + { + // + // Validate ... + bool has = HasChild(_zones); + if (!has) + { + return; + } + + // + for (int i = 0; i < ArraySize(_zones); i++) + { + // + DrawZone( + _zones[i], + config // + ); + } + } + /** * Draw Specified Pattern info ... * diff --git a/Documents/BKP/test.fima.conditions.mq5 b/Documents/BKP/test.fima.conditions.mq5 new file mode 100644 index 00000000..8e2d667a --- /dev/null +++ b/Documents/BKP/test.fima.conditions.mq5 @@ -0,0 +1,97 @@ + + // // + // isBullish = + // // + // // Vales Same ... + // sameVales >= 7 && + // // + // // PBar Patterns ... + // isBarPatternsPassed && + // isPBarCloseOverFast && + // // + // // Validate PullBack based on HK Bond ... + // isPullbackBullish && + // pBar.close > pHKBondLower; + + // + // poiDrawer.DrawPatternAnalysis( + // pBarAnalysis, + // structureDrawConfig.barAnalysisDrawConfig // + // ); + + // // + // if (IsValidSize(zonesCount)) + // { + // // + // poiDrawer.DrawZones( + // zones, + // structureDrawConfig.drawConfig // + // ); + // } + + // // + // if (IsValidSize(affectedZonesCount)) + // { + // // + // poiDrawer.DrawZones( + // affectedZones, + // structureDrawConfig.drawConfig // + // ); + // } + + // + // poiDrawer.DrawZones( + // affectedZonesBullish, + // structureDrawConfig.drawConfig // + // ); + + // // + // poiDrawer.DrawZones( + // affectedZonesBearish, + // structureDrawConfig.drawConfig // + // ); + + + + + // // + // // Update POI Zones ... + // ENUM_X_DETECTOR_ZONE_ACTION zoneActions[]; + // poiDetector.UpdateZones( + // iBar, + // zoneActions // + // // Validation Length ... + // // Required Zones ... + // // Loopback ... + // ); + + // + // Retrieve Conditions ... + // conditions.Clean(); + // has = fimaHelper.GetConditions( + // conditions, + // barIndex, + // 10 // Loopback ... + // ); + // if (!has) + // { + // // + // iBar.Clean(); + // conditions.Clean(); + + // // + // return; + // } + + // + // structure.Clean(); + // poiDetector.AnalyseMarket( + // structure, + // structureConfig, + // barIndex // + // ); + // poiDrawer.drawnObjects.Clear(); + // poiDrawer.DrawMarketStructure( + // structure, + // structureDrawConfig // + // ); diff --git a/Documents/BKP/x-saherelm.xfima.signaller.class copy 3.mq5 b/Documents/BKP/x-saherelm.xfima.signaller.class copy 3.mq5 new file mode 100644 index 00000000..b29a2e53 --- /dev/null +++ b/Documents/BKP/x-saherelm.xfima.signaller.class copy 3.mq5 @@ -0,0 +1,1657 @@ +/////////////////////////////////////////////////////// +// +// 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.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 ... + + // + bool ignoreTargets; // Ignore Signal Targets ... + CArrayObj drawnObjects; // Drawing Objects Holder ... + XFIMAInputs fimaInputs; // XFIMA Inputs ... + XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... + XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ... + 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); + } + } + + // + poiDrawer = new XCXFIMAPOIDrawer(); + poiDetector = new XCXFIMAPOIDetector(fimaHelper); + + // + // 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; + + // + 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 ... + XFIMAMarketStructure structure; // XFIMA Market Structure ... + + // + // 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 ... + structureConfig.Default(); + structureDrawConfig.Default(); + + // + structure.Clean(); + + // + // Ignore Signal Targets ... + ignoreTargets = false; + } + + // + // Deconstructor ... + ~XCXFIMAStrategy1Signaller() + { + // + Destroy(); + + // + structure.Clean(); + } + + // + // 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; + int count = 0; + XBoxZone iZone; + XSignal iSignal; + bool has = false; + XTarget iTargets[]; + string iName = NULL; + bool isBullish = false; + bool isBearish = false; + XFIMAConditions iFIMAConditions; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Initialize Bar as CBar ... + has = iBar.Init( + symbol, + period, + barIndex // + ); + if (!has) + { + // + iBar.Clean(); + return; + } + + // + // Retrieve Conditions ... + has = fimaHelper.GetConditions( + iFIMAConditions, + barIndex, + 10 // Loopback ... + ); + if (!has) + { + // + iBar.Clean(); + iFIMAConditions.Clean(); + + // + return; + } + + // + structure.Clean(); + poiDetector.AnalyseMarket( + structure, + structureConfig, + barIndex // + ); + // poiDrawer.drawnObjects.Clear(); + // poiDrawer.DrawMarketStructure( + // structure, + // structureDrawConfig // + // ); + + // + // Strategy 1 ... + // has = Strategy1HasSignal( + // iBar, + // iZone, + // iTargets, + // iDir, + // iFIMAConditions, + // structure // + // ); + + // + // Strategy 2 ... + if (!has) + { + // // + // has = Strategy2HasSignal( + // iBar, + // iZone, + // iTargets, + // iDir, + // iFIMAConditions, + // structure // + // ); + } + + // + // Strategy 3 ... + if (!has) + { + // + // has = Strategy3HasSignal( + // iBar, + // iZone, + // iTargets, + // iDir, + // iFIMAConditions, + // structure // + // ); + } + + // + // Strategy 4 ... + has = false; + if (!has) + { + // + has = Strategy4HasSignal( + iBar, + iZone, + iTargets, + iDir, + iFIMAConditions, + structure // + ); + } + + // + has = HasDirection(iDir) && + iZone.IsValid(); + if (has) + { + // + has = false; + iZone.Clean(); + iDir = X_DIRECTION_NONE; + } + + // + if (has) + { + // + isBullish = IsXBullish(iDir); + isBearish = IsXBearish(iDir); + + // + // TODO: Provided SL ... + double _point = GetPoints(iBar.symbol); + double slAddition = 5 * _point; + double atrAddition = GetAverageTrueRange( + iZone.symbol, + iZone.period, + 0 // + ); + double slPrice = + isBullish + ? iZone.lower - slAddition + : iZone.upper + slAddition; + + // + // Prepare Founded Signal ... + + // + // Handle Signal Targets ... + if (ignoreTargets) + { + XClean(iTargets); + } + + // + has = PrepareSignal( + iSignal, + iDir, + iTargets, + 0, // Use Default R2R ... + slPrice, // Provided Price for SL ... + 0 // Specified Risk in Point .... + ); + if (has) + { + // + // Notify On Signal Event ... + NotifySignalEventListeners(iSignal); + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + iZone.Clean(); + iSignal.Clean(); + iFIMAConditions.Clean(); + SpecifiedClean(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; + + // + SpecifiedClean(guards); + + // + result = ArraySize(guards); + + // + return result; + } + + // + // Private ... + private: + // + // Props ... + + // + // Implementing Strategies ... + + /** + * Check Bar Has Signal Based on Strategy 1 ... + * + * @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 ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool Strategy1HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir, + XFIMAConditions &conditions, + XFIMAMarketStructure &_structure // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Testing Porposes ... + result = + result && + fimaHelper.IsBoundaryFakeBreaked( + dir, + bar.Index(), + X_PRICE_CLOSE, + X_PRICE_CLOSE // + ); + + // + // Nearest Noisy ZG Pivot Must has Same Direction + // by Boundary Faked Break ... + result = + result && + HasDirection(dir) && + _structure.zgAnalysis.IsValid() && + _structure.zgAnalysis.HasPivots() && + _structure.zgAnalysis.pivots[0].dir == dir; + + // + // We Have to Detect a Zone which Nearest ZG Pivot Reject or goes inside it ... + + // + int idx = -1; + XOHCL tmpBar; + XPivot pivot; + XPivot pivots[]; + XBoxZone zones[]; + bool has = false; + int zonesCount = 0; + int pivotIndex = -1; + XBoxZone affectedZone; + double bullishScore = 0; + double bearishScore = 0; + int prevPivotIndex = -1; + XBoxZone affectedZones[]; + int affectedZonesCount = 0; + + // + Copy( + _structure.zgAnalysis.pivots, + pivots // + ); + pivot = pivots[0]; + ArrayRemove(pivots, 0, 1); + + // + bool isBullish = IsXBullish(dir); + bool isBearish = IsXBearish(dir); + + // + zonesCount = _structure.CollectZones( + zones, + dir // + ); + result = result && + IsValidSize(zonesCount); + + // + // Noisey ZG Pivot must inside atleast one of Zones ... + + // + // Initial Pivots Bar ... + result = + result && + bar.BarAt(pivot.time, tmpBar); + + // + // Extract Affected Zones ... + if (result) + { + // + affectedZonesCount = ExtractAffectedZones( + tmpBar, + zones, + affectedZones, + dir // + ); + } + + // + // Validate Affected Zones ... + result = + result && + HasChild(affectedZones) && + affectedZonesCount >= 1; + if (result) + { + affectedZone = affectedZones[0]; + } + result = + result && + affectedZone.IsValid() && + (isBullish + ? bar.close > affectedZone.upper + : bar.close < affectedZone.lower); + + // + // There Must another Same Directional ZG Pivot Exists + // which is Affect another Zone ... + idx = GetYoungest(pivots, pivot.type); + result = + result && + IsValidIndex(idx) && + affectedZone.IsValid() && + (isBullish + ? pivots[idx].value < pivot.value + : pivots[idx].value > pivot.value); + if (result) + { + // + pivot.Clean(); + tmpBar.Clean(); + pivot = pivots[idx]; + XClean(affectedZones); + ArrayRemove(pivots, idx, 1); + + // + result = bar.BarAt(pivot.time, tmpBar); + } + + // + // Extract Affected Zones ... + XClean(affectedZones); + affectedZonesCount = 0; + if (result) + { + // + affectedZonesCount = ExtractAffectedZones( + tmpBar, + zones, + affectedZones, + dir // + ); + } + result = + result && + HasChild(affectedZones) && + affectedZonesCount >= 1; + + // + // Handling Scores ... + if (result) + { + // + for (int i = 0; i < ArraySize(_structure.barsAnalysis); i++) + { + // + bullishScore += _structure.barsAnalysis[i].Count(X_DIRECTION_BULLISH); + bearishScore += _structure.barsAnalysis[i].Count(X_DIRECTION_BEARISH); + } + } + result = + isBullish + ? bullishScore > bearishScore + : bearishScore > bullishScore; + + // + // Last Validation is Candlestick Patterns of Bar ... + // XPatternAnalysis barAnalysis; + // result = + // result && + // poiDetector.AnalyseBarPatterns( + // bar, + // barAnalysis, + // structureConfig.barsAnalysisConfig // + // ); + + // + if (!result) + { + // + dir = X_DIRECTION_NONE; + + // + return result; + } + + // + // Drawa ... + if (result) + { + // + // Affected Zone ... + XCBoxObject *iObj; + has = poiDrawer.DrawBox( + affectedZone, + iObj, + true, + affectedZone.type + "_" + ToXString(TimeToSeconds(affectedZone.from)) // + ); + if (has) + { + // + XPOIStyle iStyle; + poiDrawer.GetBoxStyle( + iStyle, + affectedZone.dir // + ); + iStyle.clr = clrYellow; + poiDrawer.ApplyBoxStyle( + iObj, + iStyle // + ); + iStyle.Clean(); + + // + Print("Affected Zone ..."); + } + + // + // Draw Bar Pattern ... + // poiDrawer.DrawPatternAnalysis(barAnalysis, structureDrawConfig.barAnalysisDrawConfig); + } + + // + // Prepare zone ... + if (result) + { + // + zone = affectedZone; + + // + zone.type = name + "_" + ToXString(dir); + + // + double entry = GetEntry(bar.symbol, dir); + double points = GetPoints(bar.symbol); + double risk = MathAbs(entry - (isBullish ? zone.lower : zone.upper)); + double reward = risk * defaultSignalR2R; + + // + // Partially Close on TP 1 ... + double tp1 = isBullish + ? entry + (risk * 1) + : entry - (risk * 1); + XTarget target1; + target1.target = tp1; + target1.doRF = false; + target1.actingDistance = 2; + target1.volumeMultiplier = 0.5; + + // + // TP 3 ... + double tp3 = isBullish + ? entry + (risk * 3) + : entry - (risk * 3); + XTarget target3; + target3.target = tp3; + target3.doRF = true; + target3.actingDistance = 10; + + // + // TP 5 ... + double tp5 = isBullish + ? entry + (risk * 5) + : entry - (risk * 5); + XTarget target5; + target5.target = tp5; + target5.doRF = true; + target5.actingDistance = 10; + + // + AddRef( + target1, + targets // + ); + AddRef( + target3, + targets // + ); + AddRef( + target5, + targets // + ); + + // + result = zone.IsValid(); + } + + // + // Check Result ... + if (result) + { + // + // dir = structure.maCrossDir; + + // + // Handle Targets Detection ... + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + } + + // + pivot.Clean(); + XClean(zones); + tmpBar.Clean(); + XClean(pivots); + affectedZone.Clean(); + XClean(affectedZones); + + // + return result; + } + + /** + * Check Bar Has Signal Based on Strategy 2 ... + * + * @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 ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool Strategy2HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir, + XFIMAConditions &conditions, + XFIMAMarketStructure &_structure // + ) + { + // + bool result = false; + + // + // Prepare ... + XOHCL pBar; + XOHCL p2Bar; + zone.Clean(); + pBar.Clean(); + p2Bar.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid() && + bar.GetPreviousBar(pBar) && + pBar.GetPreviousBar(p2Bar); + if (!result) + { + return result; + } + + // + result = false; + bool isBullish = false; + bool isBearish = false; + ENUM_X_DIRECTION tmpDir; + + // + // Do Signal Detection ... + + // + // Preparing Requirement Conditions ... + // Here we Have to Prepare Some Directional Confirmations Using Indicators ... + // for Validate Signals ... + + // + int verifierBarIndex = pBar.Index(); + + // + bool hasSarSwitch = fimaHelper.HasSARSwitch(tmpDir, verifierBarIndex); + bool isSarSwitchedToBullish = hasSarSwitch && + IsXBullish(tmpDir); + bool isSarSwitchedToBearish = hasSarSwitch && + IsXBearish(tmpDir); + + // + bool hasMACross = fimaHelper.HasMACross( + tmpDir, + verifierBarIndex, + structureConfig.maCrossValidationDiffMultiplier // + ); + bool isCrossedOver = hasMACross && + IsXBullish(tmpDir); + bool isCrossedUnder = hasMACross && + IsXBearish(tmpDir); + + // + bool hasHKSwitch = fimaHelper.HasHKSwitch(tmpDir, verifierBarIndex); + bool isHKSwitchedToBullish = hasHKSwitch && + IsXBullish(tmpDir); + bool isHKSwitchedToBearish = hasHKSwitch && + IsXBearish(tmpDir); + + // + bool isBoundaryFakeBreaked = fimaHelper.IsBoundaryFakeBreaked(tmpDir, verifierBarIndex); + bool isBoundaryFakeBreakedBullish = isBoundaryFakeBreaked && + IsXBullish(tmpDir); + bool isBoundaryFakeBreakedBearish = isBoundaryFakeBreaked && + IsBearish(tmpDir); + + // + bool hasZigZagHigherLow = fimaHelper.HasZigZagHigherLow(bar.Index(), true); + bool hasZigZagLowerHigh = fimaHelper.HasZigZagLowerHigh(bar.Index(), true); + + // + // Summarize Confirmations ... + + // + bool isBullishConfirmed = + (hasZigZagHigherLow && + ( + // + isCrossedOver || + isHKSwitchedToBullish || + isSarSwitchedToBullish || + isBoundaryFakeBreakedBullish + // + )); + + // + bool isBearishConfirmed = + (hasZigZagLowerHigh && + ( + // + isCrossedUnder || + isHKSwitchedToBearish || + isSarSwitchedToBearish || + isBoundaryFakeBreakedBullish + // + )); + + // + // Validation Patterns ... + int directionalPatternsValidations = 3; + + // + // Check Bullish Conditions ... + isBullish = + // + // Confirmations Passed ... + isBullishConfirmed && + // + // Quarters Has Minor Support Zone ... + _structure.barAnalysis.HasMinorSupport() && + // + // Current Bar's Price Placed Propper ... + bar.open > _structure.barAnalysis.minorSupport.upper && + bar.close > _structure.barAnalysis.minorSupport.upper && + // + // Required Number of Pivots Validation Exists ... + (_structure.barsAnalysis[1].Count(X_DIRECTION_BULLISH) >= directionalPatternsValidations) && + // + // Bar or PBar ReTested Quarter Zone ... + (IsTested( + pBar, + _structure.barAnalysis.minorSupport // + ) || + IsTested( + p2Bar, + _structure.barAnalysis.minorSupport // + )) + // + ; + + // + // Check Bearish Conditions ... + isBearish = + // + // Confirmations Passed ... + isBearishConfirmed && + // + // Quarters Has Minor Resistance Zone ... + _structure.barAnalysis.HasMinorResistance() && + // + // Current Bar's Price Placed Propper ... + bar.open < _structure.barAnalysis.minorResistance.lower && + bar.close < _structure.barAnalysis.minorResistance.lower && + // + // Required Number of Pivots Validation Exists ... + (_structure.barsAnalysis[1].Count(X_DIRECTION_BEARISH) >= directionalPatternsValidations) && + // + // Bar or pBar ReTested Quarter Zone ... + (IsTested( + pBar, + _structure.barAnalysis.minorResistance // + ) || + IsTested( + p2Bar, + _structure.barAnalysis.minorResistance // + )) + // + ; + + // + // Summarize Conditions ... + result = + isBullish || + isBearish; + + // + // Assign Direction ... + if (result) + { + // + dir = isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + if (isBullish) + { + zone = _structure.barAnalysis.minorSupport; + } + + // + if (isBearish) + { + zone = _structure.barAnalysis.minorResistance; + } + } + + // + // Validate Result ... + result = + result && + zone.IsValid() && + HasDirection(dir); + // if (result) + // { + // // + // XPOIDrawConfig iConfig = structureDrawConfig + // .barAnalysisDrawConfig + // .quarterMinorsDrawConfig; + // iConfig.zonesWidth = 3; + // iConfig.zonesFill = true; + // iConfig.bullishColor = clrYellow; + // iConfig.bearishColor = clrYellow; + + // // + // if (isBullish) + // { + // // + // poiDrawer.DrawZone( + // _structure.barAnalysis.minorSupport, + // iConfig // + // ); + + // // + // Print("Bullish Condition ..."); + // } + + // // + // if (isBearish) + // { + // // + // poiDrawer.DrawZone( + // _structure.barAnalysis.minorResistance, + // iConfig // + // ); + + // // + // Print("Bearish Condition ..."); + // } + + // // + // Print(ToXString(dir), " Detected ..."); + // } + + // + // Provide Direction and Targets if Required ... + if (result) + { + // + // Handle Targets Detection ... + + // + double spread = GetSpread(zone.symbol); + double entry = GetEntry(zone.symbol, dir); + + // + double risk = isBullish + ? entry - zone.lower + : zone.upper - entry; + double reward1 = entry + (isBullish + ? risk + : (-1 * risk) // + ); + double reward4 = entry + (isBullish + ? 4 * risk + : (-4 * risk) // + ); + double requiredDistance = PriceToPoint(spread * 2, zone.symbol); + + // + XTarget iRFOnEntryOnTP1; + iRFOnEntryOnTP1.target = reward1; + iRFOnEntryOnTP1.tpValue = reward4; + iRFOnEntryOnTP1.doRFOnEntry = true; + iRFOnEntryOnTP1.volumeMultiplier = 0.5; + iRFOnEntryOnTP1.actingDistance = requiredDistance; + + // + AddRef( + iRFOnEntryOnTP1, + targets // + ); + } + + // + // Cleanup Resources ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + } + pBar.Clean(); + p2Bar.Clean(); + + // + return result; + } + + /** + * 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 ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool Strategy3HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir, + XFIMAConditions &conditions, + XFIMAMarketStructure &_structure // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Define Requirements ... + bool isBullish = false; + bool isBearish = false; + + // + XOHCL pBar; + int barIndex = bar.Index(); + int pBarIndex = barIndex + 1; + result = bar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Do Conditions Checking ... + + // + XBoxZone zones[]; + int zonesCount = 0; + ENUM_X_PRICE bullishPriceType = X_PRICE_LOW; + ENUM_X_PRICE bearishPriceType = X_PRICE_HIGH; + + // + isBullish = fimaHelper.IsSwitchedUnderHKBondLower(bullishPriceType, pBarIndex); + + // + isBearish = fimaHelper.IsSwitchedOverHKBondUpper(bearishPriceType, pBarIndex); + + // + result = + isBullish || + isBearish; + + // + // Do Validations ... + if (result) + { + // + // Direction Assignment ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + int lastIDX; + XBoxZone tmpZones[]; + int tmpZonesCount = 0; + int validationCount = 0; + ENUM_X_PRICE priceType = + isBullish + ? bullishPriceType + : bearishPriceType; + + // + // Detect Last Direction Change ... + if (isBullish) + { + result = fimaHelper.FindLastUnderHKBondLower(lastIDX, bullishPriceType, pBarIndex); + } + else + { + result = fimaHelper.FindLastOverHKBondUpper(lastIDX, bearishPriceType, pBarIndex); + } + + // + // Validate Direction Changed ... + if (result) + { + // + validationCount = lastIDX - pBarIndex; + result = validationCount >= 10; + } + + // + // Collect Zones ... + if (result) + { + // + // Support and Resistances ... + tmpZonesCount = poiDetector.CollectZones( + pBar, + tmpZones, + 5, + 14, // Zones Validation Length ... + 0, // Required Count ... + validationCount // Loopback ... + ); + if (IsValidSize(tmpZonesCount)) + { + // + Copy( + tmpZones, + zones, + false // ignore Clean ... + ); + } + + // + // OB ... + tmpZonesCount = poiDetector.CollectOBs( + pBar, + tmpZones, + 5, // Zones Loopback ... + 0, // Required Count ... + validationCount // Loopback ... + ); + if (IsValidSize(tmpZonesCount)) + { + // + Copy( + tmpZones, + zones, + false // ignore Clean ... + ); + } + + // + // FVG ... + tmpZonesCount = poiDetector.CollectFVGs( + pBar, + tmpZones, + 5, // Zones Loopback ... + 0, // Required Count ... + validationCount // Loopback ... + ); + if (IsValidSize(tmpZonesCount)) + { + // + Copy( + tmpZones, + zones, + false // ignore Clean ... + ); + } + + // + // Filter Zones Based on pBar ... + zonesCount = poiDetector.FilterZones( + pBar, + zones, + dir, + priceType, + dir // + ); + + // + // Extract Affected Zones ... + XClean(tmpZones); + tmpZonesCount = ExtractAffectedZones( + pBar, + zones, + tmpZones, + dir // + ); + Copy(tmpZones, zones); + zonesCount = ArraySize(zones); + + // + // Update Zones Time ... + UpdateToTime(zones); + } + + // + // Draw Zones ... + result = IsValidSize(zonesCount); + if (result) + { + // + for (int i = 0; i < zonesCount; i++) + { + poiDrawer.DrawZone(zones[i], structureDrawConfig.drawConfig); + } + } + + // + XClean(tmpZones); + } + + // + // Prepare Zone ... + if (result) + { + // + // Zone Detection ... + zone.Clean(); + if (isBullish) + { + // + int idx = GetLowest(zones); + if (IsValidIndex(idx)) + { + zone = zones[idx]; + } + } + else + { + // + int idx = GetHighest(zones); + if (IsValidIndex(idx)) + { + zone = zones[idx]; + } + } + + // zone.dir = dir; + // zone.type = name; + // zone.to = bar.time; + // zone.at = pBar.time; + // zone.from = pBar.time; + // zone.symbol = bar.symbol; + // zone.period = bar.period; + // zone.lower = MathMin(pBar.low, bar.low); + // zone.upper = MathMax(pBar.high, bar.high); + + // + result = zone.IsValid(); + } + + // + // Prepare Targets ... + if (result) + { + // + // Target Handling ... + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + XClean(zones); + + // + return result; + } + + /** + * Check Bar Has Signal Based on Strategy 4 ... + * + * @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 ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool Strategy4HasSignal( + XOHCL &bar, + XBoxZone &zone, + XTarget &targets[], + ENUM_X_DIRECTION &dir, + XFIMAConditions &conditions, + XFIMAMarketStructure &_structure // + ) + { + // + bool result = false; + + // + // Prepare ... + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Define Requirements ... + bool isBullish = false; + bool isBearish = false; + + // + XOHCL pBar; + int barIndex = bar.Index(); + int pBarIndex = barIndex + 1; + result = bar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Do Conditions Checking ... + + // + // Reading HK Bond ... + double hkBondUpper = fimaHelper.GetHKBondUpper(pBarIndex); + double hkBondLower = fimaHelper.GetHKBondLower(pBarIndex); + bool hasHKBoundary = + NotEmptyZero(hkBondUpper) && + NotEmptyZero(hkBondLower); + + // + // Pullback Detection ... + bool isPullback = poiDetector.IsPullbackPattern( + pBar, + zone, + dir, + 2, + false // + ); + + // + isBullish = + isPullback && + hasHKBoundary && + IsXBullish(dir) && + zone.lower > hkBondLower; + + // + isBearish = + isPullback && + hasHKBoundary && + IsXBearish(dir) && + zone.upper < hkBondUpper; + + // + result = + isBullish || + isBearish; + + // + // Do Validations ... + if (result) + { + // + // Direction Assignment ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // TEMP ... + poiDrawer.DrawZone( + zone, + structureDrawConfig.drawConfig // + ); + } + + // + // Prepare Decision Zone ... + if (result) + { + // + // Zone Detection ... + zone.Clean(); + + // + // zone.dir = dir; + // zone.type = name; + // zone.to = bar.time; + // zone.at = pBar.time; + // zone.from = pBar.time; + // zone.symbol = bar.symbol; + // zone.period = bar.period; + // zone.lower = MathMin(pBar.low, bar.low); + // zone.upper = MathMax(pBar.high, bar.high); + + // + result = zone.IsValid(); + } + + // + // Prepare Targets ... + if (result) + { + // + // Target Handling ... + } + + // + // Cleanup ... + if (!result) + { + // + zone.Clean(); + XClean(targets); + dir = X_DIRECTION_NONE; + } + pBar.Clean(); + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.xfima.helper.mq5 b/Helpers/x-saherelm.xfima.helper.mq5 index a6155eec..26471f91 100644 --- a/Helpers/x-saherelm.xfima.helper.mq5 +++ b/Helpers/x-saherelm.xfima.helper.mq5 @@ -1129,91 +1129,6 @@ class XCXFIMAHelper : public XCBaseHelper return result; } - /** - * Check Specified Bar has SAR Switch or not ... - * - * @param dir: reference for holds cross Direction ... - * @param barIndex: int, Specified Bar Index ... - * - * @return ( bool ) - */ - bool HasSARSwitch( - ENUM_X_DIRECTION &dir, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - // Prepare ... - dir = X_DIRECTION_NONE; - - // - // Normalize ... - barIndex = NormalizeInt(barIndex, 0); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - double sars[]; - int count = CopySarState(barIndex, 2, sars); - - // - bool isBullish = false; - bool isBearish = false; - - // - // Validate Readed Values ... - result = IsValidSize(count) && count >= 2; - if (result) - { - // - // Detect Direction Change ... - - // - isBullish = - sars[0] >= 1 && - sars[1] <= -1; - - // - isBearish = - sars[0] <= -1 && - sars[1] >= 1; - - // - result = - isBullish || - isBearish; - } - - // - if (result) - { - // - // Setting Direction ... - dir = - isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - } - - // - // Cleanup Resources ... - XClean(sars); - - // - return result; - } - /** * Check Specified Bar Price is In Boundary or not ... * @@ -1976,162 +1891,6 @@ class XCXFIMAHelper : public XCBaseHelper return result; } - /** - * Check Peak Happens over Last ... - * - * @param barIndex: int, Specified Bar Index ... - * - * @return ( bool ) - */ - bool IsPeakOverLast(int barIndex = 0) - { - // - bool result = false; - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - // Reading Values ... - - // - double iPeak = GetPeak(barIndex); - double pPeak = GetPeak(barIndex + 1); - - // - result = NotEmptyZero(iPeak) && - iPeak > pPeak; - - // - return result; - } - - /** - * Check Vale Happens over Last ... - * - * @param barIndex: int, Specified Bar Index ... - * - * @return ( bool ) - */ - bool IsValeOverLast(int barIndex = 0) - { - // - bool result = false; - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - // Reading Values ... - - // - double iVale = GetVale(barIndex); - double pVale = GetVale(barIndex + 1); - - // - result = NotEmptyZero(iVale) && - iVale > pVale; - - // - return result; - } - - /** - * Check Peak Happens under Last ... - * - * @param barIndex: int, Specified Bar Index ... - * - * @return ( bool ) - */ - bool IsPeakUnderLast(int barIndex = 0) - { - // - bool result = false; - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - // Reading Values ... - - // - double iPeak = GetPeak(barIndex); - double pPeak = GetPeak(barIndex + 1); - - // - result = NotEmptyZero(iPeak) && - iPeak < pPeak; - - // - return result; - } - - /** - * Check Vale Happens under Last ... - * - * @param barIndex: int, Specified Bar Index ... - * - * @return ( bool ) - */ - bool IsValeUnderLast(int barIndex = 0) - { - // - bool result = false; - - // - // Normalize ... - barIndex = NormalizeBarIndex(barIndex); - - // - // Validate ... - result = IsValid(); - if (!result) - { - return result; - } - - // - // Reading Values ... - - // - double iVale = GetVale(barIndex); - double pVale = GetVale(barIndex + 1); - - // - result = NotEmptyZero(iVale) && - iVale < pVale; - - // - return result; - } - /** * Check Fibo Section is Changed or not ... * @@ -2759,6 +2518,641 @@ class XCXFIMAHelper : public XCBaseHelper return result; } + // + // SAR ... + + /** + * Check Specified Bar has SAR Switch or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool HasSARSwitch( + ENUM_X_DIRECTION &dir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double sars[]; + int count = CopySarState(barIndex, 2, sars); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + isBullish = + sars[0] >= 1 && + sars[1] <= -1; + + // + isBearish = + sars[0] <= -1 && + sars[1] >= 1; + + // + result = + isBullish || + isBearish; + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(sars); + + // + return result; + } + + bool IsSarBullish(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double state = GetSarState(barIndex); + result = state >= 1; + + // + return result; + } + + bool IsSarBearish(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + double state = GetSarState(barIndex); + result = state <= -1; + + // + return result; + } + + // + // PV ... + + /** + * Check Peak Happens over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsPeakOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Reading Values ... + + // + double iPeak = GetPeak(barIndex); + double pPeak = GetPeak(barIndex + 1); + + // + result = NotEmptyZero(iPeak) && + iPeak > pPeak; + + // + return result; + } + + /** + * Check Vale Happens over Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsValeOverLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Reading Values ... + + // + double iVale = GetVale(barIndex); + double pVale = GetVale(barIndex + 1); + + // + result = NotEmptyZero(iVale) && + iVale > pVale; + + // + return result; + } + + /** + * Check Peak Happens under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsPeakUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Reading Values ... + + // + double iPeak = GetPeak(barIndex); + double pPeak = GetPeak(barIndex + 1); + + // + result = NotEmptyZero(iPeak) && + iPeak < pPeak; + + // + return result; + } + + /** + * Check Vale Happens under Last ... + * + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool IsValeUnderLast(int barIndex = 0) + { + // + bool result = false; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Reading Values ... + + // + double iVale = GetVale(barIndex); + double pVale = GetVale(barIndex + 1); + + // + result = NotEmptyZero(iVale) && + iVale < pVale; + + // + return result; + } + + /** + * Detect Last Peak Change ... + * + * @param index: int, reference to hold change index ... + * @param barIndex: int, Specified Bar Index ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( bool ) + */ + bool FindLastPeakOverLast( + int &index, + int barIndex = 0, + int loopback = 500 // + ) + { + // + bool result = false; + + // + // Prepare ... + index = -1; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Loop ... + int idx = barIndex; + while (idx < barIndex + loopback) + { + // + idx++; + result = IsPeakOverLast(idx); + if (result) + { + // + index = idx; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + /** + * Detect Last Peak Change ... + * + * @param index: int, reference to hold change index ... + * @param barIndex: int, Specified Bar Index ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( bool ) + */ + bool FindLastPeakUnderLast( + int &index, + int barIndex = 0, + int loopback = 500 // + ) + { + // + bool result = false; + + // + // Prepare ... + index = -1; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Loop ... + int idx = barIndex; + while (idx < barIndex + loopback) + { + // + idx++; + result = IsPeakUnderLast(idx); + if (result) + { + // + index = idx; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + /** + * Detect Last Vale Change ... + * + * @param index: int, reference to hold change index ... + * @param barIndex: int, Specified Bar Index ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( bool ) + */ + bool FindLastValeOverLast( + int &index, + int barIndex = 0, + int loopback = 500 // + ) + { + // + bool result = false; + + // + // Prepare ... + index = -1; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Loop ... + int idx = barIndex; + while (idx < barIndex + loopback) + { + // + idx++; + result = IsValeOverLast(idx); + if (result) + { + // + index = idx; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + /** + * Detect Last Vale Change ... + * + * @param index: int, reference to hold change index ... + * @param barIndex: int, Specified Bar Index ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( bool ) + */ + bool FindLastValeUnderLast( + int &index, + int barIndex = 0, + int loopback = 500 // + ) + { + // + bool result = false; + + // + // Prepare ... + index = -1; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Loop ... + int idx = barIndex; + while (idx < barIndex + loopback) + { + // + idx++; + result = IsValeUnderLast(idx); + if (result) + { + // + index = idx; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + /** + * Count Same Peaks ... + * + * @param barIndex: int, Specified Bar Index ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( int ) + */ + int CountSamePeaks( + int barIndex = 0, + int loopback = 500 // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + double iPeak = EMPTY_VALUE; + double peak = GetPeak(barIndex); + int idx = barIndex; + while (idx < barIndex + loopback) + { + // + idx++; + iPeak = GetPeak(idx); + has = peak == iPeak; + if (has) + { + result++; + } + if (!has) + { + break; + } + } + + // + return result; + } + + /** + * Count Same Vales ... + * + * @param barIndex: int, Specified Bar Index ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( int ) + */ + int CountSameVales( + int barIndex = 0, + int loopback = 500 // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid(); + if (!has) + { + return result; + } + + // + double iVale = EMPTY_VALUE; + double vale = GetVale(barIndex); + int idx = barIndex; + while (idx < barIndex + loopback) + { + // + idx++; + iVale = GetVale(idx); + has = vale == iVale; + if (has) + { + result++; + } + if (!has) + { + break; + } + } + + // + return result; + } + // // HK ... @@ -4021,6 +4415,278 @@ class XCXFIMAHelper : public XCBaseHelper return result; } + /** + * Count Over HK Bond Bars ... + * + * @param barIndex: int, Specified Bar Index ... + * @param priceType: ENUM_X_PRICE, Specified Price Type ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( int ) + */ + int CountOverHKBondLower( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int loopback = 500 // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid() && + IsXValid(priceType); + if (!has) + { + return result; + } + + // + XOHCL iBar; + int idx = barIndex; + double iValue = EMPTY_VALUE; + double iPrice = EMPTY_VALUE; + while (idx < barIndex + loopback) + { + // + idx++; + iBar.Clean(); + has = iBar.Init(mSymbol, mPeriod, idx); + if (!has) + { + break; + } + + // + iValue = GetHKBondLower(idx); + iPrice = iBar.GetPrice(priceType); + + // + has = iPrice > iValue; + if (has) + { + result++; + } + if (!has) + { + break; + } + } + + // + return result; + } + + /** + * Count Under HK Bond Bars ... + * + * @param barIndex: int, Specified Bar Index ... + * @param priceType: ENUM_X_PRICE, Specified Price Type ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( int ) + */ + int CountUnderHKBondLower( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int loopback = 500 // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid() && + IsXValid(priceType); + if (!has) + { + return result; + } + + // + XOHCL iBar; + int idx = barIndex; + double iValue = EMPTY_VALUE; + double iPrice = EMPTY_VALUE; + while (idx < barIndex + loopback) + { + // + idx++; + iBar.Clean(); + has = iBar.Init(mSymbol, mPeriod, idx); + if (!has) + { + break; + } + + // + iValue = GetHKBondLower(idx); + iPrice = iBar.GetPrice(priceType); + + // + has = iPrice < iValue; + if (has) + { + result++; + } + if (!has) + { + break; + } + } + + // + return result; + } + + /** + * Count Over HK Bond Bars ... + * + * @param barIndex: int, Specified Bar Index ... + * @param priceType: ENUM_X_PRICE, Specified Price Type ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( int ) + */ + int CountOverHKBondUpper( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int loopback = 500 // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid() && + IsXValid(priceType); + if (!has) + { + return result; + } + + // + XOHCL iBar; + int idx = barIndex; + double iValue = EMPTY_VALUE; + double iPrice = EMPTY_VALUE; + while (idx < barIndex + loopback) + { + // + idx++; + iBar.Clean(); + has = iBar.Init(mSymbol, mPeriod, idx); + if (!has) + { + break; + } + + // + iValue = GetHKBondUpper(idx); + iPrice = iBar.GetPrice(priceType); + + // + has = iPrice > iValue; + if (has) + { + result++; + } + if (!has) + { + break; + } + } + + // + return result; + } + + /** + * Count Under HK Bond Bars ... + * + * @param barIndex: int, Specified Bar Index ... + * @param priceType: ENUM_X_PRICE, Specified Price Type ... + * @param loopback: int, Max Allowed Loopback Length ... + * + * @return ( int ) + */ + int CountUnderHKBondUpper( + int barIndex = 0, + ENUM_X_PRICE priceType = X_PRICE_CLOSE, + int loopback = 500 // + ) + { + // + int result = 0; + + // + // Normalize ... + loopback = NormalizeInt(loopback, 50); + barIndex = NormalizeBarIndex(barIndex); + + // + // Validate ... + bool has = IsValid() && + IsXValid(priceType); + if (!has) + { + return result; + } + + // + XOHCL iBar; + int idx = barIndex; + double iValue = EMPTY_VALUE; + double iPrice = EMPTY_VALUE; + while (idx < barIndex + loopback) + { + // + idx++; + iBar.Clean(); + has = iBar.Init(mSymbol, mPeriod, idx); + if (!has) + { + break; + } + + // + iValue = GetHKBondUpper(idx); + iPrice = iBar.GetPrice(priceType); + + // + has = iPrice < iValue; + if (has) + { + result++; + } + if (!has) + { + break; + } + } + + // + return result; + } + // // ZigZag Pivots With Liquidity ... diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index b29a2e53..70390086 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -252,6 +252,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller public: // // Props ... + XFIMAConditions conditions; // XFIMA Conditions ... XFIMAMarketStructure structure; // XFIMA Market Structure ... // @@ -331,7 +332,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller string iName = NULL; bool isBullish = false; bool isBearish = false; - XFIMAConditions iFIMAConditions; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; // @@ -348,92 +348,14 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller return; } - // - // Retrieve Conditions ... - has = fimaHelper.GetConditions( - iFIMAConditions, - barIndex, - 10 // Loopback ... - ); - if (!has) - { - // - iBar.Clean(); - iFIMAConditions.Clean(); - - // - return; - } - - // - structure.Clean(); - poiDetector.AnalyseMarket( - structure, - structureConfig, - barIndex // - ); - // poiDrawer.drawnObjects.Clear(); - // poiDrawer.DrawMarketStructure( - // structure, - // structureDrawConfig // - // ); - // // Strategy 1 ... - // has = Strategy1HasSignal( - // iBar, - // iZone, - // iTargets, - // iDir, - // iFIMAConditions, - // structure // - // ); - - // - // Strategy 2 ... - if (!has) - { - // // - // has = Strategy2HasSignal( - // iBar, - // iZone, - // iTargets, - // iDir, - // iFIMAConditions, - // structure // - // ); - } - - // - // Strategy 3 ... - if (!has) - { - // - // has = Strategy3HasSignal( - // iBar, - // iZone, - // iTargets, - // iDir, - // iFIMAConditions, - // structure // - // ); - } - - // - // Strategy 4 ... - has = false; - if (!has) - { - // - has = Strategy4HasSignal( - iBar, - iZone, - iTargets, - iDir, - iFIMAConditions, - structure // - ); - } + has = Strategy1HasSignal( + iBar, + iZone, + iTargets, + iDir // + ); // has = HasDirection(iDir) && @@ -441,9 +363,12 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller if (has) { // - has = false; - iZone.Clean(); - iDir = X_DIRECTION_NONE; + // Draw Zone ... + + // + // has = false; + // iZone.Clean(); + // iDir = X_DIRECTION_NONE; } // @@ -499,7 +424,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller iBar.Clean(); iZone.Clean(); iSignal.Clean(); - iFIMAConditions.Clean(); SpecifiedClean(iTargets); } @@ -556,9 +480,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller XOHCL &bar, XBoxZone &zone, XTarget &targets[], - ENUM_X_DIRECTION &dir, - XFIMAConditions &conditions, - XFIMAMarketStructure &_structure // + ENUM_X_DIRECTION &dir // ) { // @@ -579,296 +501,173 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller } // - // Testing Porposes ... - result = - result && - fimaHelper.IsBoundaryFakeBreaked( - dir, - bar.Index(), - X_PRICE_CLOSE, - X_PRICE_CLOSE // - ); + // Define Requirements ... // - // Nearest Noisy ZG Pivot Must has Same Direction - // by Boundary Faked Break ... - result = - result && - HasDirection(dir) && - _structure.zgAnalysis.IsValid() && - _structure.zgAnalysis.HasPivots() && - _structure.zgAnalysis.pivots[0].dir == dir; + XOHCL pBar; + XOHCL p2Bar; + bool isBullish = false; + bool isBearish = false; // - // We Have to Detect a Zone which Nearest ZG Pivot Reject or goes inside it ... - - // - int idx = -1; - XOHCL tmpBar; - XPivot pivot; - XPivot pivots[]; - XBoxZone zones[]; - bool has = false; - int zonesCount = 0; - int pivotIndex = -1; - XBoxZone affectedZone; - double bullishScore = 0; - double bearishScore = 0; - int prevPivotIndex = -1; - XBoxZone affectedZones[]; - int affectedZonesCount = 0; - - // - Copy( - _structure.zgAnalysis.pivots, - pivots // - ); - pivot = pivots[0]; - ArrayRemove(pivots, 0, 1); - - // - bool isBullish = IsXBullish(dir); - bool isBearish = IsXBearish(dir); - - // - zonesCount = _structure.CollectZones( - zones, - dir // - ); + // Read PBar ... + result = bar.GetPreviousBar(pBar); result = result && - IsValidSize(zonesCount); - - // - // Noisey ZG Pivot must inside atleast one of Zones ... - - // - // Initial Pivots Bar ... - result = - result && - bar.BarAt(pivot.time, tmpBar); - - // - // Extract Affected Zones ... - if (result) - { - // - affectedZonesCount = ExtractAffectedZones( - tmpBar, - zones, - affectedZones, - dir // - ); - } - - // - // Validate Affected Zones ... - result = - result && - HasChild(affectedZones) && - affectedZonesCount >= 1; - if (result) - { - affectedZone = affectedZones[0]; - } - result = - result && - affectedZone.IsValid() && - (isBullish - ? bar.close > affectedZone.upper - : bar.close < affectedZone.lower); - - // - // There Must another Same Directional ZG Pivot Exists - // which is Affect another Zone ... - idx = GetYoungest(pivots, pivot.type); - result = - result && - IsValidIndex(idx) && - affectedZone.IsValid() && - (isBullish - ? pivots[idx].value < pivot.value - : pivots[idx].value > pivot.value); - if (result) - { - // - pivot.Clean(); - tmpBar.Clean(); - pivot = pivots[idx]; - XClean(affectedZones); - ArrayRemove(pivots, idx, 1); - - // - result = bar.BarAt(pivot.time, tmpBar); - } - - // - // Extract Affected Zones ... - XClean(affectedZones); - affectedZonesCount = 0; - if (result) - { - // - affectedZonesCount = ExtractAffectedZones( - tmpBar, - zones, - affectedZones, - dir // - ); - } - result = - result && - HasChild(affectedZones) && - affectedZonesCount >= 1; - - // - // Handling Scores ... - if (result) - { - // - for (int i = 0; i < ArraySize(_structure.barsAnalysis); i++) - { - // - bullishScore += _structure.barsAnalysis[i].Count(X_DIRECTION_BULLISH); - bearishScore += _structure.barsAnalysis[i].Count(X_DIRECTION_BEARISH); - } - } - result = - isBullish - ? bullishScore > bearishScore - : bearishScore > bullishScore; - - // - // Last Validation is Candlestick Patterns of Bar ... - // XPatternAnalysis barAnalysis; - // result = - // result && - // poiDetector.AnalyseBarPatterns( - // bar, - // barAnalysis, - // structureConfig.barsAnalysisConfig // - // ); - - // + pBar.GetPreviousBar(p2Bar); if (!result) { // - dir = X_DIRECTION_NONE; + pBar.Clean(); + p2Bar.Clean(); // return result; } // - // Drawa ... + // Reading pBar Patterns ... + XPatternAnalysis pBarAnalysis; + poiDetector.AnalyseBarPatterns( + pBar, + pBarAnalysis, + structureConfig.barsAnalysisConfig // + ); + + // + // Check Bar Patterns ... + bool isPBarHasBullishPatterns = + (bar.close > pBar.low || + bar.open > pBar.low) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isPBarHasBearishPatterns = + (bar.close < pBar.high || + bar.open < pBar.high) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + double pPeak = fimaHelper.GetPeak(pBar.Index()); + double pVale = fimaHelper.GetVale(pBar.Index()); + bool isPPeakOverLast = fimaHelper.IsPeakOverLast(pBar.Index()); + bool isPValeUnderLast = fimaHelper.IsValeUnderLast(pBar.Index()); + bool isP2PeakOverLast = fimaHelper.IsPeakOverLast(p2Bar.Index()); + bool isP2ValeUnderLast = fimaHelper.IsValeUnderLast(p2Bar.Index()); + bool isPeakOverLast = isPPeakOverLast || + isP2PeakOverLast; + bool isValeUnderLast = isPValeUnderLast || + isP2ValeUnderLast; + + // + // 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); + + // + // Do ... + + // + isBullish = + // + isFastOverLast && + isValeUnderLast && + isPBarCloseOverFast && + isP2BarBullishPinned && + isPBarHasBullishPatterns + // + ; + + // + isBearish = + // + isPeakOverLast && + isFastUnderLast && + isPBarCloseUnderFast && + isP2BarBearishPinned && + isPBarHasBearishPatterns + // + ; + + // + // Validate ... + result = isBullish || + isBearish; if (result) { // - // Affected Zone ... - XCBoxObject *iObj; - has = poiDrawer.DrawBox( - affectedZone, - iObj, - true, - affectedZone.type + "_" + ToXString(TimeToSeconds(affectedZone.from)) // - ); - if (has) - { - // - XPOIStyle iStyle; - poiDrawer.GetBoxStyle( - iStyle, - affectedZone.dir // - ); - iStyle.clr = clrYellow; - poiDrawer.ApplyBoxStyle( - iObj, - iStyle // - ); - iStyle.Clean(); - - // - Print("Affected Zone ..."); - } + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; // - // Draw Bar Pattern ... - // poiDrawer.DrawPatternAnalysis(barAnalysis, structureDrawConfig.barAnalysisDrawConfig); + result = HasDirection(dir); } // - // Prepare zone ... + // Prepare Zone ... if (result) { // - zone = affectedZone; - - // - zone.type = name + "_" + ToXString(dir); - - // - double entry = GetEntry(bar.symbol, dir); - double points = GetPoints(bar.symbol); - double risk = MathAbs(entry - (isBullish ? zone.lower : zone.upper)); - double reward = risk * defaultSignalR2R; - - // - // Partially Close on TP 1 ... - double tp1 = isBullish - ? entry + (risk * 1) - : entry - (risk * 1); - XTarget target1; - target1.target = tp1; - target1.doRF = false; - target1.actingDistance = 2; - target1.volumeMultiplier = 0.5; - - // - // TP 3 ... - double tp3 = isBullish - ? entry + (risk * 3) - : entry - (risk * 3); - XTarget target3; - target3.target = tp3; - target3.doRF = true; - target3.actingDistance = 10; - - // - // TP 5 ... - double tp5 = isBullish - ? entry + (risk * 5) - : entry - (risk * 5); - XTarget target5; - target5.target = tp5; - target5.doRF = true; - target5.actingDistance = 10; - - // - AddRef( - target1, - targets // - ); - AddRef( - target3, - targets // - ); - AddRef( - target5, - targets // + zone.Clean(); + result = ToBox( + p2Bar, + zone, + dir, + X_BAR_PATTERN_PINNED // ); + // + if (result) + { + // + zone.to = bar.time; + + // + poiDrawer.DrawZone( + zone, + structureDrawConfig.drawConfig // + ); + } + // result = zone.IsValid(); } // - // Check Result ... + // Prepare Targets ... if (result) { - // - // dir = structure.maCrossDir; - - // - // Handle Targets Detection ... } // @@ -878,22 +677,17 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // zone.Clean(); XClean(targets); + dir = X_DIRECTION_NONE; } - - // - pivot.Clean(); - XClean(zones); - tmpBar.Clean(); - XClean(pivots); - affectedZone.Clean(); - XClean(affectedZones); + pBar.Clean(); + p2Bar.Clean(); // return result; } /** - * Check Bar Has Signal Based on Strategy 2 ... + * Check Bar Has Signal Based on Strategy 1 ... * * @param bar: XOHCL, reference to Bar ... * @param zone: XBoxZone, reference to holds affected zone ... @@ -908,327 +702,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller XOHCL &bar, XBoxZone &zone, XTarget &targets[], - ENUM_X_DIRECTION &dir, - XFIMAConditions &conditions, - XFIMAMarketStructure &_structure // - ) - { - // - bool result = false; - - // - // Prepare ... - XOHCL pBar; - XOHCL p2Bar; - zone.Clean(); - pBar.Clean(); - p2Bar.Clean(); - XClean(targets); - dir = X_DIRECTION_NONE; - - // - // Validate ... - result = bar.IsValid() && - bar.GetPreviousBar(pBar) && - pBar.GetPreviousBar(p2Bar); - if (!result) - { - return result; - } - - // - result = false; - bool isBullish = false; - bool isBearish = false; - ENUM_X_DIRECTION tmpDir; - - // - // Do Signal Detection ... - - // - // Preparing Requirement Conditions ... - // Here we Have to Prepare Some Directional Confirmations Using Indicators ... - // for Validate Signals ... - - // - int verifierBarIndex = pBar.Index(); - - // - bool hasSarSwitch = fimaHelper.HasSARSwitch(tmpDir, verifierBarIndex); - bool isSarSwitchedToBullish = hasSarSwitch && - IsXBullish(tmpDir); - bool isSarSwitchedToBearish = hasSarSwitch && - IsXBearish(tmpDir); - - // - bool hasMACross = fimaHelper.HasMACross( - tmpDir, - verifierBarIndex, - structureConfig.maCrossValidationDiffMultiplier // - ); - bool isCrossedOver = hasMACross && - IsXBullish(tmpDir); - bool isCrossedUnder = hasMACross && - IsXBearish(tmpDir); - - // - bool hasHKSwitch = fimaHelper.HasHKSwitch(tmpDir, verifierBarIndex); - bool isHKSwitchedToBullish = hasHKSwitch && - IsXBullish(tmpDir); - bool isHKSwitchedToBearish = hasHKSwitch && - IsXBearish(tmpDir); - - // - bool isBoundaryFakeBreaked = fimaHelper.IsBoundaryFakeBreaked(tmpDir, verifierBarIndex); - bool isBoundaryFakeBreakedBullish = isBoundaryFakeBreaked && - IsXBullish(tmpDir); - bool isBoundaryFakeBreakedBearish = isBoundaryFakeBreaked && - IsBearish(tmpDir); - - // - bool hasZigZagHigherLow = fimaHelper.HasZigZagHigherLow(bar.Index(), true); - bool hasZigZagLowerHigh = fimaHelper.HasZigZagLowerHigh(bar.Index(), true); - - // - // Summarize Confirmations ... - - // - bool isBullishConfirmed = - (hasZigZagHigherLow && - ( - // - isCrossedOver || - isHKSwitchedToBullish || - isSarSwitchedToBullish || - isBoundaryFakeBreakedBullish - // - )); - - // - bool isBearishConfirmed = - (hasZigZagLowerHigh && - ( - // - isCrossedUnder || - isHKSwitchedToBearish || - isSarSwitchedToBearish || - isBoundaryFakeBreakedBullish - // - )); - - // - // Validation Patterns ... - int directionalPatternsValidations = 3; - - // - // Check Bullish Conditions ... - isBullish = - // - // Confirmations Passed ... - isBullishConfirmed && - // - // Quarters Has Minor Support Zone ... - _structure.barAnalysis.HasMinorSupport() && - // - // Current Bar's Price Placed Propper ... - bar.open > _structure.barAnalysis.minorSupport.upper && - bar.close > _structure.barAnalysis.minorSupport.upper && - // - // Required Number of Pivots Validation Exists ... - (_structure.barsAnalysis[1].Count(X_DIRECTION_BULLISH) >= directionalPatternsValidations) && - // - // Bar or PBar ReTested Quarter Zone ... - (IsTested( - pBar, - _structure.barAnalysis.minorSupport // - ) || - IsTested( - p2Bar, - _structure.barAnalysis.minorSupport // - )) - // - ; - - // - // Check Bearish Conditions ... - isBearish = - // - // Confirmations Passed ... - isBearishConfirmed && - // - // Quarters Has Minor Resistance Zone ... - _structure.barAnalysis.HasMinorResistance() && - // - // Current Bar's Price Placed Propper ... - bar.open < _structure.barAnalysis.minorResistance.lower && - bar.close < _structure.barAnalysis.minorResistance.lower && - // - // Required Number of Pivots Validation Exists ... - (_structure.barsAnalysis[1].Count(X_DIRECTION_BEARISH) >= directionalPatternsValidations) && - // - // Bar or pBar ReTested Quarter Zone ... - (IsTested( - pBar, - _structure.barAnalysis.minorResistance // - ) || - IsTested( - p2Bar, - _structure.barAnalysis.minorResistance // - )) - // - ; - - // - // Summarize Conditions ... - result = - isBullish || - isBearish; - - // - // Assign Direction ... - if (result) - { - // - dir = isBullish - ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - - // - if (isBullish) - { - zone = _structure.barAnalysis.minorSupport; - } - - // - if (isBearish) - { - zone = _structure.barAnalysis.minorResistance; - } - } - - // - // Validate Result ... - result = - result && - zone.IsValid() && - HasDirection(dir); - // if (result) - // { - // // - // XPOIDrawConfig iConfig = structureDrawConfig - // .barAnalysisDrawConfig - // .quarterMinorsDrawConfig; - // iConfig.zonesWidth = 3; - // iConfig.zonesFill = true; - // iConfig.bullishColor = clrYellow; - // iConfig.bearishColor = clrYellow; - - // // - // if (isBullish) - // { - // // - // poiDrawer.DrawZone( - // _structure.barAnalysis.minorSupport, - // iConfig // - // ); - - // // - // Print("Bullish Condition ..."); - // } - - // // - // if (isBearish) - // { - // // - // poiDrawer.DrawZone( - // _structure.barAnalysis.minorResistance, - // iConfig // - // ); - - // // - // Print("Bearish Condition ..."); - // } - - // // - // Print(ToXString(dir), " Detected ..."); - // } - - // - // Provide Direction and Targets if Required ... - if (result) - { - // - // Handle Targets Detection ... - - // - double spread = GetSpread(zone.symbol); - double entry = GetEntry(zone.symbol, dir); - - // - double risk = isBullish - ? entry - zone.lower - : zone.upper - entry; - double reward1 = entry + (isBullish - ? risk - : (-1 * risk) // - ); - double reward4 = entry + (isBullish - ? 4 * risk - : (-4 * risk) // - ); - double requiredDistance = PriceToPoint(spread * 2, zone.symbol); - - // - XTarget iRFOnEntryOnTP1; - iRFOnEntryOnTP1.target = reward1; - iRFOnEntryOnTP1.tpValue = reward4; - iRFOnEntryOnTP1.doRFOnEntry = true; - iRFOnEntryOnTP1.volumeMultiplier = 0.5; - iRFOnEntryOnTP1.actingDistance = requiredDistance; - - // - AddRef( - iRFOnEntryOnTP1, - targets // - ); - } - - // - // Cleanup Resources ... - if (!result) - { - // - zone.Clean(); - XClean(targets); - } - pBar.Clean(); - p2Bar.Clean(); - - // - return result; - } - - /** - * 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 ... - * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... - * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... - * - * @return ( bool ) - */ - bool Strategy3HasSignal( - XOHCL &bar, - XBoxZone &zone, - XTarget &targets[], - ENUM_X_DIRECTION &dir, - XFIMAConditions &conditions, - XFIMAMarketStructure &_structure // + ENUM_X_DIRECTION &dir // ) { // @@ -1250,183 +724,215 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // // Define Requirements ... + + // + XOHCL pBar; bool isBullish = false; bool isBearish = false; // - XOHCL pBar; - int barIndex = bar.Index(); - int pBarIndex = barIndex + 1; + // Read PBar ... result = bar.GetPreviousBar(pBar); if (!result) { + // + pBar.Clean(); return result; } // - // Do Conditions Checking ... + // Reading Conditions ... + int pullBackStartBar = -1; + bool isPullBack = result && + poiDetector.IsPullbackPattern( + pBar, + zone, + dir, + 2, + false // Force Break ... + ); + bool isPullbackBullish = isPullBack && + IsXBullish(dir); + bool isPullbackBearish = isPullBack && + IsXBearish(dir); + if (isPullBack) + { + pullBackStartBar = zone.FromIndex(); + } // + // Reading HK Bond ... + + // + double pHKBondUpper = fimaHelper.GetHKBondUpper(pBar.Index()); + double pHKBondLower = fimaHelper.GetHKBondLower(pBar.Index()); + int overHKBondUpperCount = fimaHelper.CountOverHKBondUpper(pullBackStartBar, X_PRICE_LOW); + int underHKBondLowerCount = fimaHelper.CountUnderHKBondLower(pullBackStartBar, X_PRICE_HIGH); + + // + // Reading PV Requirements ... + + // + int lastPeakOverLastIDX = -1; + int lastValeUnderLastIDX = -1; + double pPeak = fimaHelper.GetPeak(pBar.Index()); + double pVale = fimaHelper.GetVale(pBar.Index()); + int samePeaks = fimaHelper.CountSamePeaks(pBar.Index()); + int sameVales = fimaHelper.CountSameVales(pBar.Index()); + fimaHelper.FindLastPeakOverLast(lastPeakOverLastIDX, pBar.Index()); + fimaHelper.FindLastValeUnderLast(lastValeUnderLastIDX, pBar.Index()); + + // + // Reading pBar Patterns ... + XPatternAnalysis pBarAnalysis; + poiDetector.AnalyseBarPatterns( + pBar, + pBarAnalysis, + structureConfig.barsAnalysisConfig // + ); + + // + // Check Bar Patterns ... + bool isPBarHasBullishPatterns = + (bar.close > pBar.low || + bar.open > pBar.low) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH) + // + ); + bool isPBarHasBearishPatterns = + (bar.close < pBar.high || + bar.open < pBar.high) && + ( + // + pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) || + pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) || + pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) || + pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) || + pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH) + // + ); + + // + // Check PBar Close Over Under Fast Ma ... + bool isPBarCloseOverFast = pBar.close > fimaHelper.GetMAFast(pBar.Index()); + bool isPBarCloseUnderFast = pBar.close < fimaHelper.GetMAFast(pBar.Index()); + + // + // Try To Find Affected Zone ... + + // + // Collecting Zones ... XBoxZone zones[]; - int zonesCount = 0; - ENUM_X_PRICE bullishPriceType = X_PRICE_LOW; - ENUM_X_PRICE bearishPriceType = X_PRICE_HIGH; + XBoxZone affectedZones[]; + XBoxZone affectedZonesBullish[]; + XBoxZone affectedZonesBearish[]; + int zonesCount = poiDetector.CollectZones( + pBar, + zones, // + 5, // Zones Loopback ... + 3 // Zones Validation Length ... + // Required Zones ... + // Loopback ... + ); + int affectedZonesCount = ExtractAffectedZones( + pBar, + zones, + affectedZones // + ); + int affectedZonesBullishCount = ExtractByDirection( + affectedZonesBullish, + affectedZones, + X_DIRECTION_BULLISH // + ); + int affectedZonesBearishCount = ExtractByDirection( + affectedZonesBearish, + affectedZones, + X_DIRECTION_BEARISH // + ); // - isBullish = fimaHelper.IsSwitchedUnderHKBondLower(bullishPriceType, pBarIndex); + int insideBullishIDX = -1; + int insideBearishIDX = -1; + bool hasBullishInside = + pBar.IsBullish() && + HasInside( + insideBullishIDX, + pBar, + affectedZonesBullish // + ); + bool hasBearishInside = + pBar.IsBearish() && + HasInside( + insideBearishIDX, + pBar, + affectedZonesBearish // + ); // - isBearish = fimaHelper.IsSwitchedOverHKBondUpper(bearishPriceType, pBarIndex); + // Do ... // - result = - isBullish || - isBearish; + isBullish = + // + hasBullishInside && + isPullbackBullish && + isPBarHasBullishPatterns && + fimaHelper.IsSarBullish(pBar.Index()) && + (pVale >= affectedZonesBullish[insideBullishIDX].lower && + pVale <= affectedZonesBullish[insideBullishIDX].upper) + // + ; // - // Do Validations ... + isBearish = + // + hasBearishInside && + isPullbackBearish && + isPBarHasBearishPatterns && + fimaHelper.IsSarBearish(pBar.Index()) && + (pPeak >= affectedZonesBearish[insideBearishIDX].lower && + pPeak <= affectedZonesBearish[insideBearishIDX].upper) + // + ; + + // + // Validate ... + result = isBullish || + isBearish; if (result) { // - // Direction Assignment ... + if (isBullish) + { + // + poiDrawer.DrawZone( + affectedZonesBullish[insideBullishIDX], + structureDrawConfig.drawConfig // + ); + } + else + { + // + poiDrawer.DrawZone( + affectedZonesBearish[insideBearishIDX], + structureDrawConfig.drawConfig // + ); + } + + // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // - int lastIDX; - XBoxZone tmpZones[]; - int tmpZonesCount = 0; - int validationCount = 0; - ENUM_X_PRICE priceType = - isBullish - ? bullishPriceType - : bearishPriceType; - - // - // Detect Last Direction Change ... - if (isBullish) - { - result = fimaHelper.FindLastUnderHKBondLower(lastIDX, bullishPriceType, pBarIndex); - } - else - { - result = fimaHelper.FindLastOverHKBondUpper(lastIDX, bearishPriceType, pBarIndex); - } - - // - // Validate Direction Changed ... - if (result) - { - // - validationCount = lastIDX - pBarIndex; - result = validationCount >= 10; - } - - // - // Collect Zones ... - if (result) - { - // - // Support and Resistances ... - tmpZonesCount = poiDetector.CollectZones( - pBar, - tmpZones, - 5, - 14, // Zones Validation Length ... - 0, // Required Count ... - validationCount // Loopback ... - ); - if (IsValidSize(tmpZonesCount)) - { - // - Copy( - tmpZones, - zones, - false // ignore Clean ... - ); - } - - // - // OB ... - tmpZonesCount = poiDetector.CollectOBs( - pBar, - tmpZones, - 5, // Zones Loopback ... - 0, // Required Count ... - validationCount // Loopback ... - ); - if (IsValidSize(tmpZonesCount)) - { - // - Copy( - tmpZones, - zones, - false // ignore Clean ... - ); - } - - // - // FVG ... - tmpZonesCount = poiDetector.CollectFVGs( - pBar, - tmpZones, - 5, // Zones Loopback ... - 0, // Required Count ... - validationCount // Loopback ... - ); - if (IsValidSize(tmpZonesCount)) - { - // - Copy( - tmpZones, - zones, - false // ignore Clean ... - ); - } - - // - // Filter Zones Based on pBar ... - zonesCount = poiDetector.FilterZones( - pBar, - zones, - dir, - priceType, - dir // - ); - - // - // Extract Affected Zones ... - XClean(tmpZones); - tmpZonesCount = ExtractAffectedZones( - pBar, - zones, - tmpZones, - dir // - ); - Copy(tmpZones, zones); - zonesCount = ArraySize(zones); - - // - // Update Zones Time ... - UpdateToTime(zones); - } - - // - // Draw Zones ... - result = IsValidSize(zonesCount); - if (result) - { - // - for (int i = 0; i < zonesCount; i++) - { - poiDrawer.DrawZone(zones[i], structureDrawConfig.drawConfig); - } - } - - // - XClean(tmpZones); + result = HasDirection(dir); } // @@ -1434,37 +940,16 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller if (result) { // - // Zone Detection ... zone.Clean(); if (isBullish) { - // - int idx = GetLowest(zones); - if (IsValidIndex(idx)) - { - zone = zones[idx]; - } + zone = affectedZonesBullish[insideBullishIDX]; } else { - // - int idx = GetHighest(zones); - if (IsValidIndex(idx)) - { - zone = zones[idx]; - } + zone = affectedZonesBearish[insideBearishIDX]; } - // zone.dir = dir; - // zone.type = name; - // zone.to = bar.time; - // zone.at = pBar.time; - // zone.from = pBar.time; - // zone.symbol = bar.symbol; - // zone.period = bar.period; - // zone.lower = MathMin(pBar.low, bar.low); - // zone.upper = MathMax(pBar.high, bar.high); - // result = zone.IsValid(); } @@ -1473,8 +958,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // Prepare Targets ... if (result) { - // - // Target Handling ... } // @@ -1488,164 +971,10 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller } pBar.Clean(); XClean(zones); - - // - return result; - } - - /** - * Check Bar Has Signal Based on Strategy 4 ... - * - * @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 ... - * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... - * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... - * - * @return ( bool ) - */ - bool Strategy4HasSignal( - XOHCL &bar, - XBoxZone &zone, - XTarget &targets[], - ENUM_X_DIRECTION &dir, - XFIMAConditions &conditions, - XFIMAMarketStructure &_structure // - ) - { - // - bool result = false; - - // - // Prepare ... - zone.Clean(); - XClean(targets); - dir = X_DIRECTION_NONE; - - // - // Validate ... - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - // Define Requirements ... - bool isBullish = false; - bool isBearish = false; - - // - XOHCL pBar; - int barIndex = bar.Index(); - int pBarIndex = barIndex + 1; - result = bar.GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - // Do Conditions Checking ... - - // - // Reading HK Bond ... - double hkBondUpper = fimaHelper.GetHKBondUpper(pBarIndex); - double hkBondLower = fimaHelper.GetHKBondLower(pBarIndex); - bool hasHKBoundary = - NotEmptyZero(hkBondUpper) && - NotEmptyZero(hkBondLower); - - // - // Pullback Detection ... - bool isPullback = poiDetector.IsPullbackPattern( - pBar, - zone, - dir, - 2, - false // - ); - - // - isBullish = - isPullback && - hasHKBoundary && - IsXBullish(dir) && - zone.lower > hkBondLower; - - // - isBearish = - isPullback && - hasHKBoundary && - IsXBearish(dir) && - zone.upper < hkBondUpper; - - // - result = - isBullish || - isBearish; - - // - // Do Validations ... - if (result) - { - // - // Direction Assignment ... - dir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - // TEMP ... - poiDrawer.DrawZone( - zone, - structureDrawConfig.drawConfig // - ); - } - - // - // Prepare Decision Zone ... - if (result) - { - // - // Zone Detection ... - zone.Clean(); - - // - // zone.dir = dir; - // zone.type = name; - // zone.to = bar.time; - // zone.at = pBar.time; - // zone.from = pBar.time; - // zone.symbol = bar.symbol; - // zone.period = bar.period; - // zone.lower = MathMin(pBar.low, bar.low); - // zone.upper = MathMax(pBar.high, bar.high); - - // - result = zone.IsValid(); - } - - // - // Prepare Targets ... - if (result) - { - // - // Target Handling ... - } - - // - // Cleanup ... - if (!result) - { - // - zone.Clean(); - XClean(targets); - dir = X_DIRECTION_NONE; - } - pBar.Clean(); + pBarAnalysis.Clean(); + XClean(affectedZones); + XClean(affectedZonesBullish); + XClean(affectedZonesBearish); // return result; 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 a141fe1c..ac1fcbd5 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -39,12 +39,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector XCBarAnalyser *barAnalyser; // Bar Analyser ... XCXFIMAHelper *fimaHelper; // XFIMA Helper ... - // - XBoxZone obs[]; - XBoxZone fvgs[]; - XBoxZone supports[]; - XBoxZone resistances[]; - // // Constructor ... XCXFIMAPOIDetector( @@ -344,12 +338,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector */ void Destroy() { - // - SpecifiedClean(obs); - SpecifiedClean(fvgs); - SpecifiedClean(supports); - SpecifiedClean(resistances); - // delete barAnalyser; ZeroMemory(barAnalyser);