/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: X121 XHK // Description: XHK ... // // // 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 X121 XHK Indicator" #property strict // // Definitions ... // #define ShortName "X121 XHK" // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5" // // Inputs ... // // Market ... input group "Market"; input int xhkSmoothingLength = 14; // Length input ENUM_X_MA_METHOD xhkSmoothingMode = X_MA_MODE_EMA; // Smoothing Method input bool xhkIgnoreSmoothingShadows = false; // Ignore Smoothed Bar Shadows // input group "Presentation"; // input int startCalculationForLastBars = 1000; // Calculate Last n Bars // input bool drawRawXHKCandles = true; // Draw Raw Candle input bool drawSmoothedXHKCandles = true; // Draw Smoothed Candle // // Buffers ... // #property indicator_chart_window // #property indicator_buffers 10 #property indicator_plots 2 // #define hideColorIDX 0 #define bullishColorIDX 1 #define bearishColorIDX 2 #define neuturalColorIDX 3 // // PLOTTED Buffers ... // #define openHKBufferIndex 0 double openHKBuffer[]; // #define highHKBufferIndex 1 double highHKBuffer[]; // #define lowHKBufferIndex 2 double lowHKBuffer[]; // #define closeHKBufferIndex 3 double closeHKBuffer[]; // #define rawHKColorBufferIndex 4 double rawHKColorBuffer[]; // #define rawHKBufferIndex 0 #property indicator_label1 "X121 XHK Open;X121 XHK High;X121 XHK Low;X121 XHK Close" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 CLR_NONE, clrDodgerBlue, clrDarkGoldenrod // // Open ... #define openBufferIndex 5 double openBuffer[]; // // High ... #define highBufferIndex 6 double highBuffer[]; // // Low ... #define lowBufferIndex 7 double lowBuffer[]; // // Close ... #define closeBufferIndex 8 double closeBuffer[]; // // Candle Color ... #define candleColorBufferIndex 9 double candleColorBuffer[]; // #define candlesBufferIndex 1 #property indicator_label2 "X121 XHKSM Open;X121 XHKSM High;X121 XHKSM Low;X121 XHKSM Close" #property indicator_type2 DRAW_COLOR_CANDLES #property indicator_color2 CLR_NONE, clrAqua, clrMagenta // // Variables, Properties and etc ... // // this counts Available Bars ... int limit; // int maxLength; // int firstBarIndex; // // Event Handlers ... /** * Initialize Indicator ... * * @return ( int ) */ int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initialize Indicator Handlers ... // // 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; } /** * De Initialize Indicator ... * * @param reason: Integer, De Initialization Reason ... */ 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 // } /** * Calculate Bars ... * * @param rates_total: Integer, Total Bars on Chart ... * @param prev_calculated: Integer, Total Calculated Bars on Charts ... * @param time: DateTime Array, History of Open Time ... * @param open: Double Array, History of Open Prices ... * @param high: Double Array, History of High Prices ... * @param low: Double Array, History of Low Prices ... * @param close: Double Array, History of Close Prices ... * @param tick_volume: Long, History of Tick Volumes on Bar ... * @param volume: Long, History of Trade Volumes ... * @param spread: Double, History of Spread Price ... * * @return ( int ) */ int OnCalculate( const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[] // ) { // // 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); // // Fill All Buffers by Zero ... if (prev_calculated == 0) { } // 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--) { // CalculateBuffers( i, prev_calculated, rates_total, // open, high, close, low, tick_volume // ); } // return rates_total; } // // Functions ... /** * Validate Input Args for Initialization ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = // true // ; // return result; } /** * Extract Max Length of Inputs ... * * @return ( int ) */ int ExtractMaxLengthOfInputs() { // int result = 0; // result = MathMax(0, xhkSmoothingLength); // return result; } /** * Define Required Buffers ... */ void DefineBuffers() { // // RAW ... // // Raw Candles Color ... ArraySetAsSeries(rawHKColorBuffer, true); SetIndexBuffer(rawHKColorBufferIndex, rawHKColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on Candles Buffer ... PlotIndexSetDouble(rawHKBufferIndex, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetInteger(rawHKBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(openHKBuffer, true); SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(highHKBuffer, true); SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(closeHKBuffer, true); SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(lowHKBuffer, true); SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA); // // SMOOTHED ... // // Candles Color ... ArraySetAsSeries(candleColorBuffer, true); SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on Candles Buffer ... PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(openBuffer, true); SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(highBuffer, true); SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(closeBuffer, true); SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(lowBuffer, true); SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA); } /** * Set Indicator Short Name and also we can define Buffers Labels ... */ void SetIndicatorName() { IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } /** * Calculate Custom Buffers ... * * @param bar_index: Integer, Represent Current Bar ... * @param prevCalculated: Integer, Represent Previous Calculated Bars ... * @param ratesTotal: Integer, Represents All Available Bars ... * @param open: Double Array, History of Open Prices ... * @param high: Double Array, History of High Prices ... * @param close: Double Array, History of Close Prices ... * @param low: Double Array, History of Low Prices ... * @param tickVolume: Long, History of Tick Volumes on Bar ... */ void CalculateBuffers( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, const double &open[], const double &high[], const double &close[], const double &low[], const long &tickVolume[] // ) { // int barsLimit = startCalculationForLastBars > 0 ? startCalculationForLastBars : 0; if (barsLimit == 0) { // barsLimit = ratesTotal; firstBarIndex = barsLimit - 1; } else { // firstBarIndex = startCalculationForLastBars; } // // bool canCalculate = true; bool canCalculate = bar_index <= barsLimit; if (canCalculate) { // CalculateXHK( bar_index, prevCalculated, ratesTotal, open, high, close, low // ); } else { FillBuffersZero(bar_index); } } // // Custom ... /** * Fill All Bufers to Zero Vlue for Specified Bar Index ... * * @param barIndex: Integer ... */ void FillBuffersZero(int barIndex) { // lowHKBuffer[barIndex] = 0.0; openHKBuffer[barIndex] = 0.0; highHKBuffer[barIndex] = 0.0; closeHKBuffer[barIndex] = 0.0; rawHKColorBuffer[barIndex] = hideColorIDX; // lowBuffer[barIndex] = 0.0; openBuffer[barIndex] = 0.0; highBuffer[barIndex] = 0.0; closeBuffer[barIndex] = 0.0; candleColorBuffer[barIndex] = hideColorIDX; } /** * Calculate ATR Zones ... * * @param bar_index: Integer, Represent Current Bar ... * @param prevCalculated: Integer, Represent Previous Calculated Bars ... * @param ratesTotal: Integer, Represents All Available Bars ... * @param open: Double Array, History of Open Prices ... * @param high: Double Array, History of High Prices ... * @param close: Double Array, History of Close Prices ... * @param low: Double Array, History of Low Prices ... */ void CalculateXHK( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, const double &open[], const double &high[], const double &close[], const double &low[] // ) { // int lastBarIndex = bar_index + 1; bool isFirstBar = startCalculationForLastBars > 0 ? bar_index == startCalculationForLastBars : bar_index == firstBarIndex; // double mPrevHKOpenValue; double mPrevHKCloseValue; // if (ArraySize(open) <= bar_index + 1) { // mPrevHKOpenValue = 0; mPrevHKCloseValue = 0; } else { // mPrevHKOpenValue = openHKBuffer[bar_index + 1]; mPrevHKCloseValue = closeHKBuffer[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)); // double candleColorValue = mHKOpenValue < mHKCloseValue ? bullishColorIDX : bearishColorIDX; // // Raw HK Buffers ... openHKBuffer[bar_index] = mHKOpenValue; highHKBuffer[bar_index] = mHKHighValue; lowHKBuffer[bar_index] = mHKLowValue; closeHKBuffer[bar_index] = mHKCloseValue; rawHKColorBuffer[bar_index] = drawRawXHKCandles ? candleColorValue : hideColorIDX; // // Apply Smoothing ... bool canSmooth = xhkSmoothingLength > 0 && xhkSmoothingMode != X_MA_MODE_NONE; if (!canSmooth) { // double min = MathMin(mHKOpenValue, mHKCloseValue); double max = MathMax(mHKOpenValue, mHKCloseValue); // openBuffer[bar_index] = mHKOpenValue; highBuffer[bar_index] = xhkIgnoreSmoothingShadows ? max : mHKHighValue; lowBuffer[bar_index] = xhkIgnoreSmoothingShadows ? min : mHKLowValue; closeBuffer[bar_index] = mHKCloseValue; candleColorBuffer[bar_index] = drawSmoothedXHKCandles ? candleColorValue : hideColorIDX; } else { // // Open ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, xhkSmoothingLength, openHKBuffer, openBuffer, xhkSmoothingMode // ); // // Close ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, xhkSmoothingLength, closeHKBuffer, closeBuffer, xhkSmoothingMode // ); // // Ignoring Shadows ... if (!xhkIgnoreSmoothingShadows) { // // High ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, xhkSmoothingLength, highHKBuffer, highBuffer, xhkSmoothingMode // ); // // Low ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, xhkSmoothingLength, lowHKBuffer, lowBuffer, xhkSmoothingMode // ); } else { // double min = MathMin(closeBuffer[bar_index], openBuffer[bar_index]); double max = MathMin(closeBuffer[bar_index], openBuffer[bar_index]); // lowBuffer[bar_index] = min; highBuffer[bar_index] = max; } // // Calculate Smoothed Color ... candleColorValue = openBuffer[bar_index] < closeBuffer[bar_index] ? bullishColorIDX : bearishColorIDX; candleColorBuffer[bar_index] = drawSmoothedXHKCandles ? candleColorValue : hideColorIDX; } } //