/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: X121_XICH // Description: Ichimoku Kinko Hyo ... // // // 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_XICH Indicator" #property strict // // START Constants ... // // // Indicator Short Name ... #define ShortName "X121_XICH" // // Ichimoku Golden Numbers ... enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS { X_ICH_BASE = 9, X_ICH_GOLDEN = 17, X_ICH_CYCLE = 26, X_ICH_PERIOD = 35, X_ICH_STAR = 45, X_ICH_MED = 52, X_ICH_LONG = 63, X_ICH_FULL = 72 }; // // Ichimoku Lines Calculator Mode ... enum ENUM_X_ICHIMOKU_CALCULATION_MODE { // X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close }; // // END Constants ... // // // START Inputs ... // // // ICHIMOKU Kinko Hyo ... // // TENKANSEN ... input group "Tenkan Sen"; input int tenkanSenLength = 9; // Length input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode // // KIJUNSEN ... input group "Kijun Sen"; input int kijunSenLength = 26; // Length input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode // // SENKOUSPANB ... input group "Senkou Span B"; input int senkouSpanBLength = 52; // Length input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode // // CHIKOUSPAN ... input group "Chikou Span"; input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type // input group "Presentation"; input bool showTenkanSen = true; // Show Tenkan Sen input bool showKijunSen = true; // Show Kijun Sen input bool showKijunSenPlus = false; // Show Kijun Sen + input bool showKijunSenNegative = false; // Show Kijun Sen - input bool showChikouSpan = true; // Show Chikou Span input bool showSenkouSpanA = true; // Show Senkou Span A input bool showSenkouSpanB = true; // Show Senkou Span B input bool showKumo = true; // Show Kumo input bool shiftKumo = true; // Shift Kumo to Future // // END Inputs ... // // // START Includes and Imports ... // // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5" // // END Includes and Imports ... // // // START Buffers ... // #property indicator_chart_window // #property indicator_buffers 15 #property indicator_plots 8 // // PLOTTED Buffers ... // // ICHIMOKU ... // // TENKANSEN ... // #define tenkanSenBufferIndex 0 double tenkanSenBuffer[]; // #property indicator_label1 "X121_XICH TK" #property indicator_type1 DRAW_LINE #property indicator_color1 clrBrown #property indicator_style1 STYLE_SOLID #property indicator_width1 1 // // KIJUNSEN ... // #define kijunSenBufferIndex 1 double kijunSenBuffer[]; // #property indicator_label2 "X121_XICH KJ" #property indicator_type2 DRAW_LINE #property indicator_color2 clrDodgerBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 // #define kijunSenPlusBufferIndex 2 double kijunSenPlusBuffer[]; // #property indicator_label3 "X121_XICH KJ+" #property indicator_type3 DRAW_LINE #property indicator_color3 clrMediumTurquoise #property indicator_style3 STYLE_DOT #property indicator_width3 1 // #define kijunSenNegativeBufferIndex 3 double kijunSenNegativeBuffer[]; // #property indicator_label4 "X121_XICH KJ-" #property indicator_type4 DRAW_LINE #property indicator_color4 clrDarkSeaGreen #property indicator_style4 STYLE_DOT #property indicator_width4 1 // // CHIKOUSPAN ... // #define chikouSpanBufferIndex 4 double chikouSpanBuffer[]; // #property indicator_label5 "X121_XICH CS" #property indicator_type5 DRAW_LINE #property indicator_color5 clrDarkGreen #property indicator_style5 STYLE_SOLID #property indicator_width5 1 // #define senkouABufferIndex 5 double senkouABuffer[]; // #property indicator_label6 "X121_XICH SSA" #property indicator_type6 DRAW_LINE #property indicator_color6 clrLightGray #property indicator_style6 STYLE_DASHDOTDOT #property indicator_width6 1 // #define senkouBBufferIndex 6 double senkouBBuffer[]; // #property indicator_label7 "X121_XICH SSB" #property indicator_type7 DRAW_LINE #property indicator_color7 clrLightGray #property indicator_style7 STYLE_DASHDOTDOT #property indicator_width7 1 // // KUMO ... // // SENKOUSPANA ... // #define senkouSpanABufferIndex 7 double senkouSpanABuffer[]; // // SENKOUSPANB ... // #define senkouSpanBBufferIndex 8 double senkouSpanBBuffer[]; // // KUMOCLOUD ... // #define kumoBufferIndex 7 // #property indicator_label8 "X121_XICH Kumo" #property indicator_type8 DRAW_FILLING #property indicator_color8 clrAqua, clrMagenta #property indicator_style8 STYLE_SOLID #property indicator_width8 1 // // DATA Buffers ... // #define dTenkanBufferIndex 9 double dTenkanBuffer[]; // #define dKijunBufferIndex 10 double dKijunBuffer[]; // #define dChikouBufferIndex 11 double dChikouBuffer[]; // #define dSSABufferIndex 12 double dSSABuffer[]; // #define dSSBBufferIndex 13 double dSSBBuffer[]; // // END Buffers ... // // // START Global Definitions: Variables, Properties and etc ... // // int maxLength; int mHandler; // ENUM_SERIESMODE mTenkanSenTopMode = NULL; ENUM_SERIESMODE mTenkanSenBottomMode = NULL; // ENUM_SERIESMODE mKijunSenTopMode = NULL; ENUM_SERIESMODE mKijunSenBottomMode = NULL; // ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; // // END Global Definitions: Variables, Properties and etc ... // // // START Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { 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(); // // Init Handler ... mHandler = iIchimoku( _Symbol, _Period, tenkanSenLength, kijunSenLength, senkouSpanBLength); if (mHandler == INVALID_HANDLE) { return INIT_FAILED; } // // 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 // IndicatorRelease(mHandler); } // // Calculating what we want ... int OnCalculate( // // total Candles on chart ... const int rates_total, // // total calculated Candles on charts ... const int prev_calculated, // // history of Candles Open Time ... const datetime &time[], // // history of Candles Open Price ... const double &open[], // // history of Candles High Price ... const double &high[], // // history of Candles Low Price ... const double &low[], // // history of Candles Close Price ... const double &close[], // // history of Tick Volumes on Candle ... const long &tick_volume[], // // history of Trade Volumes ... const long &volume[], // // history of Candles Spread Price ... 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); // // this counts Available Bars ... int limit; // // Check Calculated Bars ... int ichCalculatedBars = BarsCalculated(mHandler); if (ichCalculatedBars < maxLength) { return prev_calculated; } // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Buffers Copy ... int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer); int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer); int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer); int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer); int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer); if ( copiedSSAs < 0 || copiedSSBs < 0 || copiedKijuns < 0 || copiedTenkans < 0 || copiedChikous < 0) { return prev_calculated; } // // Main Loop ... for (int i = limit - 1; i >= 0 && !IsStopped(); i--) { CalculateBuffers(i); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = // (tenkanSenLength > 2 && kijunSenLength > tenkanSenLength && senkouSpanBLength > kijunSenLength) // ; // return result; } // // Retrieve all Exists Input Max Length ... // use for Start Of Drawing ... int ExtractMaxLengthOfInputs() { // int result = 0; // // Ichimoku ... result = MathMax(result, tenkanSenLength); result = MathMax(result, kijunSenLength); result = MathMax(result, senkouSpanBLength); // return result; } // // Define Indexes and Styles ... void DefineBuffers() { // // ICHIMOKU ... // // TENKANSEN ... // ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; // ArraySetAsSeries(tenkanSenBuffer, true); SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA); PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen); PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType); // // KIJUNSEN ... // ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; // ArraySetAsSeries(kijunSenBuffer, true); SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA); PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen); PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType); // // KIJUNSEN Plus ... // ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE; // ArraySetAsSeries(kijunSenPlusBuffer, true); SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA); PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength); PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType); // // KIJUNSEN Negative ... // ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE; // ArraySetAsSeries(kijunSenNegativeBuffer, true); SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA); PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength); PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType); // // CHIKOUSPAN ... // ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; // ArraySetAsSeries(chikouSpanBuffer, true); SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA); PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength); PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan); PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType); // // SENKOUSPAN A and B ... int shiftSize = shiftKumo ? kijunSenLength : 0; // // SENKOUSPANA ... ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(senkouABuffer, true); SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize); PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); // // SENKOUSPANB ... ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(senkouBBuffer, true); SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize); PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); // // KUMO ... // // SENKOUSPANA ... ArraySetAsSeries(senkouSpanABuffer, true); SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength); // // SENKOUSPANB ... ArraySetAsSeries(senkouSpanBBuffer, true); SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength); // // KUMO ... // ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; // PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize); PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false); PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType); // // DATA Buffers ... // // D Tenkan ... ArraySetAsSeries(dTenkanBuffer, true); SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS); // // D Kijun ... ArraySetAsSeries(dKijunBuffer, true); SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS); // // D Chikou ... ArraySetAsSeries(dChikouBuffer, true); SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS); // // D SSA ... ArraySetAsSeries(dSSABuffer, true); SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS); // // D SSB ... ArraySetAsSeries(dSSBBuffer, true); SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS); } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } // // Calculate Buffers ... void CalculateBuffers( int bar_index // Selected Bar Index ) { // // ICHIMOKU ... // double topValue; double bottomValue; // // TENKANSEN ... // // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) { // switch (tenkanSenMode) { // case X_XICH_HH_LL_MODE: // mTenkanSenTopMode = MODE_HIGH; mTenkanSenBottomMode = MODE_LOW; break; // case X_XICH_HO_LC_MODE: // mTenkanSenTopMode = MODE_OPEN; mTenkanSenBottomMode = MODE_CLOSE; break; } } // // Calculate Top ... topValue = GetHighestHigh( _Symbol, _Period, mTenkanSenTopMode, tenkanSenLength, bar_index); // // Calculate Bottom ... bottomValue = GetLowestLow( _Symbol, _Period, mTenkanSenBottomMode, tenkanSenLength, bar_index); // double tenkanSenValue = (topValue + bottomValue) / 2; tenkanSenBuffer[bar_index] = tenkanSenValue; // // KIJUNSEN ... // // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) { // switch (kijunSenMode) { // case X_XICH_HH_LL_MODE: // mKijunSenTopMode = MODE_HIGH; mKijunSenBottomMode = MODE_LOW; break; // case X_XICH_HO_LC_MODE: // mKijunSenTopMode = MODE_OPEN; mKijunSenBottomMode = MODE_CLOSE; break; } } // // Calculate Top ... topValue = GetHighestHigh( _Symbol, _Period, mKijunSenTopMode, kijunSenLength, bar_index); // // Calculate Bottom ... bottomValue = GetLowestLow( _Symbol, _Period, mKijunSenBottomMode, kijunSenLength, bar_index); // double kijunSenValue = (topValue + bottomValue) / 2; kijunSenBuffer[bar_index] = kijunSenValue; // kijunSenPlusBuffer[bar_index] = kijunSenValue; kijunSenNegativeBuffer[bar_index] = kijunSenValue; // // CHIKOUSPAN ... double chikouSpanValue = GetAppliedPrice( bar_index, chikuoSpanAppliedTo); chikouSpanBuffer[bar_index] = chikouSpanValue; // // KUMO ... // // SENKOUSPANA ... double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; senkouABuffer[bar_index] = senkouSpanAValue; senkouSpanABuffer[bar_index] = senkouSpanAValue; // // SENKOUSPANB ... // // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) { // switch (senkouSpanBMode) { // case X_XICH_HH_LL_MODE: // mSenkouSpanBTopMode = MODE_HIGH; mSenkouSpanBBottomMode = MODE_LOW; break; // case X_XICH_HO_LC_MODE: // mSenkouSpanBTopMode = MODE_OPEN; mSenkouSpanBBottomMode = MODE_CLOSE; break; } } // // Calculate Top ... topValue = GetHighestHigh( _Symbol, _Period, mSenkouSpanBTopMode, senkouSpanBLength, bar_index); // // Calculate Bottom ... bottomValue = GetLowestLow( _Symbol, _Period, mSenkouSpanBBottomMode, senkouSpanBLength, bar_index); // double senkouSpanBValue = (topValue + bottomValue) / 2; senkouBBuffer[bar_index] = senkouSpanBValue; senkouSpanBBuffer[bar_index] = senkouSpanBValue; } // // END Functions ... //