/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XMATD // Description: provides Indicator implementation // 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.base.class.mq5" // // Indicator Buffers ... enum ENUM_XMATD_BUFFERS { XMATD_FAST_LINE = 0, // Fast Buffer ... XMATD_MID_LINE = 1, // Mid Buffer ... XMATD_SLOW_LINE = 2, // Slow Buffer ... XMATD_PSAR_LINE = 3, // Parabolic Buffer ... }; // string GetTitle(ENUM_XMATD_BUFFERS bufferLine) { // string result = NULL; // switch (bufferLine) { // case XMATD_FAST_LINE: result = "XFats"; break; // case XMATD_MID_LINE: result = "XMid"; break; // case XMATD_SLOW_LINE: result = "XSlow"; break; } // return result; } // // XMATD Indicator Inputs ... struct XMATDInputs { // // Props ... string version; // // Market ... // int fastLength; // Fast Length int midLength; // Mid Length int slowLength; // Slow Length // double step; // Sar Step double maximum; // Sar Maximum // // Calculation Mode ... // int shift; // Shift ENUM_MA_METHOD method; // Method of MA ENUM_APPLIED_PRICE appliedTo; // Applied To // // Constructor ... XMATDInputs() { Clean(); } // // Tools ... // // Initial Inputs ... bool Init( int _fastLength = 21, // Fast Length int _midLength = 50, // Mid Length int _slowLength = 200, // Slow Length ENUM_MA_METHOD _method = MODE_SMA, // Shift ENUM_APPLIED_PRICE _appliedTo = PRICE_CLOSE, // Method of MA int _shift = 0 // Applied To ) { // bool result = false; // this.fastLength = _fastLength; this.midLength = _midLength; this.slowLength = _slowLength; // this.shift = _shift; this.method = _method; this.appliedTo = _appliedTo; // result = IsValid(); // return result; } // // Cleanup ... void Clean() { // fastLength = 0; midLength = 0; slowLength = 0; // shift = 0; // step = 0; maximum = 0; // method = MODE_SMA; appliedTo = PRICE_CLOSE; } // // Default ... void Default() { // fastLength = 21; midLength = 50; slowLength = 200; // method = MODE_SMA; appliedTo = PRICE_CLOSE; // step = 0.02; maximum = 0.2; } // // Validate ... bool IsValid() { // bool result = false; // result = // fastLength > 0 && midLength > fastLength && slowLength > midLength // && // step > 0 && maximum > step // ; // return result; } // // Retrieve Max Length ... int Max() { // int result = 0; // int values[3] = { fastLength, midLength, slowLength // }; // result = GetMax(values); // return result; } }; // // Define Conditions ... struct XMATDConditions { // // Common ... string symbol; ENUM_TIMEFRAMES period; datetime time; // // Buffers ... double fast[]; double mid[]; double slow[]; // double psar[]; // // Conditions ... // // Trend ... bool isBullish; bool isBearish; bool isSwitchedToBullish; bool isSwitchedToBearish; // // Fast Mid ... bool isFastOverMid; bool isFastUnderMid; bool isFastCrossedOverMid; bool isFastCrossedUnderMid; // // Fast Slow ... bool isFastOverSlow; bool isFastUnderSlow; bool isFastCrossedOverSlow; bool isFastCrossedUnderSlow; // // Mid Slow ... bool isMidOverSlow; bool isMidUnderSlow; bool isMidCrossedOverSlow; bool isMidCrossedUnderSlow; // bool isSARBullish; bool isSARBearish; bool isSARSwitchedToBullish; bool isSARSwitchedToBearish; // void Clean() { // Clean(fast); Clean(mid); Clean(slow); Clean(psar); // ArraySetAsSeries(fast, true); ArraySetAsSeries(mid, true); ArraySetAsSeries(slow, true); ArraySetAsSeries(psar, true); // // Trend ... isBullish = false; isBearish = false; isSwitchedToBullish = false; isSwitchedToBearish = false; // // Fast Mid ... isFastOverMid = false; isFastUnderMid = false; isFastCrossedOverMid = false; isFastCrossedUnderMid = false; // // Fast Slow ... isFastOverSlow = false; isFastUnderSlow = false; isFastCrossedOverSlow = false; isFastCrossedUnderSlow = false; // // Mid Slow ... isMidOverSlow = false; isMidUnderSlow = false; isMidCrossedOverSlow = false; isMidCrossedUnderSlow = false; // isSARBullish = false; isSARBearish = false; isSARSwitchedToBullish = false; isSARSwitchedToBearish = false; } // void GenerateScore( double &bullishScore, double &bearishScore // ) { // bullishScore = 0; bearishScore = 0; // // Trend ... // if (isBullish) { bullishScore++; } if (isSwitchedToBullish) { bullishScore++; } // if (isBearish) { bearishScore++; } if (isSwitchedToBearish) { bearishScore++; } // // Fast Mid ... // if (isFastOverMid) { bullishScore++; } if (isFastCrossedOverMid) { bullishScore++; } // if (isFastUnderMid) { bearishScore++; } if (isFastCrossedUnderMid) { bearishScore++; } // // Fast Slow ... // if (isFastOverSlow) { bullishScore++; } if (isFastCrossedOverSlow) { bullishScore++; } // if (isFastUnderSlow) { bearishScore++; } if (isFastCrossedUnderSlow) { bearishScore++; } // // Mid Slow ... // if (isMidOverSlow) { bullishScore++; } if (isMidCrossedOverSlow) { bullishScore++; } // if (isMidUnderSlow) { bearishScore++; } if (isMidCrossedUnderSlow) { bearishScore++; } // if (isSARBullish) { bullishScore++; } if (isSARSwitchedToBullish) { bullishScore++; } // if (isSARBearish) { bearishScore++; } if (isSARSwitchedToBearish) { bearishScore++; } } // 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 = // // Trend ... ToString("isBullish", isBullish, ignoreFalseConditions, separator) + ToString("isBearish", isBearish, ignoreFalseConditions, separator) + ToString("isSwitchedToBullish", isSwitchedToBullish, ignoreFalseConditions, separator) + ToString("isSwitchedToBearish", isSwitchedToBearish, ignoreFalseConditions, separator) + // // Fast Mid ... ToString("isFastOverMid", isFastOverMid, ignoreFalseConditions, separator) + ToString("isFastUnderMid", isFastUnderMid, ignoreFalseConditions, separator) + ToString("isFastCrossedOverMid", isFastCrossedOverMid, ignoreFalseConditions, separator) + ToString("isFastCrossedUnderMid", isFastCrossedUnderMid, ignoreFalseConditions, separator) + // // Fast Slow ... ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions, separator) + ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions, separator) + ToString("isFastCrossedOverSlow", isFastCrossedOverSlow, ignoreFalseConditions, separator) + ToString("isFastCrossedUnderSlow", isFastCrossedUnderSlow, ignoreFalseConditions, separator) + // // Mid Slow ... ToString("isMidOverSlow", isMidOverSlow, ignoreFalseConditions, separator) + ToString("isMidUnderSlow", isMidUnderSlow, ignoreFalseConditions, separator) + ToString("isMidCrossedOverSlow", isMidCrossedOverSlow, ignoreFalseConditions, separator) + ToString("isMidCrossedUnderSlow", isMidCrossedUnderSlow, ignoreFalseConditions, separator) + // // Psar ... ToString("isSARBullish", isSARBullish, ignoreFalseConditions, separator) + ToString("isSARBearish", isSARBearish, ignoreFalseConditions, separator) + ToString("isSARSwitchedToBullish", isSARSwitchedToBullish, ignoreFalseConditions, separator) + ToString("isSARSwitchedToBearish", isSARSwitchedToBearish, ignoreFalseConditions, separator) + // "" // ; // result = // "[" + GetTag() + "]" + separator + (onlyConditions ? "" : commonStr) + (!includeScores ? "" : scoresStr) + " " + separator + (onlyCommons ? "" : conditionsStr) + "" // ; // return result; } // string GetTag() { return "XMATD"; } }; // // Indicator Class ... class XSCXMATDHelper : public XSCBase { // // Public ... public: // // Props ... // // Constructor(s) ... void XSCXMATDHelper( string symbol, // Trading Symbol ENUM_TIMEFRAMES period // Trading TimeFrame ) { // mSymbol = symbol; mPeriod = period; } // // Deconstructor ... void ~XSCXMATDHelper() {} // // Initialize Indicator ... bool Init( XMATDInputs &inputs // Indicator Properties ) { // bool result = false; // result = inputs.IsValid(); if (!result) { return result; } // // Set Inputs ... this.mInputs = inputs; // // Validate Indicator State ... result = this.IsValid(); if (!result) { return result; } // result = DefineBuffers(); if (!result) { return result; } // fastHandler = iMA( mSymbol, mPeriod, mInputs.fastLength, mInputs.shift, mInputs.method, mInputs.appliedTo // ); midHandler = iMA( mSymbol, mPeriod, mInputs.midLength, mInputs.shift, mInputs.method, mInputs.appliedTo // ); slowHandler = iMA( mSymbol, mPeriod, mInputs.slowLength, mInputs.shift, mInputs.method, mInputs.appliedTo // ); result = // fastHandler != INVALID_HANDLE && midHandler != INVALID_HANDLE && slowHandler != INVALID_HANDLE // ; if (!result) { return result; } // sarHandler = iSAR( _Symbol, _Period, mInputs.step, mInputs.maximum // ); result = sarHandler != INVALID_HANDLE; // return result; } // XMATDInputs GetInputs() { return mInputs; } // bool SetInputs( XMATDInputs &inputs // Indicator Properties ) { return Init(inputs); } // // Get Tag ... string GetTag() { // string result = NULL; // result = GetToken(); // return result; } // // Get Token ... string GetToken() { // string result = NULL; // result = GetSpecificToken(this); // return result; } // string GetSymbol() { return mSymbol; } // ENUM_TIMEFRAMES GetPeriod() { return mPeriod; } // // Validate ... bool IsValid() { // bool result = false; // result = // mInputs.IsValid() && IsSpecifiedValid(mPeriod) && IsSpecifiedValid(mSymbol) // ; // return result; } // // De Initialize Class ... void DeInit(int reason) { // IndicatorRelease(fastHandler); IndicatorRelease(midHandler); IndicatorRelease(slowHandler); } // // Tools ... int CopyData( ENUM_XMATD_BUFFERS line, double &dest[], int start = 0, int count = 1 // ) { // int result = 0; // int mHandler = INVALID_HANDLE; switch (line) { // case XMATD_FAST_LINE: mHandler = fastHandler; break; // case XMATD_MID_LINE: mHandler = midHandler; break; // case XMATD_SLOW_LINE: mHandler = slowHandler; break; // case XMATD_PSAR_LINE: mHandler = sarHandler; break; } // if (mHandler == INVALID_HANDLE) { return result; } // result = CopyBuffer( mHandler, 0, start, count, dest // ); // return result; } // bool GetConditions( XMATDConditions &conditions, // int barIndex = 0, // int loopback = 3 // ) { // bool result = true; // if (loopback < 3) { loopback = 3; } // 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; // CopyData( XMATD_FAST_LINE, conditions.fast, zIndex, loopback // ); CopyData( XMATD_MID_LINE, conditions.mid, zIndex, loopback // ); CopyData( XMATD_SLOW_LINE, conditions.slow, zIndex, loopback // ); // // Calculate Conditions ... // // Trend ... // bool isBullish = conditions.fast[cIndex] > conditions.mid[cIndex] && conditions.mid[cIndex] > conditions.slow[cIndex]; bool isBearish = conditions.fast[cIndex] < conditions.mid[cIndex] && conditions.mid[cIndex] < conditions.slow[cIndex]; // bool isBullishPrev = conditions.fast[pIndex] > conditions.mid[pIndex] && conditions.mid[pIndex] > conditions.slow[pIndex]; bool isBearishPrev = conditions.fast[pIndex] < conditions.mid[pIndex] && conditions.mid[pIndex] < conditions.slow[pIndex]; // bool isSwitchedToBullish = isBullish && !isBullishPrev; bool isSwitchedToBearish = isBearish && !isBearishPrev; // // Set Conditions to Structure ... conditions.isBullish = isBullish; conditions.isBearish = isBearish; conditions.isSwitchedToBullish = isSwitchedToBullish; conditions.isSwitchedToBearish = isSwitchedToBearish; // // Fast Mid ... // bool isFastOverMid = conditions.fast[cIndex] > conditions.mid[cIndex]; bool isFastUnderMid = conditions.fast[cIndex] < conditions.mid[cIndex]; // bool isFastOverMidPrev = conditions.fast[pIndex] > conditions.mid[pIndex]; bool isFastUnderMidPrev = conditions.fast[pIndex] < conditions.mid[pIndex]; // bool isFastCrossedOverMid = isFastOverMid && !isFastOverMidPrev; bool isFastCrossedUnderMid = isFastUnderMid && !isFastUnderMidPrev; // conditions.isFastOverMid = isFastOverMid; conditions.isFastUnderMid = isFastUnderMid; conditions.isFastCrossedOverMid = isFastCrossedOverMid; conditions.isFastCrossedUnderMid = isFastCrossedUnderMid; // // Fast Slow ... // bool isFastOverSlow = conditions.fast[cIndex] > conditions.slow[cIndex]; bool isFastUnderSlow = conditions.fast[cIndex] < conditions.slow[cIndex]; // bool isFastOverSlowPrev = conditions.fast[pIndex] > conditions.slow[pIndex]; bool isFastUnderSlowPrev = conditions.fast[pIndex] < conditions.slow[pIndex]; // bool isFastCrossedOverSlow = isFastOverSlow && !isFastOverSlowPrev; bool isFastCrossedUnderSlow = isFastUnderSlow && !isFastUnderSlowPrev; // conditions.isFastOverSlow = isFastOverSlow; conditions.isFastUnderSlow = isFastUnderSlow; conditions.isFastCrossedOverSlow = isFastCrossedOverSlow; conditions.isFastCrossedUnderSlow = isFastCrossedUnderSlow; // // Mid Slow ... // bool isMidOverSlow = conditions.mid[cIndex] > conditions.slow[cIndex]; bool isMidUnderSlow = conditions.mid[cIndex] < conditions.slow[cIndex]; // bool isMidOverSlowPrev = conditions.mid[pIndex] > conditions.slow[pIndex]; bool isMidUnderSlowPrev = conditions.mid[pIndex] < conditions.slow[pIndex]; // bool isMidCrossedOverSlow = isMidOverSlow && !isMidOverSlowPrev; bool isMidCrossedUnderSlow = isMidUnderSlow && !isMidUnderSlowPrev; // conditions.isMidOverSlow = isMidOverSlow; conditions.isMidUnderSlow = isMidUnderSlow; conditions.isMidCrossedOverSlow = isMidCrossedOverSlow; conditions.isMidCrossedUnderSlow = isMidCrossedUnderSlow; // // PSar ... // CopyData( XMATD_PSAR_LINE, conditions.psar, zIndex, loopback // ); // XOHCL cBar; cBar.Init( mSymbol, mPeriod, cIndex // ); // XOHCL pBar; pBar.Init( mSymbol, mPeriod, pIndex // ); // bool isSARBullish = conditions.psar[cIndex] < cBar.low; bool isSARBearish = conditions.psar[cIndex] > cBar.high; // bool isSARBullishPrev = conditions.psar[pIndex] < pBar.low; bool isSARBearishPrev = conditions.psar[pIndex] > pBar.high; // bool isSARSwitchedToBullish = isSARBullish && !isSARBullishPrev; bool isSARSwitchedToBearish = isSARBearish && !isSARBearishPrev; // conditions.isSARBullish = isSARBullish; conditions.isSARBearish = isSARBearish; conditions.isSARSwitchedToBullish = isSARSwitchedToBullish; conditions.isSARSwitchedToBearish = isSARSwitchedToBearish; // return result; } // // Protected ... protected: // // Props ... int fastHandler; int midHandler; int slowHandler; // int sarHandler; // // Tools ... bool DefineBuffers() { // bool result = false; // result = true; // return result; } // // Private ... private: // // Props ... // string mSymbol; // Symbol ENUM_TIMEFRAMES mPeriod; // TimeFrame // XMATDInputs mInputs; // Properties }; //