///////////////////////////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 XTS Oscillator Helper for Signal Providers // -------------------------------------------------------------------------- // // 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 "../Libraries/x-saherelm.log.lib.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // // START Enum Definitions ... // // // Methods to Calculate TimeFrames ... enum ENUM_X_PERIOD_METHOD { // X_PERIOD_NOTHING, // X_PERIOD_AUTO, // X_PERIOD_MANUALLY }; // // Buffer Lines ... enum ENUM_X_XTS_BUFFER_LINES { X_XTS_CURRENT_LINE = 0, X_XTS_NEAREST_LINE = 1, X_XTS_MEDIEST_LINE = 2, X_XTS_FAREST_LINE = 3, }; // // Periods ... enum ENUM_X_XTS_PERIODS { // // Current Period ... X_XTS_PERIOD_CURRENT, // // Nearest Period ... X_XTS_PERIOD_NEAREST, // // Mediest Period ... X_XTS_PERIOD_MEDIEST, // // Farest Period ... X_XTS_PERIOD_FAREST, }; // // END Enum Definitions ... // // // START Inputs ... // // // // input group "XTS Oscillator"; // // // input group "XTS Current Period"; // input ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To // // // input group "XTS Nearest Period"; // input ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period // input ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame // input ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To // // // input group "XTS Mediest Period"; // input ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period // input ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame // input ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To // // // input group "XTS Farest Period"; // input ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period // input ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame // input ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To // // Configurations ... ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To // ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To // ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To // ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To // // END Inputs ... // // // START Definitions ... // int xTSHandler = INVALID_HANDLE; double xTSCurrentBuffer[]; double xTSNearestBuffer[]; double xTSMediestBuffer[]; double xTSFarestBuffer[]; // // END Definitions ... // // // START Handler Functions ... // // // Validate Inputs ... bool XTSValidateInputs() { // bool result = false; // result = true; // if (!result) { // LogMessage("XTS Oscillator Inputs Validation Failed ..."); } // return result; } // // Init Oscillators ... bool XTSInitHandlers() { // bool result = false; // // Initialize Indicator/Oscillator Handlers ... ResetLastError(); // // XTS Handler ... ArraySetAsSeries(xTSCurrentBuffer, true); ArraySetAsSeries(xTSNearestBuffer, true); ArraySetAsSeries(xTSMediestBuffer, true); ArraySetAsSeries(xTSFarestBuffer, true); xTSHandler = iCustom( _Symbol, _Period, "x-saherelm.xts.oscillator", // // Inputs ... "", xTSCurrentAppliedTo, "", xTSNearestMethod, xTSNearestPeriod, xTSNearestAppliedTo, "", xTSMediestMethod, xTSMediestPeriod, xTSMediestAppliedTo, "", xTSFarestMethod, xTSFarestPeriod, xTSFarestAppliedTo // ); if (xTSHandler == INVALID_HANDLE) { // LogMessage("failed to Initialize XTS Oscillator: " + (string)GetLastError()); return result; } // result = true; // return result; } // // Release Oscillators ... void XTSReleaseHandlers() { IndicatorRelease(xTSHandler); } // // Handle Reading Buffers ... void XTSReadBuffers( int xTSItemsPerTick // Number Of Reading Buffer Items Per Tick ) { // // XTS Current ... CopyBuffer( xTSHandler, X_XTS_CURRENT_LINE, 0, xTSItemsPerTick, xTSCurrentBuffer); // // XTS Nearest ... CopyBuffer( xTSHandler, X_XTS_NEAREST_LINE, 0, xTSItemsPerTick, xTSNearestBuffer); // // XTS Mediest ... CopyBuffer( xTSHandler, X_XTS_MEDIEST_LINE, 0, xTSItemsPerTick, xTSMediestBuffer); // // XTS Farest ... CopyBuffer( xTSHandler, X_XTS_FAREST_LINE, 0, xTSItemsPerTick, xTSFarestBuffer); } // // END Handler Funcions ... // // // START XTS Custom Functions ... // // // Calculate Min Value ... double XTSGetMinValue( int bar_index // Specified Index ... ) { // ENUM_X_XTS_PERIODS periods[]; XTSGetAllPeriodsEnum(periods); // double result = XTSGetPeriodsMinValue( periods, bar_index); // return result; } // // Calculate Max Value ... double XTSGetMaxValue( int bar_index // Specified Index ... ) { // ENUM_X_XTS_PERIODS periods[]; XTSGetAllPeriodsEnum(periods); // double result = XTSGetPeriodsMaxValue( periods, bar_index); // return result; } // // Check if all Periods Values are Same ... bool XTSIsAllSame( int bar_index // Specified Index ... ) { // bool result = false; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // result = xTSCurrentBuffer[bar_index] == xTSNearestBuffer[bar_index] && xTSNearestBuffer[bar_index] == xTSMediestBuffer[bar_index] && xTSMediestBuffer[bar_index] == xTSFarestBuffer[bar_index]; // return result; } // // Current ... // // Check Current Buffer is Min Or Not ... bool XTSIsCurrentMin( int bar_index // Specified Index ... ) { // bool result = false; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // double minValue = XTSGetMinValue(bar_index); // result = xTSCurrentBuffer[bar_index] == minValue; // return result; } // // Check Current Buffer is Max Or Not ... bool XTSIsCurrentMax( int bar_index // Specified Index ... ) { // bool result = false; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // double maxValue = XTSGetMaxValue(bar_index); // result = xTSCurrentBuffer[bar_index] == maxValue; // return result; } // // Current VS Nearest ... // // Check Current Crossed Over Nearest ... bool XTSIsCurrentCrossedOverNearest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodCrossedOverAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_NEAREST, bar_index); // return result; } // // Check Current Over Nearest ... bool XTSIsCurrentOverNearest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodOverAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_NEAREST, bar_index); // return result; } // // Check Current Crossed Under Nearest ... bool XTSIsCurrentCrossedUnderNearest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodCrossedUnderAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_NEAREST, bar_index); // return result; } // // Check Current Under Nearest ... bool XTSIsCurrentUnderNearest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodUnderAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_NEAREST, bar_index); // return result; } // // Current VS Mediest ... // // Check Current Crossed Over Mediest ... bool XTSIsCurrentCrossedOverMediest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodCrossedOverAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_MEDIEST, bar_index); // return result; } // // Check Current Over Mediest ... bool XTSIsCurrentOverMediest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodOverAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_MEDIEST, bar_index); // return result; } // // Check Current Crossed Under Mediest ... bool XTSIsCurrentCrossedUnderMediest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodCrossedUnderAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_MEDIEST, bar_index); // return result; } // // Check Current Under Mediest ... bool XTSIsCurrentUnderMediest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodUnderAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_MEDIEST, bar_index); // return result; } // // Current VS Farest ... // // Check Current Crossed Over Farest ... bool XTSIsCurrentCrossedOverFarest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodCrossedOverAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_FAREST, bar_index); // return result; } // // Check Current Over Farest ... bool XTSIsCurrentOverFarest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodOverAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_FAREST, bar_index); // return result; } // // Check Current Crossed Under Farest ... bool XTSIsCurrentCrossedUnderFarest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodCrossedUnderAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_FAREST, bar_index); // return result; } // // Check Current Under Farest ... bool XTSIsCurrentUnderFarest( int bar_index // Specified Index ... ) { // bool result = false; // result = XTSIsPeriodUnderAnother( X_XTS_PERIOD_CURRENT, X_XTS_PERIOD_FAREST, bar_index); // return result; } // // Globally Custom Functions ... // // Check a Period Crossed Over another one ... bool XTSIsPeriodCrossedOverAnother( ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... int bar_index // Specified Index ... ) { // bool result = false; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 2)) { return result; } // double sourceValue = XTSGetPeriodValue( source, bar_index); double sourceValue1 = XTSGetPeriodValue( source, bar_index + 1); // double destValue = XTSGetPeriodValue( dest, bar_index); double destValue1 = XTSGetPeriodValue( dest, bar_index + 1); // result = sourceValue > destValue && sourceValue1 <= destValue1; // return result; } // // Check a Period Over another one ... bool XTSIsPeriodOverAnother( ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... int bar_index // Specified Index ... ) { // bool result = false; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // double sourceValue = XTSGetPeriodValue( source, bar_index); // double destValue = XTSGetPeriodValue( dest, bar_index); // result = sourceValue > destValue; // return result; } // // Check a Period Crossed Under another one ... bool XTSIsPeriodCrossedUnderAnother( ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... int bar_index // Specified Index ... ) { // bool result = false; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 2)) { return result; } // double sourceValue = XTSGetPeriodValue( source, bar_index); double sourceValue1 = XTSGetPeriodValue( source, bar_index + 1); // double destValue = XTSGetPeriodValue( dest, bar_index); double destValue1 = XTSGetPeriodValue( dest, bar_index + 1); // result = sourceValue < destValue && sourceValue1 >= destValue1; // return result; } // // Check a Period Under another one ... bool XTSIsPeriodUnderAnother( ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... int bar_index // Specified Index ... ) { // bool result = false; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // double sourceValue = XTSGetPeriodValue( source, bar_index); // double destValue = XTSGetPeriodValue( dest, bar_index); // result = sourceValue < destValue; // return result; } // // Retrieve Specific Period's Value from Buffer for Specific Bar Index ... double XTSGetPeriodValue( ENUM_X_XTS_PERIODS period, // Specified Period to read it's Value ... int bar_index // Specified Index ... ) { // double result = 0; // // Validate Args ... if ( bar_index < 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // switch (period) { // case X_XTS_PERIOD_CURRENT: result = xTSCurrentBuffer[bar_index]; break; // case X_XTS_PERIOD_NEAREST: result = xTSNearestBuffer[bar_index]; break; // case X_XTS_PERIOD_MEDIEST: result = xTSMediestBuffer[bar_index]; break; // case X_XTS_PERIOD_FAREST: result = xTSFarestBuffer[bar_index]; break; } // return result; } // // Fill All Exists Periods ... void XTSGetAllPeriodsEnum( ENUM_X_XTS_PERIODS &result[] // Hold's Result ... ) { // CleanBuffer(result); // Add( X_XTS_PERIOD_CURRENT, result); // Add( X_XTS_PERIOD_NEAREST, result); // Add( X_XTS_PERIOD_MEDIEST, result); // Add( X_XTS_PERIOD_FAREST, result); } // // Fill All Exists Periods Except ... void XTSGetAllPeriodsEnumExcept( ENUM_X_XTS_PERIODS &result[], // Hold's Result ... ENUM_X_XTS_PERIODS exception // Excepted Period ... ) { // CleanBuffer(result); // ENUM_X_XTS_PERIODS allPeriods[]; XTSGetAllPeriodsEnum(allPeriods); int periodsCount = ArraySize(allPeriods); if (periodsCount <= 0) { return; } // // Loop ... for (int i = 0; i < periodsCount; i++) { // ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; // if (iPeriod != exception) { Add( iPeriod, result); } } } // // Fill All Exists Periods Except ... void XTSGetAllPeriodsEnumExcept( ENUM_X_XTS_PERIODS &result[], // Hold's Result ... ENUM_X_XTS_PERIODS &exceptions[] // Excepted Periods ... ) { // CleanBuffer(result); // ENUM_X_XTS_PERIODS allPeriods[]; XTSGetAllPeriodsEnum(allPeriods); int periodsCount = ArraySize(allPeriods); if (periodsCount <= 0) { return; } // int exceptionsCount = ArraySize(exceptions); // // Loop ... for (int i = 0; i < periodsCount; i++) { // ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; // bool canAddIPeriod = false; if (exceptionsCount <= 0) { canAddIPeriod = true; } else { // // Loop through Exceptions ... for (int j = 0; j < exceptionsCount; j++) { // ENUM_X_XTS_PERIODS jException = exceptions[j]; // if (iPeriod == jException) { // canAddIPeriod = false; break; } // canAddIPeriod = true; } } // if (canAddIPeriod) { // Add( iPeriod, result); } } } // // Calculate Periods Min Value ... double XTSGetPeriodsMinValue( ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... int bar_index // Specified Index ... ) { // double result = 0; // int periodsCount = ArraySize(periods); // // Validate Args ... if ( bar_index < 0 || periodsCount <= 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // // Loop ... for (int i = 0; i < periodsCount; i++) { // ENUM_X_XTS_PERIODS iPeriod = periods[i]; // double iValue = 0; // switch (iPeriod) { // case X_XTS_PERIOD_CURRENT: iValue = xTSCurrentBuffer[bar_index]; break; // case X_XTS_PERIOD_NEAREST: iValue = xTSNearestBuffer[bar_index]; break; // case X_XTS_PERIOD_MEDIEST: iValue = xTSMediestBuffer[bar_index]; break; // case X_XTS_PERIOD_FAREST: iValue = xTSFarestBuffer[bar_index]; break; } // // Compare iValue to result ... result = result == 0 || result > iValue ? iValue : result; } // return result; } // // Calculate Periods Max Value ... double XTSGetPeriodsMaxValue( ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... int bar_index // Specified Index ... ) { // double result = 0; // int periodsCount = ArraySize(periods); // // Validate Args ... if ( bar_index < 0 || periodsCount <= 0 || !XTSIsValidBuffersSize(bar_index + 1)) { return result; } // // Loop ... for (int i = 0; i < periodsCount; i++) { // ENUM_X_XTS_PERIODS iPeriod = periods[i]; // double iValue = 0; // switch (iPeriod) { // case X_XTS_PERIOD_CURRENT: iValue = xTSCurrentBuffer[bar_index]; break; // case X_XTS_PERIOD_NEAREST: iValue = xTSNearestBuffer[bar_index]; break; // case X_XTS_PERIOD_MEDIEST: iValue = xTSMediestBuffer[bar_index]; break; // case X_XTS_PERIOD_FAREST: iValue = xTSFarestBuffer[bar_index]; break; } // // Compare iValue to result ... result = result == 0 || result < iValue ? iValue : result; } // return result; } // // Check all Buffers has valid Size ... bool XTSIsValidBuffersSize( int size // the size of buffers which min size for requirements ) { // bool result = false; // if ( size <= 0 || // ArraySize(xTSCurrentBuffer) < size // ) { result = false; } else { result = true; } // return result; } // void Add( ENUM_X_XTS_PERIODS item, // Specified Item ... ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... ) { // int bufferSize = ArraySize(buffer); // ArrayResize( buffer, bufferSize + 1); // buffer[bufferSize] = item; } void CleanBuffer( ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... ) { // ArrayFree(buffer); ArrayResize(buffer, 0); } // // END XTS Custom Functions ... //