/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCBaseHelper // Description: provides all Base Indicator // Helper requirements ... // // // 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 // // Includes ... #include "../Classes/x-saherelm.base.class.mq5" // // Definitions ... // // a Class for Handle base requirements ... // for indicators ... class XCBaseHelper : public XCBase { // // Public ... public: // // Constructor ... void XCBaseHelper( string symbol, // Trading Symbol ENUM_TIMEFRAMES period // Trading Time Frame ) { // mSymbol = symbol; mPeriod = period; } // // Deconstructor ... void ~XCBaseHelper() { // IndicatorRelease(mHandler); } // // Setter(s) / Getter(s) ... // // Symbol ... string GetSymbol() { return mSymbol; } // // Period ... ENUM_TIMEFRAMES GetPeriod() { return mPeriod; } // // Retrieve Bars ... int CountBars() { // int result = Bars( mSymbol, mPeriod // ); // return result; } // // Retrieve Indicator Calculated Bars ... int CountCalculatedBars() { return BarsCalculated(mHandler); } // virtual void Free() { } // // Generate Tag ... virtual string GetTag() { // string result = NULL; // result = // GetToken() + "[" + GetSymbol() + "|" + ToXString(GetPeriod()) + "]" // ; // return result; } // // Functions ... /** * Extract Validated Zones ... * * @param zones: XBoxZone, collection reference to holds results ... * @param barIndex: int, Specified Bar Index ... * @param requiredNumberOFZones: int, required Number of Zones ... * @param breakValidLength: int, Breake Validation Length of Zones ... * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... * @param shadowMultiplier: double a Shadow Multiplier for Validation ... * @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ... * @param validationLength: int, Validation Length of Zones ... * @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ... * * @return ( int ) */ int ExtractBarZones( XBoxZone &zones[], int barIndex = 0, int requiredNumberOFZones = 50, int breakValidLength = 3, bool validateFakeBreakes = true, double shadowMultiplier = 3, double validationStrength = 1, int validationLength = 21, int maxAllowedLoopbackLength = 1500 // ) { // int result = 0; // // Prepare ... SpecifiedClean(zones); // // Normalize ... barIndex = NormalizeInt(barIndex, 0); validationLength = NormalizeInt(validationLength, 7); shadowMultiplier = NormalizeDouble(shadowMultiplier, 1); validationStrength = NormalizeDouble(validationStrength, 1); requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5); maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100); // // Reading Values ... // string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod(); double minAllowedStrength = (validationStrength * GetPoints(symbol)); // XOHCL bar; bool has = false; // // Initialized Start Bar ... has = bar.Init( symbol, period, barIndex // ); if (!has) { return result; } // XOHCL iBar; XBoxZone zone; int start = barIndex; bool isBullish = false; bool isBearish = false; bool lowShadowPassed = false; bool highShadowPassed = false; ENUM_X_DIRECTION dir = X_DIRECTION_NONE; int end = start + maxAllowedLoopbackLength; for (int i = start; i < end; i++) { // // Cleanup ... iBar.Clean(); zone.Clean(); dir = X_DIRECTION_NONE; // // Reading HK Buffesr ... has = bar.BarAt(i, iBar); if (!has) { continue; } // // Check Direction ... isBullish = iBar.open < iBar.close; isBearish = iBar.open > iBar.close; dir = (isBullish && !isBearish) ? X_DIRECTION_BULLISH : (isBearish && !isBullish) ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; has = HasDirection(dir); if (!has) { continue; } // // Low Shadow ... lowShadowPassed = iBar.GetLowShadow() >= (shadowMultiplier * iBar.GetHighShadow()); // // High Shadow ... highShadowPassed = iBar.GetHighShadow() >= (shadowMultiplier * iBar.GetLowShadow()); // has = (lowShadowPassed && !highShadowPassed) || (highShadowPassed && !lowShadowPassed); if (!has) { continue; } // // Filling Zone ... // zone.symbol = symbol; zone.period = period; zone.from = GetBarTime( zone.symbol, zone.period, i // ); zone.dir = lowShadowPassed ? X_DIRECTION_BULLISH : highShadowPassed ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; // zone.upper = IsXBullish(zone.dir) ? iBar.GetDown() : IsXBearish(zone.dir) ? iBar.high : EMPTY_VALUE; // zone.lower = IsXBullish(zone.dir) ? iBar.low : IsXBearish(zone.dir) ? iBar.GetUp() : EMPTY_VALUE; // zone.to = bar.time; zone.type = "XBar_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance" : "") + "_" + ToXString(TimeToSeconds(zone.from)); // // Validate ... has = zone.IsValid() && HasDirection(zone.dir) && NotEmptyZero(zone.upper) && NotEmptyZero(zone.lower) && (zone.IsBullish() ? bar.low > zone.upper : bar.high < zone.lower) && (zone.upper - zone.lower) >= minAllowedStrength && ValidateBarZone(zone, validationLength, breakValidLength, validateFakeBreakes); if (has) { // AddIfNotExists( zone, zones // ); } // // Cleanup Resources ... zone.Clean(); // // Validating ... result = ArraySize(zones); has = IsValidSize(result) && result >= requiredNumberOFZones; if (has) { break; } } // // Cleanup Resources ... bar.Clean(); iBar.Clean(); zone.Clean(); // return result; } /** * Validate Bar Zone ... * * @param zone: XBoxZone, reference to Specified Zone ... * @param validationLength: int, Validation Length of Zones ... * @param breakValidLength: int, Break Validation Length of Zones ... * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... * * @return ( bool ) */ bool ValidateBarZone( XBoxZone &zone, int validationLength = 1, int breakValidLength = 3, bool validateFakeBreakes = true // ) { // bool result = false; // // Normalize ... validationLength = NormalizeInt(validationLength, 1); breakValidLength = NormalizeInt(breakValidLength, 2); // // Validate ... result = zone.IsValid(); if (!result) { return result; } // // Requirements ... XOHCL iBar; int count = 0; string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod(); // int start = zone.FromIndex() + 1; int end = start + validationLength; // // Validate Before ... for (int i = start; i < end; i++) { // // Initialize Indexed Bar ... iBar.Clean(); result = iBar.Init( symbol, period, i // ); if (!result) { break; } // result = zone.IsBullish() ? iBar.low > zone.lower : iBar.high < zone.upper; if (!result) { break; } } // // Validating After ... if (result) { // start = zone.ToIndex() + 1; count = zone.FromIndex() - start; end = start + count; for (int i = start; i < end; i++) { // // Initialized Indexed Bar ... iBar.Clean(); result = iBar.Init( symbol, period, i // ); if (!result) { break; } // result = zone.IsBullish() ? iBar.low > zone.lower : iBar.high < zone.upper; if (!result) { // // Check For Fake Breake ... if (validateFakeBreakes && breakValidLength > 0) { // result = i - 1 >= 0; if (result) { // for (int j = i - 1; j >= zone.ToIndex(); j--) { // // Initialized Indexed Bar ... iBar.Clean(); result = iBar.Init( symbol, period, j // ); if (!result) { break; } // result = zone.IsBullish() ? iBar.close > zone.upper : iBar.close < zone.lower; if (result) { // result = MathAbs(j - i) <= breakValidLength; if (result) { break; } } } } } // if (!result) { break; } } } } // // Cleanup Resource ... iBar.Clean(); // return result; } // // Protected ... protected: // // Props ... // // Symbol ... string mSymbol; // // Period ... ENUM_TIMEFRAMES mPeriod; // // Indicator Handler ... int mHandler; // // Private ... private: // }; // // Tools ....