/////////////////////////////////////////////////////// // SaherElm IT Center MQL5 Indicator // ------------------------------------------- // Name: XCHSwings // Description: XCHSwings Detector ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm XCHVWAP Indicator" #property strict // #define ShortName "XCHVWAP" // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5" // // Inputs ... // // Market ... input group "Market"; input int length = 12; // Length // input group "Cycles"; // input group "Short"; input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period // input group "Medium"; input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period // input group "Long"; input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period // input group "Hind"; input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period // // Presentation ... input group "Presentation"; // input bool showSwingHighs = true; // Show Swing Highs input bool showSwingLows = true; // Show Swing Lows // input bool showCurrent = true; // Show Cycle Cycle input bool showShort = true; // Show Short Cycle input bool showMedium = true; // Show Medium Cycle input bool showLong = true; // Show Long Cycle input bool showHind = true; // Show Hind Cycle // #property indicator_chart_window // #property indicator_buffers 10 #property indicator_plots 10 // #define hideColorIDX 0 #define bullishColorIDX 1 #define bearishColorIDX 2 // // Current ... // #define cSHBufferIndex 0 double cSHBuffer[]; // #property indicator_label1 "XCHVSwings CH" #property indicator_type1 DRAW_ARROW #property indicator_color1 clrMagenta #property indicator_style1 STYLE_SOLID #property indicator_width1 2 // #define cSLBufferIndex 1 double cSLBuffer[]; // #property indicator_label2 "XCHVSwings CL" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrAqua #property indicator_style2 STYLE_SOLID #property indicator_width2 2 // // Short ... // #define sSHBufferIndex 2 double sSHBuffer[]; // #property indicator_label3 "XCHVSwings SH" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrMagenta #property indicator_style3 STYLE_SOLID #property indicator_width3 2 // #define sSLBufferIndex 3 double sSLBuffer[]; // #property indicator_label4 "XCHVSwings SL" #property indicator_type4 DRAW_ARROW #property indicator_color4 clrAqua #property indicator_style4 STYLE_SOLID #property indicator_width4 2 // // Medium ... // #define mSHBufferIndex 4 double mSHBuffer[]; // #property indicator_label5 "XCHVSwings MH" #property indicator_type5 DRAW_ARROW #property indicator_color5 clrMagenta #property indicator_style5 STYLE_SOLID #property indicator_width5 2 // #define mSLBufferIndex 5 double mSLBuffer[]; // #property indicator_label6 "XCHVSwings ML" #property indicator_type6 DRAW_ARROW #property indicator_color6 clrAqua #property indicator_style6 STYLE_SOLID #property indicator_width6 2 // // Long ... // #define lSHBufferIndex 6 double lSHBuffer[]; // #property indicator_label7 "XCHVSwings LH" #property indicator_type7 DRAW_ARROW #property indicator_color7 clrMagenta #property indicator_style7 STYLE_SOLID #property indicator_width7 2 // #define lSLBufferIndex 7 double lSLBuffer[]; // #property indicator_label8 "XCHVSwings LL" #property indicator_type8 DRAW_ARROW #property indicator_color8 clrAqua #property indicator_style8 STYLE_SOLID #property indicator_width8 2 // // Hind ... // #define hSHBufferIndex 8 double hSHBuffer[]; // #property indicator_label9 "XCHVSwings HH" #property indicator_type9 DRAW_ARROW #property indicator_color9 clrMagenta #property indicator_style9 STYLE_SOLID #property indicator_width9 2 // #define hSLBufferIndex 9 double hSLBuffer[]; // #property indicator_label10 "XCHVSwings HL" #property indicator_type10 DRAW_ARROW #property indicator_color10 clrAqua #property indicator_style10 STYLE_SOLID #property indicator_width10 2 // // Variables ... // int maxLength; // // Cuurent ... int mCMarketLength = length; // double cH1 = 0; double cL1 = 0; datetime cH1Time = 0; datetime cL1Time = 0; // // Short ... int mSCycleLength = 0; int mSMarketLength = 0; ENUM_TIMEFRAMES mSCPeriod = NULL; // double sH1 = 0; double sL1 = 0; datetime sH1Time = 0; datetime sL1Time = 0; // // Medium ... int mMCycleLength = 0; int mMMarketLength = 0; ENUM_TIMEFRAMES mMCPeriod = NULL; // double mH1 = 0; double mL1 = 0; datetime mH1Time = 0; datetime mL1Time = 0; // // Long ... int mLCycleLength = 0; int mLMarketLength = 0; ENUM_TIMEFRAMES mLCPeriod = NULL; // double lH1 = 0; double lL1 = 0; datetime lH1Time = 0; datetime lL1Time = 0; // // Hind ... int mHCycleLength = 0; int mHMarketLength = 0; ENUM_TIMEFRAMES mHCPeriod = NULL; // double hH1 = 0; double hL1 = 0; datetime hH1Time = 0; datetime hL1Time = 0; // // Event Handlers ... // // Initialization ... int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // if (!InitMarketCycles()) { return INIT_PARAMETERS_INCORRECT; } // // because in some cases we may have more than one input for // calculation and we must prevent any calculation // untill we pass the biggest input length, here we get max Input length // and then wait until pass it ... maxLength = ExtractMaxLengthOfInputs(); // // Define Index Buffers ... DefineBuffers(); // // Set Indicator ShortName ... SetIndicatorName(); // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed } // // Calculating what we want ... int OnCalculate( const int rates_total, // Total Bars on Chart ... const int prev_calculated, // Total Calculated Bars on Charts ... const datetime &time[], // History of Open Time ... const double &open[], // History of Open Price ... const double &high[], // History of High Price ... const double &low[], // History of Low Price ... const double &close[], // History of Close Price ... const long &tick_volume[], // History of Tick Volumes on Bar ... const long &volume[], // History of Trade Volumes ... const int &spread[] // History of Spread Price ... ) { // int start; // if (prev_calculated == 0) { start = maxLength; } else { start = prev_calculated - 1; } // for (int i = start; i < rates_total - maxLength && !IsStopped(); i++) { // CalculateBuffers( i, prev_calculated, rates_total, // time, open, high, close, low, tick_volume // ); } // return rates_total; } // // Functions ... // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = false; // result = // length >= 2 && // (IsValid(scMethod, scPeriod) && IsValid(mcMethod, mcPeriod) && IsValid(lcMethod, lcPeriod) && IsValid(hcMethod, hcPeriod)) // ; // return result; } // // Initialize Market Cycles ... bool InitMarketCycles() { // bool result = false; // // Current Cycle Initialization ... // int cPeriodSeconds = PeriodSeconds(_Period); // // Short Cycle Initialization ... // // Find Cycle Period ... if (scMethod == X_PERIOD_AUTO) { // // Select Period ... mSCPeriod = GetCyclePeriod( X_MARKET_CYCLE_SHORT, _Period // ); } else { mSCPeriod = scPeriod; } // result = IsValid(mSCPeriod); if (!result) { return result; } // mSCycleLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; mSMarketLength = mSCycleLength * mCMarketLength; result = mSCycleLength > 0; if (!result) { return result; } // // Medium Cycle Initialization ... // // Find Cycle Period ... if (mcMethod == X_PERIOD_AUTO) { // // Select Period ... mMCPeriod = GetCyclePeriod( X_MARKET_CYCLE_MEDIUM, _Period // ); } else { mMCPeriod = mcPeriod; } // result = IsValid(mMCPeriod); if (!result) { return result; } // mMCycleLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; mMMarketLength = mMCycleLength * mCMarketLength; result = mMCycleLength > 0; if (!result) { return result; } // // Long Cycle Initialization ... // // Find Cycle Period ... if (lcMethod == X_PERIOD_AUTO) { // // Select Period ... mLCPeriod = GetCyclePeriod( X_MARKET_CYCLE_LONG, _Period // ); } else { mLCPeriod = lcPeriod; } // result = IsValid(mLCPeriod); if (!result) { return result; } // mLCycleLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; mLMarketLength = mLCycleLength * mCMarketLength; result = mLCycleLength > 0; if (!result) { return result; } // // Hind Cycle Initialization ... // // Find Cycle Period ... if (hcMethod == X_PERIOD_AUTO) { // // Select Period ... mHCPeriod = GetCyclePeriod( X_MARKET_CYCLE_HIND, _Period // ); } else { mHCPeriod = hcPeriod; } // result = IsValid(mHCPeriod); if (!result) { return result; } // mHCycleLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; mHMarketLength = mHCycleLength * mCMarketLength; result = mHCycleLength > 0; if (!result) { return result; } // return result; } // // Retrieve all Exists Input Max Length ... // use for Start Of Drawing ... int ExtractMaxLengthOfInputs() { // int result = 0; // result = MathMax(mCMarketLength, mSMarketLength); result = MathMax(result, mMMarketLength); result = MathMax(result, mLMarketLength); result = MathMax(result, mHMarketLength); // return result; } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { // IndicatorSetString(INDICATOR_SHORTNAME, ShortName); // Setting Indicator Digits IndicatorSetInteger(INDICATOR_DIGITS, _Digits); } // // Define Indexes and Styles ... void DefineBuffers() { // // Current ... // ENUM_DRAW_TYPE cSHDrawType = showCurrent && showSwingHighs ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(cSHBufferIndex, cSHBuffer, INDICATOR_DATA); PlotIndexSetDouble(cSHBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(cSHBufferIndex, PLOT_ARROW, 234); PlotIndexSetInteger(cSHBufferIndex, PLOT_SHOW_DATA, showCurrent && showSwingHighs); PlotIndexSetInteger(cSHBufferIndex, PLOT_DRAW_TYPE, cSHDrawType); // ENUM_DRAW_TYPE cSLDrawType = showCurrent && showSwingLows ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(cSLBufferIndex, cSLBuffer, INDICATOR_DATA); PlotIndexSetDouble(cSLBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(cSLBufferIndex, PLOT_ARROW, 233); PlotIndexSetInteger(cSLBufferIndex, PLOT_SHOW_DATA, showCurrent && showSwingLows); PlotIndexSetInteger(cSLBufferIndex, PLOT_DRAW_TYPE, cSLDrawType); // // Short ... // ENUM_DRAW_TYPE sSHDrawType = showShort && showSwingHighs ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(sSHBufferIndex, sSHBuffer, INDICATOR_DATA); PlotIndexSetDouble(sSHBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(sSHBufferIndex, PLOT_ARROW, 234); PlotIndexSetInteger(sSHBufferIndex, PLOT_SHOW_DATA, showShort && showSwingHighs); PlotIndexSetInteger(sSHBufferIndex, PLOT_DRAW_TYPE, sSHDrawType); // ENUM_DRAW_TYPE sSLDrawType = showShort && showSwingLows ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(sSLBufferIndex, sSLBuffer, INDICATOR_DATA); PlotIndexSetDouble(sSLBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(sSLBufferIndex, PLOT_ARROW, 233); PlotIndexSetInteger(sSLBufferIndex, PLOT_SHOW_DATA, showShort && showSwingLows); PlotIndexSetInteger(sSLBufferIndex, PLOT_DRAW_TYPE, sSLDrawType); // // Medium ... // ENUM_DRAW_TYPE mSHDrawType = showMedium && showSwingHighs ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(mSHBufferIndex, mSHBuffer, INDICATOR_DATA); PlotIndexSetDouble(mSHBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(mSHBufferIndex, PLOT_ARROW, 234); PlotIndexSetInteger(mSHBufferIndex, PLOT_SHOW_DATA, showMedium && showSwingHighs); PlotIndexSetInteger(mSHBufferIndex, PLOT_DRAW_TYPE, mSHDrawType); // ENUM_DRAW_TYPE mSLDrawType = showMedium && showSwingLows ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(mSLBufferIndex, mSLBuffer, INDICATOR_DATA); PlotIndexSetDouble(mSLBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(mSLBufferIndex, PLOT_ARROW, 233); PlotIndexSetInteger(mSLBufferIndex, PLOT_SHOW_DATA, showMedium && showSwingLows); PlotIndexSetInteger(mSLBufferIndex, PLOT_DRAW_TYPE, mSLDrawType); // // Long ... // ENUM_DRAW_TYPE lSHDrawType = showLong && showSwingHighs ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(lSHBufferIndex, lSHBuffer, INDICATOR_DATA); PlotIndexSetDouble(lSHBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(lSHBufferIndex, PLOT_ARROW, 234); PlotIndexSetInteger(lSHBufferIndex, PLOT_SHOW_DATA, showLong && showSwingHighs); PlotIndexSetInteger(lSHBufferIndex, PLOT_DRAW_TYPE, lSHDrawType); // ENUM_DRAW_TYPE lSLDrawType = showLong && showSwingLows ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(lSLBufferIndex, lSLBuffer, INDICATOR_DATA); PlotIndexSetDouble(lSLBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(lSLBufferIndex, PLOT_ARROW, 233); PlotIndexSetInteger(lSLBufferIndex, PLOT_SHOW_DATA, showLong && showSwingLows); PlotIndexSetInteger(lSLBufferIndex, PLOT_DRAW_TYPE, lSLDrawType); // // Hind ... // ENUM_DRAW_TYPE hSHDrawType = showHind && showSwingHighs ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(hSHBufferIndex, hSHBuffer, INDICATOR_DATA); PlotIndexSetDouble(hSHBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(hSHBufferIndex, PLOT_ARROW, 234); PlotIndexSetInteger(hSHBufferIndex, PLOT_SHOW_DATA, showHind && showSwingHighs); PlotIndexSetInteger(hSHBufferIndex, PLOT_DRAW_TYPE, hSHDrawType); // ENUM_DRAW_TYPE hSLDrawType = showHind && showSwingLows ? DRAW_ARROW : DRAW_NONE; // SetIndexBuffer(hSLBufferIndex, hSLBuffer, INDICATOR_DATA); PlotIndexSetDouble(hSLBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(hSLBufferIndex, PLOT_ARROW, 233); PlotIndexSetInteger(hSLBufferIndex, PLOT_SHOW_DATA, showHind && showSwingLows); PlotIndexSetInteger(hSLBufferIndex, PLOT_DRAW_TYPE, hSLDrawType); } // // Calculations ... // // Calculate Buffers ... void CalculateBuffers( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, // const datetime &time[], const double &open[], const double &high[], const double &close[], const double &low[], const long &tickVolume[] // ) { // CalculateCycles( // bar_index, prevCalculated, ratesTotal, // time, open, high, close, low, tickVolume // ); } // void CalculateCycles( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, // const datetime &time[], const double &open[], const double &high[], const double &close[], const double &low[], const long &tickVolume[] // ) { // // CURRENT ... CalculateCycle( bar_index, prevCalculated, ratesTotal, // time, open, high, close, low, tickVolume, // mCMarketLength, showCurrent, cSHBuffer, cSLBuffer, cH1, cH1Time, cL1, cL1Time // ); // // SHORT ... CalculateCycle( bar_index, prevCalculated, ratesTotal, // time, open, high, close, low, tickVolume, // mSMarketLength, showShort, sSHBuffer, sSLBuffer, sH1, sH1Time, sL1, sL1Time // ); // // MEDIUM ... CalculateCycle( bar_index, prevCalculated, ratesTotal, // time, open, high, close, low, tickVolume, // mMMarketLength, showMedium, mSHBuffer, mSLBuffer, mH1, mH1Time, mL1, mL1Time // ); // // LONG ... CalculateCycle( bar_index, prevCalculated, ratesTotal, // time, open, high, close, low, tickVolume, // mLMarketLength, showLong, lSHBuffer, lSLBuffer, lH1, lH1Time, lL1, lL1Time // ); // // HIND ... CalculateCycle( bar_index, prevCalculated, ratesTotal, // time, open, high, close, low, tickVolume, // mHMarketLength, showHind, hSHBuffer, hSLBuffer, hH1, hH1Time, hL1, hL1Time // ); } // void CalculateCycle( // int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, // const datetime &time[], const double &open[], const double &high[], const double &close[], const double &low[], const long &tickVolume[], // int _length, // Calculation Length bool _show, double &_hBuffer[], double &_lBuffer[], double &_h1, datetime &_h1Time, double &_l1, datetime &_l1Time // ) { // bool isSwingHigh = true; bool isSwingLow = true; // _hBuffer[bar_index] = 0; _lBuffer[bar_index] = 0; // // Check for Swing High for (int j = 1; j <= _length; j++) { // if (high[bar_index] <= high[bar_index + j] || high[bar_index] <= high[bar_index - j]) { // isSwingHigh = false; break; } } // // Check for Swing Low for (int j = 1; j <= _length; j++) { // if (low[bar_index] >= low[bar_index + j] || low[bar_index] >= low[bar_index - j]) { // isSwingLow = false; break; } } // if (isSwingHigh) { // _hBuffer[bar_index] = high[bar_index]; if (high[bar_index] > _h1 || _h1 == 0) { // _h1 = high[bar_index]; _h1Time = time[bar_index]; } } // if (isSwingLow) { // _lBuffer[bar_index] = low[bar_index]; if (low[bar_index] < _l1 || _l1 == 0) { // _l1 = low[bar_index]; _l1Time = time[bar_index]; } } }