/////////////////////////////////////////////////////// // SaherElm IT Center MQL5 Indicator // ------------------------------------------- // Name: XCHHK // Description: Smoothed HikenAshi Cycles ... // // 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 XCHHK Indicator" #property strict // #define ShortName "XCHHK" // // Includes Common Library ... #include #include "../Libraries/x-saherelm.common.lib.mq5" // // Inputs ... // input group "Market"; // input int cSmoothingLength = 14; // Smoothing 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 ignoreShadows = false; // Ignore Bar Shadows // input bool showCurrent = true; // Show Current 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 // // Buffers ... // #define hideColorIDX 0 #define bullishColorIDX 1 #define bearishColorIDX 2 // #property indicator_chart_window // #property indicator_buffers 29 #property indicator_plots 25 // // Current ... // #define cOpenBufferIndex 0 double cOpenBuffer[]; // #define cHighBufferIndex 1 double cHighBuffer[]; // #define cLowBufferIndex 2 double cLowBuffer[]; // #define cCloseBufferIndex 3 double cCloseBuffer[]; // #define cColorBufferIndex 4 double cColorBuffer[]; // #define cBufferIndex 0 #property indicator_label1 "C Open;C High;C Low;C Close" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 CLR_NONE, clrAqua, clrMagenta // // Short ... // #define sOpenBufferIndex 5 double sOpenBuffer[]; // #define sHighBufferIndex 6 double sHighBuffer[]; // #define sLowBufferIndex 7 double sLowBuffer[]; // #define sCloseBufferIndex 8 double sCloseBuffer[]; // #define sColorBufferIndex 9 double sColorBuffer[]; // #define sBufferIndex 1 #property indicator_label2 "S Open;S High;S Low;S Close" #property indicator_type2 DRAW_COLOR_CANDLES #property indicator_color2 CLR_NONE, clrAqua, clrMagenta // // Medium ... // #define mOpenBufferIndex 10 double mOpenBuffer[]; // #define mHighBufferIndex 11 double mHighBuffer[]; // #define mLowBufferIndex 12 double mLowBuffer[]; // #define mCloseBufferIndex 13 double mCloseBuffer[]; // #define mColorBufferIndex 14 double mColorBuffer[]; // #define mBufferIndex 2 #property indicator_label3 "M Open;M High;M Low;M Close" #property indicator_type3 DRAW_COLOR_CANDLES #property indicator_color3 CLR_NONE, clrAqua, clrMagenta // // Long ... // #define lOpenBufferIndex 15 double lOpenBuffer[]; // #define lHighBufferIndex 16 double lHighBuffer[]; // #define lLowBufferIndex 17 double lLowBuffer[]; // #define lCloseBufferIndex 18 double lCloseBuffer[]; // #define lColorBufferIndex 19 double lColorBuffer[]; // #define lBufferIndex 3 #property indicator_label4 "L Open;L High;L Low;L Close" #property indicator_type4 DRAW_COLOR_CANDLES #property indicator_color4 CLR_NONE, clrAqua, clrMagenta // // Hind ... // #define hOpenBufferIndex 20 double hOpenBuffer[]; // #define hHighBufferIndex 21 double hHighBuffer[]; // #define hLowBufferIndex 22 double hLowBuffer[]; // #define hCloseBufferIndex 23 double hCloseBuffer[]; // #define hColorBufferIndex 24 double hColorBuffer[]; // #define hBufferIndex 4 #property indicator_label5 "H Open;H High;H Low;H Close" #property indicator_type5 DRAW_COLOR_CANDLES #property indicator_color5 CLR_NONE, clrAqua, clrMagenta // // Data Buffers ... // #define openBufferIndex 25 double openBuffer[]; // #define highBufferIndex 26 double highBuffer[]; // #define lowBufferIndex 27 double lowBuffer[]; // #define closeBufferIndex 28 double closeBuffer[]; // // Variables, Properties and etc ... // int maxLength; // // Current ... int mCSMLength = cSmoothingLength; // // Short ... int mSCLength = 0; int mSSMLength = 0; ENUM_TIMEFRAMES mSCPeriod = NULL; // // Medium ... int mMCLength = 0; int mMSMLength = 0; ENUM_TIMEFRAMES mMCPeriod = NULL; // // Long ... int mLCLength = 0; int mLSMLength = 0; ENUM_TIMEFRAMES mLCPeriod = NULL; // // Hind ... int mHCLength = 0; int mHSMLength = 0; ENUM_TIMEFRAMES mHCPeriod = NULL; // // 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 ... ) { // // Prepare Buffers ... ArraySetAsSeries(time, true); ArraySetAsSeries(open, true); ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(close, true); ArraySetAsSeries(tick_volume, true); ArraySetAsSeries(volume, true); ArraySetAsSeries(spread, true); // // this counts Available Bars ... int limit; // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Main Loop ... for (int i = limit - 1; i >= 0 && !IsStopped(); i--) { CalculateHK(i, prev_calculated, rates_total, open, high, close, low); } // CalculateCycles(rates_total, prev_calculated); // return rates_total; } // // Functions ... // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = false; // result = // cSmoothingLength > 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; } // mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; mSSMLength = mSCLength * mCSMLength; result = mSCLength > 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; } // mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; mMSMLength = mMCLength * mCSMLength; result = mMCLength > 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; } // mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; mLSMLength = mLCLength * mCSMLength; result = mLCLength > 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; } // mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; mHSMLength = mHCLength * mCSMLength; result = mHCLength > 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(mCSMLength, mSSMLength); result = MathMax(result, mMSMLength); result = MathMax(result, mLSMLength); result = MathMax(result, mHSMLength); // return result; } // // Define Indexes and Styles ... void DefineBuffers() { // // Data Buffers ... // // Open ... ArraySetAsSeries(openBuffer, true); SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_CALCULATIONS); // // High ... ArraySetAsSeries(highBuffer, true); SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_CALCULATIONS); // // Low ... ArraySetAsSeries(lowBuffer, true); SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_CALCULATIONS); // // Close ... ArraySetAsSeries(closeBuffer, true); SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_CALCULATIONS); // // Current ... // // Color ... ArraySetAsSeries(cColorBuffer, true); SetIndexBuffer(cColorBufferIndex, cColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on Bar Buffer ... PlotIndexSetDouble(cBufferIndex, PLOT_EMPTY_VALUE, 0.0); // PlotIndexSetInteger(cBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(cColorBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(cOpenBuffer, true); PlotIndexSetInteger(cOpenBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(cOpenBufferIndex, cOpenBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(cHighBuffer, true); PlotIndexSetInteger(cHighBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(cHighBufferIndex, cHighBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(cCloseBuffer, true); PlotIndexSetInteger(cCloseBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(cCloseBufferIndex, cCloseBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(cLowBuffer, true); PlotIndexSetInteger(cLowBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(cLowBufferIndex, cLowBuffer, INDICATOR_DATA); // // Short ... // // Color ... ArraySetAsSeries(sColorBuffer, true); SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on Bar Buffer ... PlotIndexSetDouble(sBufferIndex, PLOT_EMPTY_VALUE, 0.0); // PlotIndexSetInteger(sBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(sColorBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(sOpenBuffer, true); PlotIndexSetInteger(sOpenBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(sOpenBufferIndex, sOpenBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(sHighBuffer, true); PlotIndexSetInteger(sHighBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(sHighBufferIndex, sHighBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(sCloseBuffer, true); PlotIndexSetInteger(sCloseBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(sCloseBufferIndex, sCloseBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(sLowBuffer, true); PlotIndexSetInteger(sLowBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(sLowBufferIndex, sLowBuffer, INDICATOR_DATA); // // Medium ... // // Color ... ArraySetAsSeries(mColorBuffer, true); SetIndexBuffer(mColorBufferIndex, mColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on Bar Buffer ... PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0.0); // PlotIndexSetInteger(mBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(mColorBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(mOpenBuffer, true); PlotIndexSetInteger(mOpenBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(mOpenBufferIndex, mOpenBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(mHighBuffer, true); PlotIndexSetInteger(mHighBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(mHighBufferIndex, mHighBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(mCloseBuffer, true); PlotIndexSetInteger(mCloseBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(mCloseBufferIndex, mCloseBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(mLowBuffer, true); PlotIndexSetInteger(mLowBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(mLowBufferIndex, mLowBuffer, INDICATOR_DATA); // // Long ... // // Color ... ArraySetAsSeries(lColorBuffer, true); SetIndexBuffer(lColorBufferIndex, lColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on Bar Buffer ... PlotIndexSetDouble(lBufferIndex, PLOT_EMPTY_VALUE, 0.0); // PlotIndexSetInteger(lBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(lColorBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(lOpenBuffer, true); PlotIndexSetInteger(lOpenBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(lOpenBufferIndex, lOpenBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(lHighBuffer, true); PlotIndexSetInteger(lHighBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(lHighBufferIndex, lHighBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(lCloseBuffer, true); PlotIndexSetInteger(lCloseBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(lCloseBufferIndex, lCloseBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(lLowBuffer, true); PlotIndexSetInteger(lLowBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(lLowBufferIndex, lLowBuffer, INDICATOR_DATA); // // Hind ... // // Color ... ArraySetAsSeries(hColorBuffer, true); SetIndexBuffer(hColorBufferIndex, hColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on Bar Buffer ... PlotIndexSetDouble(hBufferIndex, PLOT_EMPTY_VALUE, 0.0); // PlotIndexSetInteger(hBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(hColorBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(hOpenBuffer, true); PlotIndexSetInteger(hOpenBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(hOpenBufferIndex, hOpenBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(hHighBuffer, true); PlotIndexSetInteger(hHighBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(hHighBufferIndex, hHighBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(hCloseBuffer, true); PlotIndexSetInteger(hCloseBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(hCloseBufferIndex, hCloseBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(hLowBuffer, true); PlotIndexSetInteger(hLowBufferIndex, PLOT_SHOW_DATA, false); SetIndexBuffer(hLowBufferIndex, hLowBuffer, INDICATOR_DATA); } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } // // Calculations ... // // Calculate Hiken Ashi ... void CalculateHK( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, const double &open[], const double &high[], const double &close[], const double &low[] // ) { // double mPrevHKOpenValue; double mPrevHKCloseValue; // if (ArraySize(open) <= bar_index + 1) { // mPrevHKOpenValue = 0; mPrevHKCloseValue = 0; } else { // mPrevHKOpenValue = openBuffer[bar_index + 1]; mPrevHKCloseValue = closeBuffer[bar_index + 1]; } // double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); // openBuffer[bar_index] = mHKOpenValue; highBuffer[bar_index] = mHKHighValue; lowBuffer[bar_index] = mHKLowValue; closeBuffer[bar_index] = mHKCloseValue; } // void CalculateCycles( int ratesTotal, // Total Bars int prevCalculated // Calculated Bars ) { // // Current ... CalculateCycle( cOpenBuffer, cHighBuffer, cLowBuffer, cCloseBuffer, cColorBuffer, mCSMLength, showCurrent, ratesTotal, prevCalculated // ); // // Short ... CalculateCycle( sOpenBuffer, sHighBuffer, sLowBuffer, sCloseBuffer, sColorBuffer, mSSMLength, showShort, ratesTotal, prevCalculated // ); // // Medium ... CalculateCycle( mOpenBuffer, mHighBuffer, mLowBuffer, mCloseBuffer, mColorBuffer, mMSMLength, showMedium, ratesTotal, prevCalculated // ); // // Long ... CalculateCycle( lOpenBuffer, lHighBuffer, lLowBuffer, lCloseBuffer, lColorBuffer, mLSMLength, showLong, ratesTotal, prevCalculated // ); // // Hind ... CalculateCycle( hOpenBuffer, hHighBuffer, hLowBuffer, hCloseBuffer, hColorBuffer, mHSMLength, showHind, ratesTotal, prevCalculated // ); } // void CalculateCycle( double &open[], double &high[], double &low[], double &close[], double &clr[], // Color Index Buffer int length, // Calculation Length bool show, // Show or not int ratesTotal, // Total Bars int prevCalculated // Calculated Bars ) { // // Open ... int calculatedSMOpens = ExponentialMAOnBuffer( ratesTotal, prevCalculated, 0, length, openBuffer, open // ); // // Close ... int calculatedSMCloses = ExponentialMAOnBuffer( ratesTotal, prevCalculated, 0, length, closeBuffer, close // ); // int calculatedSMLows = 0; int calculatedSMHighs = 0; if (!ignoreShadows) { // // High ... calculatedSMHighs = ExponentialMAOnBuffer( ratesTotal, prevCalculated, 0, length, highBuffer, high // ); // // Low ... calculatedSMLows = ExponentialMAOnBuffer( ratesTotal, prevCalculated, 0, length, lowBuffer, low // ); } else { // // High ... calculatedSMHighs = ExponentialMAOnBuffer( ratesTotal, prevCalculated, 0, length, openBuffer, high // ); // // Low ... calculatedSMLows = ExponentialMAOnBuffer( ratesTotal, prevCalculated, 0, length, closeBuffer, low // ); } // // Find Calculated Items for Colors Calculations ... int mNumberOfItems = MathMin(calculatedSMOpens, calculatedSMHighs); mNumberOfItems = MathMin(mNumberOfItems, calculatedSMLows); mNumberOfItems = MathMin(mNumberOfItems, calculatedSMCloses); // // Create a Loop for Color of Candles ... for (int i = 0; i < mNumberOfItems; i++) { // bool isBearish = // open[i] > close[i] // ; // if (show) { // clr[i] = isBearish ? bearishColorIDX : bullishColorIDX; } else { // clr[i] = hideColorIDX; } } } //