/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Helper Class Library // ---------------------------------------------- // Name: XCX121XATRHelper // Description: provides all 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 // // Imports ... #include "../Classes/x-saherelm.x-helper.class.mq5" // // Definitions ... // // Definitions ... enum ENUM_X121_XATR_BUFFERS { // X121_ATR_UPPER_LINE = 0, X121_ATR_LOWER_LINE = 1, X121_ATR_LINE = 2, X121_ATR_UPPER_RAW_LINE = 3, X121_ATR_LOWER_RAW_LINE = 4, X121_RSI_LINE = 5, }; // // Input Models ... struct X121XATRInputs { // // Props ... // // RSI ... int rsiLength; // Length double rsiOverSoldLevel; // Over Sold Level double rsiOverBoughtLevel; // Over Bought Level ENUM_APPLIED_PRICE rsiAppliedTo; // Applied To // // ATR Detection ... int atrLength; // Length double atrMultiplier; // Multiplier ENUM_APPLIED_PRICE atrUpperAppliedTo; // Upper Zone Applied To ENUM_APPLIED_PRICE atrLowerAppliedTo; // Lower Zone Applied To ENUM_X_MA_METHOD atrSmoothingMode; // Smoothing Method // int startCalculationForLastBars; // Calculate Last n Bars // bool showATRUpper; // Show Upper Zone bool showATRLower; // Show Lower Zone // // Constructor(s) ... X121XATRInputs() { // Clean(); } // // Tools ... // // Clean ... void Clean() { // // RSI ... rsiLength = 0; rsiOverSoldLevel = 0; rsiOverBoughtLevel = 0; rsiAppliedTo = PRICE_CLOSE; // // ATR ... atrLength = 0; // Length atrMultiplier = 0; // Multiplier atrUpperAppliedTo = PRICE_HIGH; // Upper Zone Applied To atrLowerAppliedTo = PRICE_LOW; // Lower Zone Applied To atrSmoothingMode = X_MA_MODE_NONE; // Smoothing Method // startCalculationForLastBars = 0; // showATRUpper = false; // Show Upper Zone showATRLower = false; // Show Lower Zone } // // Default ... void Default() { // // RSI ... rsiLength = 14; rsiOverSoldLevel = 30; rsiOverBoughtLevel = 70; rsiAppliedTo = PRICE_CLOSE; // // ATR ... atrLength = 14; // Length atrMultiplier = 1; // Multiplier atrUpperAppliedTo = PRICE_HIGH; // Upper Zone Applied To atrLowerAppliedTo = PRICE_LOW; // Lower Zone Applied To atrSmoothingMode = X_MA_MODE_EMA; // Smoothing Method // startCalculationForLastBars = 1500; showATRUpper = true; // Show Upper Zone showATRLower = true; // Show Lower Zone } // // Validate ... bool IsValid() { // bool result = false; // result = // atrLength > 0 && rsiLength > 0 && atrMultiplier > 0 && rsiOverSoldLevel > 0 && rsiOverBoughtLevel > 0 && startCalculationForLastBars > 0 && rsiOverSoldLevel < rsiOverBoughtLevel // ; // return result; } // // Retrieve MAx Length ... int Max() { // int result = 0; // result = MathMax(atrLength, rsiLength); // return result; } }; // // Conditions ... struct X121XATRConditions { // // Common ... string symbol; ENUM_TIMEFRAMES period; datetime time; // // Buffers ... double atrUpperBuffer[]; double atrLowerBuffer[]; double atrUpperRawBuffer[]; double atrLowerRawBuffer[]; double rsiBuffer[]; double atrBuffer[]; // // Conditions ... // // RSI ... // bool isRsiOverBought; bool isRsiCrossedOverOverBought; bool isRsiCrossedUnderOverBought; // bool isRsiOverSold; bool isRsiCrossedUnderOverSold; bool isRsiCrossedOverOverSold; // // ATR ... // bool isCloseOverAtrUpper; bool isCloseOverAtrLower; // bool isCloseUnderAtrUpper; bool isCloseUnderAtrLower; // bool isRejectUpAtrUpper; bool isRejectDownAtrUpper; // bool isRejectUpAtrLower; bool isRejectDownAtrLower; // bool isBreakUpAtrUpper; bool isBreakDownAtrUpper; // bool isBreakUpAtrLower; bool isBreakDownAtrLower; // // bool isCloseLower // // Constructor ... X121XATRConditions() { Clean(); } // // Tools ... /** * Cleaning Up ... */ void Clean() { // // Commons ... symbol = NULL; period = NULL; time = NULL; // // Buffers ... // Clean(rsiBuffer); Clean(atrBuffer); Clean(atrUpperBuffer); Clean(atrLowerBuffer); Clean(atrUpperRawBuffer); Clean(atrLowerRawBuffer); // ArraySetAsSeries(rsiBuffer, true); ArraySetAsSeries(atrBuffer, true); ArraySetAsSeries(atrUpperBuffer, true); ArraySetAsSeries(atrLowerBuffer, true); ArraySetAsSeries(atrUpperRawBuffer, true); ArraySetAsSeries(atrLowerRawBuffer, true); // // Conditions ... // // RSI ... // isRsiOverBought = false; isRsiCrossedOverOverBought = false; isRsiCrossedUnderOverBought = false; // isRsiOverSold = false; isRsiCrossedUnderOverSold = false; isRsiCrossedOverOverSold = false; // // ATR ... // isCloseOverAtrUpper = false; isCloseOverAtrLower = false; // isCloseUnderAtrUpper = false; isCloseUnderAtrLower = false; // isRejectUpAtrUpper = false; isRejectDownAtrUpper = false; // isRejectUpAtrLower = false; isRejectDownAtrLower = false; // isBreakUpAtrUpper = false; isBreakDownAtrUpper = false; // isBreakUpAtrLower = false; isBreakDownAtrLower = false; // // XDON ... } /** * Generate Conditions Scores ... * * @param bullishScore: Double, Directional Scores Reference ... * @param bearishScore: Double, Directional Scores Reference ... */ void GenerateScore( double &bullishScore, double &bearishScore // ) { // bullishScore = 0; bearishScore = 0; // // TODO: Implement if Required ... } /** * Generate Summary String for Represent Conditions State ... * * @param onlyCommons: Boolean, Just Generate Only Commons Conditions ... * @param onlyConditions: Boolean, Just Generate Only Conditions ... * @param includeScores: Boolean, Attach Scores Representations on Result ... * @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ... * @param separator: String, Separate Lines ... * * @return ( string ) */ string GenerateSummary( bool onlyCommons = false, bool onlyConditions = false, bool includeScores = true, bool ignoreFalseConditions = true, string separator = "\n" // ) { // string result = NULL; // double bullishScore = 0; double bearishScore = 0; GenerateScore( bullishScore, bearishScore // ); // string scoresStr = // "Scores: " + separator + "---------------" + separator + "Bullish: " + ToString(bullishScore) + separator + "Bearish: " + ToString(bearishScore) + separator + "" // ; // string commonStr = GenerateSpecifiedCommonSummary( this, separator, includeScores // ); // string conditionsStr = // // RSI ... ToString("isRsiOverBought", isRsiOverBought, ignoreFalseConditions, separator) + ToString("isRsiCrossedOverOverBought", isRsiCrossedOverOverBought, ignoreFalseConditions, separator) + ToString("isRsiCrossedUnderOverBought", isRsiCrossedUnderOverBought, ignoreFalseConditions, separator) + ToString("isRsiOverSold", isRsiOverSold, ignoreFalseConditions, separator) + ToString("isRsiCrossedUnderOverSold", isRsiCrossedUnderOverSold, ignoreFalseConditions, separator) + ToString("isRsiCrossedOverOverSold", isRsiCrossedOverOverSold, ignoreFalseConditions, separator) + // // ATR ... ToString("isCloseOverAtrUpper", isCloseOverAtrUpper, ignoreFalseConditions, separator) + ToString("isCloseOverAtrLower", isCloseOverAtrLower, ignoreFalseConditions, separator) + ToString("isCloseUnderAtrUpper", isCloseUnderAtrUpper, ignoreFalseConditions, separator) + ToString("isCloseUnderAtrLower", isCloseUnderAtrLower, ignoreFalseConditions, separator) + ToString("isRejectUpAtrUpper", isRejectUpAtrUpper, ignoreFalseConditions, separator) + ToString("isRejectDownAtrUpper", isRejectDownAtrUpper, ignoreFalseConditions, separator) + ToString("isRejectUpAtrLower", isRejectUpAtrLower, ignoreFalseConditions, separator) + ToString("isRejectDownAtrLower", isRejectDownAtrLower, ignoreFalseConditions, separator) + ToString("isBreakUpAtrUpper", isBreakUpAtrUpper, ignoreFalseConditions, separator) + ToString("isBreakDownAtrUpper", isBreakDownAtrUpper, ignoreFalseConditions, separator) + ToString("isBreakUpAtrLower", isBreakUpAtrLower, ignoreFalseConditions, separator) + ToString("isBreakDownAtrLower", isBreakDownAtrLower, ignoreFalseConditions, separator) + // "" // ; // result = // "[" + GetTag() + "]" + separator + (onlyConditions ? "" : commonStr) + (!includeScores ? "" : scoresStr) + " " + separator + (onlyCommons ? "" : conditionsStr) + "" // ; // return result; } /** * Retrieve nique Tag Identifier ... * * @return ( string ) */ string GetTag() { return GetTypeName(this); } // }; // // Class ... class XCX121XATRHelper : public XCBaseHelper { // // Public ... public: // // Props ... // // Constructors ... XCX121XATRHelper() : XCBaseHelper(_Symbol, _Period) { } // // Deconstructor ... ~XCX121XATRHelper() { } // // Tools ... bool Init( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Period X121XATRInputs &inputs // Inputs ) { // bool result = false; // mSymbol = symbol; mPeriod = period; // result = inputs.IsValid(); if (!result) { return result; } // ArraySetAsSeries(rsiBuffer, true); ArraySetAsSeries(atrUpperBuffer, true); ArraySetAsSeries(atrLowerBuffer, true); ArraySetAsSeries(atrBuffer, true); ArraySetAsSeries(atrUpperRawBuffer, true); ArraySetAsSeries(atrLowerRawBuffer, true); // mInputs = inputs; // mHandler = iCustom( mSymbol, mPeriod, "x-saherelm.x121.xatr", // // Inputs ... // // Market ... "", // // RSI Detection ... "", mInputs.rsiLength, mInputs.rsiAppliedTo, // // ATR Detection ... "", mInputs.atrLength, mInputs.atrMultiplier, mInputs.atrUpperAppliedTo, mInputs.atrLowerAppliedTo, mInputs.atrSmoothingMode, // // Presentation ... "", mInputs.startCalculationForLastBars, mInputs.showATRUpper, mInputs.showATRLower // ); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // return result; } // // Inputs ... // X121XATRInputs GetInputs() { return mInputs; } // bool SetInputs( X121XATRInputs &inputs // Configs ) { // return Init( mSymbol, mPeriod, inputs // ); } // // Readers ... // // RSI ... // double GetRSI( int barIndex // Bar Index ) { // if (barIndex < 0) { barIndex = 0; } // Calculate(); // int count = ArraySize(rsiBuffer); if (barIndex >= count) { barIndex = count - 1; } // return rsiBuffer[barIndex]; } // int CopyRSI( int start, // Start int count, // Number of Items for read double &buffer[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // // Update Calculations ... Calculate(); // // Copy Items ... return Copy( start, count, rsiBuffer, buffer, forceClean // ); } // // ATR ... // double GetATR( int barIndex // Bar Index ) { // if (barIndex < 0) { barIndex = 0; } // Calculate(); // int count = ArraySize(atrBuffer); if (barIndex >= count) { barIndex = count - 1; } // return atrBuffer[barIndex]; } // int CopyATR( int start, // Start int count, // Number of Items for read double &buffer[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // // Update Calculations ... Calculate(); // // Copy Items ... return Copy( start, count, atrBuffer, buffer, forceClean // ); } // double GetATRUpper( int barIndex // Bar Index ) { // if (barIndex < 0) { barIndex = 0; } // Calculate(); // int count = ArraySize(atrUpperBuffer); if (barIndex >= count) { barIndex = count - 1; } // return atrUpperBuffer[barIndex]; } // int CopyATRUpper( int start, // Start int count, // Number of Items for read double &buffer[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // // Update Calculations ... Calculate(); // // Copy Items ... return Copy( start, count, atrUpperBuffer, buffer, forceClean // ); } // double GetATRUpperRaw( int barIndex // Bar Index ) { // if (barIndex < 0) { barIndex = 0; } // Calculate(); // int count = ArraySize(atrUpperRawBuffer); if (barIndex >= count) { barIndex = count - 1; } // return atrUpperRawBuffer[barIndex]; } // int CopyATRUpperRaw( int start, // Start int count, // Number of Items for read double &buffer[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // // Update Calculations ... Calculate(); // // Copy Items ... return Copy( start, count, atrUpperRawBuffer, buffer, forceClean // ); } // double GetATRLower( int barIndex // Bar Index ) { // if (barIndex < 0) { barIndex = 0; } // Calculate(); // int count = ArraySize(atrLowerBuffer); if (barIndex >= count) { barIndex = count - 1; } // return atrLowerBuffer[barIndex]; } // int CopyATRLower( int start, // Start int count, // Number of Items for read double &buffer[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // // Update Calculations ... Calculate(); // // Copy Items ... return Copy( start, count, atrLowerBuffer, buffer, forceClean // ); } // double GetATRLowerRaw( int barIndex // Bar Index ) { // if (barIndex < 0) { barIndex = 0; } // Calculate(); // int count = ArraySize(atrLowerRawBuffer); if (barIndex >= count) { barIndex = count - 1; } // return atrLowerRawBuffer[barIndex]; } // int CopyATRLowerRaw( int start, // Start int count, // Number of Items for read double &buffer[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // // Update Calculations ... Calculate(); // // Copy Items ... return Copy( start, count, atrLowerRawBuffer, buffer, forceClean // ); } // bool GetConditions( X121XATRConditions &conditions, // int barIndex = 0, // int loopback = 5 // ) { // bool result = true; // if (loopback < 5) { loopback = 5; } // conditions.Clean(); // conditions.symbol = mSymbol; conditions.period = mPeriod; conditions.time = TimeCurrent(); // int zIndex = barIndex; int cIndex = zIndex + 1; int pIndex = cIndex + 1; int ppIndex = pIndex + 1; // XOHCL zBar; result = zBar.Init( mSymbol, mPeriod, zIndex // ); if (!result) { return result; } // XOHCL cBar; result = cBar.Init( mSymbol, mPeriod, cIndex // ); if (!result) { return result; } // XOHCL pBar; result = pBar.Init( mSymbol, mPeriod, pIndex // ); if (!result) { return result; } // // Buffers ... // CopyRSI( zIndex, loopback, conditions.rsiBuffer // ); // CopyATR( zIndex, loopback, conditions.atrBuffer // ); // CopyATRUpper( zIndex, loopback, conditions.atrUpperBuffer // ); // CopyATRUpperRaw( zIndex, loopback, conditions.atrUpperRawBuffer // ); // CopyATRLower( zIndex, loopback, conditions.atrLowerBuffer // ); // CopyATRLowerRaw( zIndex, loopback, conditions.atrLowerRawBuffer // ); // // Conditions ... // int cIDX = 1; int pIDX = cIDX + 1; // // RSI ... // bool isRsiOverBought = conditions.rsiBuffer[cIDX] > mInputs.rsiOverBoughtLevel; bool isRsiOverBoughtPrev = conditions.rsiBuffer[pIDX] > mInputs.rsiOverBoughtLevel; // bool isRsiCrossedOverOverBought = isRsiOverBought && !isRsiOverBoughtPrev; bool isRsiCrossedUnderOverBought = !isRsiOverBought && isRsiOverBoughtPrev; // bool isRsiOverSold = conditions.rsiBuffer[cIDX] < mInputs.rsiOverSoldLevel; bool isRsiOverSoldPrev = conditions.rsiBuffer[pIDX] < mInputs.rsiOverSoldLevel; // bool isRsiCrossedUnderOverSold = isRsiOverSold && !isRsiOverSoldPrev; bool isRsiCrossedOverOverSold = !isRsiOverSold && isRsiOverSoldPrev; // // ATR ... // bool isCloseOverAtrUpper = cBar.close > conditions.atrUpperBuffer[cIDX]; bool isCloseOverAtrLower = cBar.close > conditions.atrLowerBuffer[cIDX]; // bool isCloseUnderAtrUpper = cBar.close < conditions.atrUpperBuffer[cIDX]; bool isCloseUnderAtrLower = cBar.close < conditions.atrLowerBuffer[cIDX]; // bool isRejectUpAtrUpper = IsBarReject( atrUpperBuffer[cIDX], X_DIRECTION_BULLISH, cBar // ); bool isRejectDownAtrUpper = IsBarReject( atrUpperBuffer[cIDX], X_DIRECTION_BEARISH, cBar // ); // bool isRejectUpAtrLower = IsBarReject( atrLowerBuffer[cIDX], X_DIRECTION_BULLISH, cBar // ); ; bool isRejectDownAtrLower = IsBarReject( atrLowerBuffer[cIDX], X_DIRECTION_BEARISH, cBar // ); ; // bool isBreakUpAtrUpper = IsBarBreak( atrUpperBuffer[cIDX], X_DIRECTION_BULLISH, cBar // ); bool isBreakDownAtrUpper = IsBarBreak( atrUpperBuffer[cIDX], X_DIRECTION_BEARISH, cBar // ); // bool isBreakUpAtrLower = IsBarBreak( atrLowerBuffer[cIDX], X_DIRECTION_BULLISH, cBar // ); bool isBreakDownAtrLower = IsBarBreak( atrLowerBuffer[cIDX], X_DIRECTION_BEARISH, cBar // ); // conditions.isRsiOverSold = isRsiOverSold; conditions.isRsiOverBought = isRsiOverBought; conditions.isRejectUpAtrUpper = isRejectUpAtrUpper; conditions.isRejectUpAtrLower = isRejectUpAtrLower; conditions.isBreakUpAtrUpper = isBreakUpAtrUpper; conditions.isBreakUpAtrLower = isBreakUpAtrLower; conditions.isRejectDownAtrUpper = isRejectDownAtrUpper; conditions.isRejectDownAtrLower = isRejectDownAtrLower; conditions.isCloseOverAtrUpper = isCloseOverAtrUpper; conditions.isCloseOverAtrLower = isCloseOverAtrLower; conditions.isBreakDownAtrUpper = isBreakDownAtrUpper; conditions.isBreakDownAtrLower = isBreakDownAtrLower; conditions.isCloseUnderAtrUpper = isCloseUnderAtrUpper; conditions.isCloseUnderAtrLower = isCloseUnderAtrLower; conditions.isRsiCrossedOverOverSold = isRsiCrossedOverOverSold; conditions.isRsiCrossedUnderOverSold = isRsiCrossedUnderOverSold; conditions.isRsiCrossedOverOverBought = isRsiCrossedOverOverBought; conditions.isRsiCrossedUnderOverBought = isRsiCrossedUnderOverBought; // return result; } // // Protected ... protected: // // Private ... private: // // Props ... X121XATRInputs mInputs; // Inputs ... // // Buffers ... double rsiBuffer[]; double atrUpperBuffer[]; double atrLowerBuffer[]; double atrBuffer[]; double atrUpperRawBuffer[]; double atrLowerRawBuffer[]; // void Calculate() { // int totalBars = CountBars(); if (totalBars > 1000) { totalBars = 1000; } // // Buffers ... // // RSI ... CopyBuffer( mHandler, X121_RSI_LINE, 0, totalBars, rsiBuffer // ); // // ATR ... // CopyBuffer( mHandler, X121_ATR_UPPER_LINE, 0, totalBars, atrUpperBuffer // ); // CopyBuffer( mHandler, X121_ATR_LOWER_LINE, 0, totalBars, atrLowerBuffer // ); // CopyBuffer( mHandler, X121_ATR_LINE, 0, totalBars, atrBuffer // ); // CopyBuffer( mHandler, X121_ATR_UPPER_RAW_LINE, 0, totalBars, atrUpperRawBuffer // ); // CopyBuffer( mHandler, X121_ATR_LOWER_RAW_LINE, 0, totalBars, atrLowerRawBuffer // ); } }; // // Tools ...