From a908d4ad1a02eb071af8f84b59294416b6d91302 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 8 Nov 2024 17:56:16 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-chart-objects.class.mq5 | 6 +- Classes/z-saherelm.x-bar.analyser.class.mq5 | 713 ++++++++++++++++++ .../Classes/x-121.smc.base.strategy.class.mq5 | 2 + .../x-121.smc.test.strategy.class.mq5 | Bin 140192 -> 156814 bytes 4 files changed, 718 insertions(+), 3 deletions(-) create mode 100644 Classes/z-saherelm.x-bar.analyser.class.mq5 diff --git a/Classes/x-saherelm.x-chart-objects.class.mq5 b/Classes/x-saherelm.x-chart-objects.class.mq5 index dfc64384..93114c8a 100644 --- a/Classes/x-saherelm.x-chart-objects.class.mq5 +++ b/Classes/x-saherelm.x-chart-objects.class.mq5 @@ -511,10 +511,10 @@ class XCZoneObject : public XCBaseObject } // - NormalizeTime(time2); + datetime time_2 = NormalizeTime(time2); // - result = time1 < time2; + result = time1 < time_2; if (!result) { return result; @@ -544,7 +544,7 @@ class XCZoneObject : public XCBaseObject window, time1, upperPrice1, - time2, + time_2, lowerPrice1 // ); } diff --git a/Classes/z-saherelm.x-bar.analyser.class.mq5 b/Classes/z-saherelm.x-bar.analyser.class.mq5 new file mode 100644 index 00000000..aeb831a1 --- /dev/null +++ b/Classes/z-saherelm.x-bar.analyser.class.mq5 @@ -0,0 +1,713 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XPOI +// Description: Bar Analysing ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +// Definitions ... + +// +// Implementations ... +class XCBarAnalyser : public XSCBase +{ + // + public: + // + + // + // Constructor(s) ... + void XCBarAnalyser() + { + } + + // + // Deconstructor ... + void ~XCBarAnalyser() + { + } + + // + // Getter(s) / Setter(s) ... + + // + // Providers ... + + // + // Actions ... + + // + // Commons ... + + /** + * Check Specified Bar's Range is Extended or not ... + * + * @param bar: XOHCL instance, Specified Bar ... + * @param loopback: Integer, Loopback Length ... + * + * @return ( bool ) + */ + bool HasExtendedRange( + XOHCL &bar, + int loopback = 3 // + ) + { + // + bool result = false; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int index = bar.Index(); + int start = index + 1; + int end = start + loopback; + int count = end - start; + result = count >= 1; + if (!result) + { + return result; + } + + // + double sum = 0; + XOHCL iBar = bar; + for (int i = start; i < end; i++) + { + // + bool isRetrieved = iBar.GetPreviousBar(iBar); + if (!isRetrieved) + { + continue; + } + + // + sum += iBar.GetRange(); + } + + // + result = sum > 0; + if (!result) + { + return result; + } + + // + double avg = sum / count; + + // + result = bar.GetRange() >= avg; + + // + return result; + } + + /** + * Check Specified Bar's Body is Extended or not ... + * + * @param bar: XOHCL instance, Specified Bar ... + * @param loopback: Integer, Loopback Length ... + * + * @return ( bool ) + */ + bool HasExtendedBody( + XOHCL &bar, + int loopback = 3 // + ) + { + // + bool result = false; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int index = bar.Index(); + int start = index + 1; + int end = start + loopback; + int count = end - start; + result = count >= 1; + if (!result) + { + return result; + } + + // + double sum = 0; + XOHCL iBar = bar; + for (int i = start; i < end; i++) + { + // + bool isRetrieved = iBar.GetPreviousBar(iBar); + if (!isRetrieved) + { + continue; + } + + // + sum += iBar.GetBody(); + } + + // + result = sum > 0; + if (!result) + { + return result; + } + + // + double avg = sum / count; + + // + result = bar.GetBody() >= avg; + + // + return result; + } + + /** + * Check Specified Bar's Body and Range is Extended or not ... + * + * @param bar: XOHCL instance, Specified Bar ... + * @param loopback: Integer, Loopback Length ... + * + * @return ( bool ) + */ + bool IsExtended( + XOHCL &bar, + int loopback = 3 // + ) + { + // + bool result = false; + + // + bool hasExtendedBody = HasExtendedBody(bar, loopback); + bool hasExtendedRange = HasExtendedRange(bar, loopback); + result = hasExtendedBody && + hasExtendedRange; + + // + return result; + } + + // + // Rejection Bar ... + + /** + * Check Specific Bar is Bullish Rejection Bar or not ... + * + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsBullishRejectionBar( + XOHCL &bar, + double strength = 40 // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = IsRejectionBar( + dir, + bar, + strength // + ); + result = + result && + dir == X_DIRECTION_BULLISH; + + // + return result; + } + + /** + * Check Specific Bar is Bearish Rejection Bar or not ... + * + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsBearishRejectionBar( + XOHCL &bar, + double strength = 40 // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = IsRejectionBar( + dir, + bar, + strength // + ); + result = + result && + dir == X_DIRECTION_BEARISH; + + // + return result; + } + + // + // Momentum Bar ... + + /** + * Check Specific Bar is Bullish Momentum Bar or not ... + * + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsBullishMomentumBar( + XOHCL &bar, + double strength = 40 // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = IsMomentumBar( + dir, + bar, + strength // + ); + result = + result && + dir == X_DIRECTION_BULLISH; + + // + return result; + } + + /** + * Check Specific Bar is Bearish Momentum Bar or not ... + * + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsBearishMomentumBar( + XOHCL &bar, + double strength = 40 // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = IsMomentumBar( + dir, + bar, + strength // + ); + result = + result && + dir == X_DIRECTION_BEARISH; + + // + return result; + } + + /** + * Check Bar is Bullish Engulfed or not ... + * + * @param bar: XOHCL instance, Speciied Bar ... + * @param loopback: Integer, loopback Length ... + * + * @return ( bool ) + */ + bool IsBullishEngulfed( + XOHCL &bar, + int loopback = 2 // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = IsEngulfed( + dir, + bar, + loopback // + ); + result = + result && + dir == X_DIRECTION_BULLISH; + + // + return result; + } + + /** + * Check Bar is Bearish Engulfed or not ... + * + * @param bar: XOHCL instance, Speciied Bar ... + * @param loopback: Integer, loopback Length ... + * + * @return ( bool ) + */ + bool IsBearishEngulfed( + XOHCL &bar, + int loopback = 2 // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = IsEngulfed( + dir, + bar, + loopback // + ); + result = + result && + dir == X_DIRECTION_BEARISH; + + // + return result; + } + + // + protected: + // + + // + private: + // + + // + // Props ... + + // + // Actions ... + + /** + * Calculate Bar Range ... + * + * @param bar: XOHCL instance ... + * + * @return ( double ) + */ + double GetBarRangePercent(XOHCL &bar) + { + // + double result = 0; + + // + result = bar.GetRange() / 100; + + // + return result; + } + + /** + * Check Specific Bar is Rejection Bar or not ... + * + * @param dir: ENUM_X_DIRECTION member, Specified Direction ... + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsRejectionBar( + ENUM_X_DIRECTION &dir, + XOHCL &bar, + double strength // + ) + { + // + bool result = false; + + // + if (strength < 20) + { + strength = 20; + } + + // + dir = X_DIRECTION_NONE; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + double barLowShadow = bar.GetLowShadow(); + double barHighShadow = bar.GetHighShadow(); + double barRange = bar.GetRange(); + double barRangePercent = barRange / 100; + + // + bool isBullishRejectionBar = + barLowShadow > barHighShadow && + barLowShadow > barRangePercent * 40; + + // + bool isBearishRejectionBar = + barHighShadow > barLowShadow && + barHighShadow > barRangePercent * 40; + + // + result = isBullishRejectionBar || + isBearishRejectionBar; + if (result) + { + // + dir = isBullishRejectionBar + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + /** + * Check Specific Bar is Momentum Bar or not ... + * + * @param dir: ENUM_X_DIRECTION member, Specified Direction ... + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsMomentumBar( + ENUM_X_DIRECTION &dir, + XOHCL &bar, + double strength // + ) + { + // + bool result = false; + + // + if (strength < 50) + { + strength = 50; + } + + // + dir = X_DIRECTION_NONE; + + // + double rangePercent = GetBarRangePercent(bar); + bool isStrong = bar.GetBody() > rangePercent * strength; + + // + result = isStrong; + if (result) + { + // + dir = bar.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + /** + * Retrieve Loopback HH LL Data ... + * + * @param hhIDX: Integer, HH Index ... + * @param hh: Double, HH Value ... + * @param llIDX: Integer, LL Index ... + * @param ll: Double, LL Value ... + * @param bar: XOHCL instance ... + * @param loopback: Integer, Loopback Length ... + * + * @return ( bool ) + */ + bool GetLoopbackData( + int &hhIDX, + double &hh, + int &llIDX, + double &ll, + XOHCL &bar, + int loopback // + ) + { + // + bool result = false; + + // + if (loopback < 1) + { + loopback = 1; + } + + // + int index = bar.Index(); + int start = index + 1; + int end = start + loopback; + int count = end - start; + result = count >= 1; + if (!result) + { + return result; + } + + // + hhIDX = iHighest( + bar.symbol, + bar.period, + MODE_HIGH, + start, + count // + ); + result = IsValidIndex(hhIDX); + if (!result) + { + return result; + } + + // + llIDX = iLowest( + bar.symbol, + bar.period, + MODE_LOW, + start, + count // + ); + result = IsValidIndex(llIDX); + if (!result) + { + return result; + } + + // + hh = iHigh( + bar.symbol, + bar.period, + hhIDX // + ); + ll = iLow( + bar.symbol, + bar.period, + llIDX // + ); + + // + return result; + } + + /** + * Check Bar is Engulfed or not ... + * + * @param dir: ENUM_X_DIRECTION member, Specified Direction ... + * @param bar: XOHCL instance, Speciied Bar ... + * @param loopback: Integer, loopback Length ... + * + * @return ( bool ) + */ + bool IsEngulfed( + ENUM_X_DIRECTION &dir, + XOHCL &bar, + int loopback // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + int hhIDX = 0; + double hh = 0; + + // + int llIDX = 0; + double ll = 0; + + // + result = GetLoopbackData( + hhIDX, + hh, + llIDX, + ll, + bar, + loopback // + ); + if (!result) + { + return result; + } + + // + result = bar.GetDown() < ll && + bar.GetUp() > hh; + if (result) + { + // + dir = bar.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 index de857359..f239f4ce 100644 --- a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 @@ -26,6 +26,7 @@ #include "../../Classes/x-saherelm.x-poi.class.mq5" #include "../../Classes/x-saherelm.xalert.class.mq5" #include "../../Classes/x-saherelm.xtrade.class.mq5" +#include "../../Classes/z-saherelm.x-bar.analyser.class.mq5" #include "../Classes/x-121.smc.chart.objects.class.mq5" #include "../Libraries/x-121.smc.lib.mq5" @@ -533,6 +534,7 @@ class XCX121SMCBaseStrategy : public XSCBaseAlert // XBarTracker mBarTracker; // Strategy Time Tracker ... + XCBarAnalyser mBarAnalyser; // Bar Analyser Instance X121SMCStrategyConditions mConditions; // Market Conditions ... // diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index 73a14df3761ac63da533db624d137f5c0bdce97e..41a4d515caca4e281dbeb3f67bdc3b82da09f1e8 100644 GIT binary patch delta 5135 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 DXm=gb delta 427 zcmYjM%_{_97@was##+|r+Yu?lg(Um$;izW~on4i4|z^Lu|^&s%4icG z=u}Q4CUixnrUcf!8brn(J-<`~h5g=yNG;wfq3 zj#jT&c4;F;p9QGoE;8Z2c^f8DpbHzLJ`?qF1q}aT=LRFh{0zB2h>?Da5EU$B=*#&B z!(^PXu5!(ZAGbUOEqVhBum^=3=p%1ANA*TZ6>ldZ#aL?m(j_# z;3t&^S5}GPcY}95vmir!Rs(i|-cQ-)mwOzr19FZLCwB^AZ|MPhJKB~sF11Uc;H0Ir F^b3CijKTl_