/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Tools Library // -------------------------------------- // Name: XToolsLib // Description: provide all commonly used Tools ... // // // 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 "../Libraries/x-saherelm.draw.lib.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // // Definitions ... // // a Pivot Point ... struct XPivot { // string symbol; // Trading Symbol ... ENUM_TIMEFRAMES period; // Trading TimeFrame ... // double price; // Price ... datetime time; // Time ... // int breakedAsSupport; // Number of Breaked As Support ... int rejectedAsSupport; // Number of Rejected As Support ... // int breakedAsResistance; // Number of Breaked As Resistance ... int rejectedAsResistance; // Number of Rejected As Resistance ... // bool isSupport; bool isResistance; // int _lastCalculatedBar; int _loopbackForSupportAndResistance; // Number of LoopBacks for Support or Resistance ... // // Constructor ... XPivot() { Clean(); } // // Initialization ... bool Init( string _symbol, ENUM_TIMEFRAMES _period, double _price, int _supResVerifications = 21 // ) { // bool result = false; // result = // _price > 0 && IsValid(_symbol) && IsValid(_period) && IsValidSize(_supResVerifications) // ; if (!result) { return result; } // symbol = _symbol; period = _period; price = _price; // _loopbackForSupportAndResistance = _supResVerifications; // Calculate(); // result = IsValid(); // return result; } // // Tools ... // // Check Support Rejected ... bool IsSupportRejected() { // bool result = false; // result = isSupport; if (!result) { return result; } // // Initialize Required Bars ... // XOHCL cBar; result = cBar.Init( symbol, period, 1 // ); if (!result) { return result; } // XOHCL pBar; result = pBar.Init( symbol, period, 2 // ); if (!result) { return result; } // result = // // Check Support Touch or Fake Break ... pBar.low < price // && // // Check Rejection ... cBar.low > price // ; // return result; } // // Check Support Breaked ... bool IsSupportBreaked() { // bool result = false; // result = isSupport; if (!result) { return result; } // // Initialize Required Bars ... // XOHCL cBar; result = cBar.Init( symbol, period, 1 // ); if (!result) { return result; } // XOHCL pBar; result = pBar.Init( symbol, period, 2 // ); if (!result) { return result; } // result = // // Check Support Breaks ... pBar.close < price // && // // Check 50% ... (price - pBar.close) > (pBar.GetBody() / 100) * 50 // && // // Also Next Bar must Closed Below Support ... cBar.high < price // && // cBar.close < price // && // cBar.IsBullish() // ; // return result; } // // Check Resistance Rejected ... bool IsResistanceRejected() { // bool result = false; // result = isResistance; if (!result) { return result; } // // Initialize Required Bars ... // XOHCL cBar; result = cBar.Init( symbol, period, 1 // ); if (!result) { return result; } // XOHCL pBar; result = pBar.Init( symbol, period, 2 // ); if (!result) { return result; } // result = // // Check Resistance Touch or Fake Break ... pBar.high > price // && // // Check Rejection ... cBar.high < price // ; // return result; } // // Check Resistance Breaked ... bool IsResistanceBreaked() { // bool result = false; // result = isResistance; if (!result) { return result; } // // Initialize Required Bars ... // XOHCL cBar; result = cBar.Init( symbol, period, 1 // ); if (!result) { return result; } // XOHCL pBar; result = pBar.Init( symbol, period, 2 // ); if (!result) { return result; } // result = // // Check Resistance Breaks ... pBar.close > price // && // // Check 50% ... (pBar.close - price) > (pBar.GetBody() / 100) * 50 // && // // Also Next Bar Must Closed Above Resistance ... cBar.low > price // && // cBar.close > price // && // cBar.IsBullish() // ; // return result; } // // Cleanup ... void Clean() { // symbol = NULL; period = NULL; time = NULL; // price = 0; // breakedAsSupport = 0; rejectedAsSupport = 0; breakedAsResistance = 0; rejectedAsResistance = 0; // _lastCalculatedBar = -1; // isSupport = false; isResistance = false; } // // Validate Model ... bool IsValid() { // bool result = false; // result = // IsValid(symbol) && IsValid(period) && price > 0 // ; // return result; } // // Calculate Required Data ... void Calculate(int loopback = 288) { // if (isSupport || isResistance) { return; } // int bars = iBars( symbol, period // ); // // Normalizing Loopback ... if (loopback > bars) { loopback = bars - 2 - _loopbackForSupportAndResistance; } // // Check Previous Calculation ... if (bars == _lastCalculatedBar) { return; } // _lastCalculatedBar = bars; // // First Get Current State of Pivot ... // Means Use Zero Index ... XOHCL pBar; bool isInited = pBar.Init( symbol, period, 1 // ); if (!isInited) { return; } // // Retrieve Highest High and Lowest Low of SupRes Loopback ... double hhValue = pBar .FindHighest( _loopbackForSupportAndResistance, MODE_HIGH // ); // double llValue = pBar .FindLowest( _loopbackForSupportAndResistance, MODE_LOW // ); // isSupport = llValue > price; isResistance = hhValue < price; // // Prevent Moving Forward if it isn't Support or Resistance ... if (!isSupport && !isResistance) { return; } // time = TimeCurrent(); // for (int i = 2; i < loopback; i++) { // XOHCL iBar; isInited = iBar.Init( symbol, period, i // ); if (!isInited) { continue; } // XOHCL iPBar; isInited = iPBar.Init( symbol, period, i + 1 // ); if (!isInited) { continue; } // XOHCL iPPBar; isInited = iPPBar.Init( symbol, period, i + 2 // ); if (!isInited) { continue; } // bool isBreaked = false; bool isRejected = false; // if (isSupport) { // // Count Support Rejects // and Support Breaks ... // // Support Rejected ... isRejected = // // Check Support Touch or Fake Break ... iPBar.low < price // && // // Check Rejection ... iBar.low > price // ; if (isRejected) { rejectedAsSupport++; } // // Support Breaked ... isBreaked = // // Check Support Breaks ... iPBar.close < price // && // // Check 50% ... (price - iPBar.close) > (iPBar.GetBody() / 100) * 50 // && // // Also Next Bar must Closed Below Support ... iBar.high < price // && // iBar.close < price // && // iBar.IsBullish() // ; if (isBreaked) { breakedAsSupport++; } } else if (isResistance) { // // Count Resistance Reject // or Resistance Breaks ... // // Resistance Rejected ... isRejected = // // Check Resistance Touch or Fake Break ... iPBar.high > price // && // // Check Rejection ... iBar.high < price // ; if (isRejected) { rejectedAsResistance++; } // // Resistance Breaked ... isBreaked = // // Check Resistance Breaks ... iPBar.close > price // && // // Check 50% ... (iPBar.close - price) > (iPBar.GetBody() / 100) * 50 // && // // Also Next Bar Must Closed Above Resistance ... iBar.low > price // && // iBar.close > price // && // iBar.IsBullish() // ; if (isBreaked) { breakedAsResistance++; } } } } // string GetTag() { return "XPivot"; } }; // // a Zone Modeling ... // enum ENUM_XZONE_STATE { XZONE_STATE_INVALID = 0, // Invalid Zone ... XZONE_STATE_FULL_SUPPORT = 1, // Full Support (up / down) are Support ... XZONE_STATE_FULL_RESISTANCE = 2, // Full Resistance (up / down) are Resistaence ... XZONE_STATE_CONSOLIDATE = 3, // Down are Support and Up are Resistance ... }; // struct XZone { // string symbol; // Trading Symbol ... ENUM_TIMEFRAMES period; // Trading TimeFrame ... // datetime time; // XPivot up; // Up pivot ... XPivot down; // Down Pivot ... // // Constructor ... XZone() { Clean(); } // // Initialize a Zone ... bool Init( string _symbol, ENUM_TIMEFRAMES _period, double _upPrice, double _downPrice // ) { // bool result = false; // result = // IsValid(_symbol) && IsValid(_period) && _upPrice > 0 && _downPrice > 0 && _downPrice < _upPrice // ; if (!result) { return result; } // symbol = _symbol; period = _period; // result = up.Init( symbol, period, _upPrice // ); if (!result) { return result; } // result = down.Init( symbol, period, _downPrice // ); if (!result) { return result; } // result = IsValid(); // if (result) { time = TimeCurrent(); } // return result; } // // Tools ... // // Check XZone State ... ENUM_XZONE_STATE GetState() { // ENUM_XZONE_STATE result = XZONE_STATE_INVALID; if (!IsValid()) { return result; } // up.Calculate(); down.Calculate(); // if (up.isSupport && down.isSupport) { result = XZONE_STATE_FULL_SUPPORT; } else if (up.isResistance && down.isResistance) { result = XZONE_STATE_FULL_RESISTANCE; } else if (up.isSupport && down.isResistance) { result = XZONE_STATE_CONSOLIDATE; } // return result; } // // Check Zone Rejected ... // // Check Zone Breaked ... // // Cleanup ... void Clean() { // symbol = NULL; period = NULL; time = NULL; // up.Clean(); down.Clean(); } // // Validate ... bool IsValid() { // bool result = false; // result = // IsValid(symbol) && IsValid(period) && up.IsValid() && down.IsValid() // ; // return result; } }; // // a Range Box Model ... struct XRBox { // string symbol; ENUM_TIMEFRAMES period; // datetime time; datetime expiration; // XZone up; // Up Zone ... XZone down; // Down Zone ... // // Constructor ... XRBox() { Clean(); } // // Initialization ... bool Init( string _symbol, ENUM_TIMEFRAMES _period, double _upZoneUpperPrice, double _upZoneLowerPrice, double _downZoneUpperPrice, double _downZoneLowerPrice, datetime _expiration = NULL // ) { // bool result = false; // result = // IsValid(_symbol) && IsValid(_period) && _upZoneUpperPrice > 0 && _upZoneLowerPrice > 0 && _upZoneLowerPrice < _upZoneUpperPrice && _downZoneUpperPrice > 0 && _downZoneLowerPrice > 0 && _downZoneLowerPrice < _downZoneUpperPrice // ; // if (!result) { return result; } // result = IsValid(); // if (result) { // time = TimeCurrent(); } // return result; } // // Tools ... // // Cleanup ... void Clean() { // time = NULL; symbol = NULL; period = NULL; expiration = NULL; // up.Clean(); down.Clean(); } // // Validation ... bool IsValid() { // bool result = false; // result = // IsValid(symbol) && IsValid(period) && up.IsValid() && down.IsValid() // ; // return result; } }; // // Detect Trends ... struct XTrendDetector { // string symbol; ENUM_TIMEFRAMES period; // double higherHighs[]; datetime higherHighTimes[]; // double higherLows[]; datetime higherLowTimes[]; // double lowerHighs[]; datetime lowerHighTimes[]; // double lowerLows[]; datetime lowerLowTimes[]; // int _numberOfPivots; int _pivotShoulders; // // Constructor ... XTrendDetector() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // symbol = NULL; period = NULL; // _numberOfPivots = 0; _pivotShoulders = 0; // Clean(higherHighs); Clean(higherHighTimes); // Clean(higherLows); Clean(higherLowTimes); // Clean(lowerHighs); Clean(lowerHighTimes); // Clean(lowerLows); Clean(lowerLowTimes); } // // Validate ... bool IsValid() { // bool result = false; // result = // IsValid(symbol) && IsValid(period) // ; // return result; } };