////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // -------------------------------------- // Name: X121_XMRB // Description: Moving Average Ribbon // // // 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_XMRB Indicator" #property strict // // START Constants ... // // // Indicator Short Name ... #define ShortName "X121_XMRB" // // END Constants ... // // // START Inputs ... // // input group "Ribbon 1"; input int fast1Length = 3; // Fast input int slow1Length = 5; // Slow // input group "Ribbon 2"; input int fast2Length = 8; // Fast input int slow2Length = 13; // Slow // input group "Ribbon 3"; input int fast3Length = 21; // Fast input int slow3Length = 34; // Slow // input group "Ribbon 4"; input int fast4Length = 55; // Fast input int slow4Length = 89; // Slow // input group "Ribbon 5"; input int fast5Length = 144; // Fast input int slow5Length = 233; // Slow // input group "Calculation"; input ENUM_MA_METHOD ribbonMode = MODE_EMA; // Mode input ENUM_APPLIED_PRICE ribbonAppliedTo = PRICE_CLOSE; // Applied To // input group "Presentation"; input bool showFastMa = true; // Show Fast input bool showSlowMa = true; // Show Slow input bool showRibbon = false; // Show Ribbon // // 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 12 #property indicator_plots 12 // // PLOTTED Buffers ... // // MA ... // // FAST ... #define fastMaBufferIndex 0 double fastMaBuffer[]; // #property indicator_label1 "X121_XMRB F" #property indicator_type1 DRAW_LINE #property indicator_color1 clrLime #property indicator_style1 STYLE_SOLID #property indicator_width1 1 // // SLOW ... #define slowMaBufferIndex 1 double slowMaBuffer[]; // #property indicator_label2 "X121_XMRB S" #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 // // DATA Buffers ... // // FAST ... // #define fast1BufferIndex 2 double fast1Buffer[]; // #property indicator_label3 "X121_XMRB 1 F" #property indicator_type3 DRAW_LINE #property indicator_color3 clrAquamarine #property indicator_style3 STYLE_DOT #property indicator_width3 1 // #define fast2BufferIndex 3 double fast2Buffer[]; // #property indicator_label4 "X121_XMRB 2 F" #property indicator_type4 DRAW_LINE #property indicator_color4 clrAquamarine #property indicator_style4 STYLE_DOT #property indicator_width4 1 // #define fast3BufferIndex 4 double fast3Buffer[]; // #property indicator_label5 "X121_XMRB 3 F" #property indicator_type5 DRAW_LINE #property indicator_color5 clrAquamarine #property indicator_style5 STYLE_DOT #property indicator_width5 1 // #define fast4BufferIndex 5 double fast4Buffer[]; // #property indicator_label6 "X121_XMRB 4 F" #property indicator_type6 DRAW_LINE #property indicator_color6 clrAquamarine #property indicator_style6 STYLE_DOT #property indicator_width6 1 // #define fast5BufferIndex 6 double fast5Buffer[]; // #property indicator_label7 "X121_XMRB 5 F" #property indicator_type7 DRAW_LINE #property indicator_color7 clrAquamarine #property indicator_style7 STYLE_DOT #property indicator_width7 1 // // SLOW ... // #define slow1BufferIndex 7 double slow1Buffer[]; // #property indicator_label8 "X121_XMRB 1 S" #property indicator_type8 DRAW_LINE #property indicator_color8 clrPlum #property indicator_style8 STYLE_DOT #property indicator_width8 1 // #define slow2BufferIndex 8 double slow2Buffer[]; // #property indicator_label9 "X121_XMRB 2 S" #property indicator_type9 DRAW_LINE #property indicator_color9 clrPlum #property indicator_style9 STYLE_DOT #property indicator_width9 1 // #define slow3BufferIndex 9 double slow3Buffer[]; // #property indicator_label10 "X121_XMRB 3 S" #property indicator_type10 DRAW_LINE #property indicator_color10 clrPlum #property indicator_style10 STYLE_DOT #property indicator_width10 1 // #define slow4BufferIndex 10 double slow4Buffer[]; // #property indicator_label11 "X121_XMRB 4 S" #property indicator_type11 DRAW_LINE #property indicator_color11 clrPlum #property indicator_style11 STYLE_DOT #property indicator_width11 1 // #define slow5BufferIndex 11 double slow5Buffer[]; // #property indicator_label12 "X121_XMRB 5 S" #property indicator_type12 DRAW_LINE #property indicator_color12 clrPlum #property indicator_style12 STYLE_DOT #property indicator_width12 1 // // END Buffers ... // // // START Global Definitions: Variables, Properties and etc ... // // int maxLength; // int fast1MaHandler = INVALID_HANDLE; int fast2MaHandler = INVALID_HANDLE; int fast3MaHandler = INVALID_HANDLE; int fast4MaHandler = INVALID_HANDLE; int fast5MaHandler = INVALID_HANDLE; // int slow1MaHandler = INVALID_HANDLE; int slow2MaHandler = INVALID_HANDLE; int slow3MaHandler = INVALID_HANDLE; int slow4MaHandler = INVALID_HANDLE; int slow5MaHandler = INVALID_HANDLE; // // 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(); // // Set Indicator ShortName ... SetIndicatorName(); // // Initialize MAs ... if (!InitializeMas()) { return INIT_PARAMETERS_INCORRECT; } // // 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 // // Here we can handle De Initialization Reasons ... // IndicatorRelease(fast1MaHandler); IndicatorRelease(fast2MaHandler); IndicatorRelease(fast3MaHandler); IndicatorRelease(fast4MaHandler); IndicatorRelease(fast5MaHandler); // IndicatorRelease(slow1MaHandler); IndicatorRelease(slow2MaHandler); IndicatorRelease(slow3MaHandler); IndicatorRelease(slow4MaHandler); IndicatorRelease(slow5MaHandler); } // // 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 fast1MaCalculatedBars = BarsCalculated(fast1MaHandler); int fast2MaCalculatedBars = BarsCalculated(fast2MaHandler); int fast3MaCalculatedBars = BarsCalculated(fast3MaHandler); int fast4MaCalculatedBars = BarsCalculated(fast4MaHandler); int fast5MaCalculatedBars = BarsCalculated(fast5MaHandler); // int slow1MaCalculatedBars = BarsCalculated(slow1MaHandler); int slow2MaCalculatedBars = BarsCalculated(slow2MaHandler); int slow3MaCalculatedBars = BarsCalculated(slow3MaHandler); int slow4MaCalculatedBars = BarsCalculated(slow4MaHandler); int slow5MaCalculatedBars = BarsCalculated(slow5MaHandler); if ( fast1MaCalculatedBars < maxLength || fast2MaCalculatedBars < maxLength || fast3MaCalculatedBars < maxLength || fast4MaCalculatedBars < maxLength || fast5MaCalculatedBars < maxLength || slow1MaCalculatedBars < maxLength || slow2MaCalculatedBars < maxLength || slow3MaCalculatedBars < maxLength || slow4MaCalculatedBars < maxLength || slow5MaCalculatedBars < maxLength) { return prev_calculated; } // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Buffers Copy ... // int copiedFast1Mas = CopyBuffer(fast1MaHandler, 0, 0, limit, fast1Buffer); int copiedFast2Mas = CopyBuffer(fast2MaHandler, 0, 0, limit, fast2Buffer); int copiedFast3Mas = CopyBuffer(fast3MaHandler, 0, 0, limit, fast3Buffer); int copiedFast4Mas = CopyBuffer(fast4MaHandler, 0, 0, limit, fast4Buffer); int copiedFast5Mas = CopyBuffer(fast5MaHandler, 0, 0, limit, fast5Buffer); // int copiedSlow1Mas = CopyBuffer(slow1MaHandler, 0, 0, limit, slow1Buffer); int copiedSlow2Mas = CopyBuffer(slow2MaHandler, 0, 0, limit, slow2Buffer); int copiedSlow3Mas = CopyBuffer(slow3MaHandler, 0, 0, limit, slow3Buffer); int copiedSlow4Mas = CopyBuffer(slow4MaHandler, 0, 0, limit, slow4Buffer); int copiedSlow5Mas = CopyBuffer(slow5MaHandler, 0, 0, limit, slow5Buffer); if ( copiedFast1Mas <= 0 || copiedFast2Mas <= 0 || copiedFast3Mas <= 0 || copiedFast4Mas <= 0 || copiedFast5Mas <= 0 || copiedSlow1Mas <= 0 || copiedSlow2Mas <= 0 || copiedSlow3Mas <= 0 || copiedSlow4Mas <= 0 || copiedSlow5Mas <= 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 = // (fast1Length > 2 && fast2Length > fast1Length && fast3Length > fast2Length && fast4Length > fast3Length && fast5Length > fast4Length && slow1Length > fast1Length && slow2Length > fast2Length && slow3Length > fast3Length && slow4Length > fast4Length && slow5Length > fast5Length && slow2Length > slow1Length && slow3Length > slow2Length && slow4Length > slow3Length && slow5Length > slow4Length // ) // ; // return result; } // // Retrieve all Exists Input Max Length ... // use for Start Of Drawing ... int ExtractMaxLengthOfInputs() { // int result = 0; // // Ma ... // result = MathMax(fast1Length, fast2Length); result = MathMax(result, fast3Length); result = MathMax(result, fast4Length); result = MathMax(result, fast5Length); // result = MathMax(result, slow1Length); result = MathMax(result, slow2Length); result = MathMax(result, slow3Length); result = MathMax(result, slow4Length); result = MathMax(result, slow5Length); // return result; } // // Initialize Ma Handlers ... bool InitializeMas() { // bool result = false; // fast1MaHandler = iMA( _Symbol, _Period, fast1Length, 0, ribbonMode, ribbonAppliedTo); fast2MaHandler = iMA( _Symbol, _Period, fast2Length, 0, ribbonMode, ribbonAppliedTo); fast3MaHandler = iMA( _Symbol, _Period, fast3Length, 0, ribbonMode, ribbonAppliedTo); fast4MaHandler = iMA( _Symbol, _Period, fast4Length, 0, ribbonMode, ribbonAppliedTo); fast5MaHandler = iMA( _Symbol, _Period, fast5Length, 0, ribbonMode, ribbonAppliedTo); // slow1MaHandler = iMA( _Symbol, _Period, slow1Length, 0, ribbonMode, ribbonAppliedTo); slow2MaHandler = iMA( _Symbol, _Period, slow2Length, 0, ribbonMode, ribbonAppliedTo); slow3MaHandler = iMA( _Symbol, _Period, slow3Length, 0, ribbonMode, ribbonAppliedTo); slow4MaHandler = iMA( _Symbol, _Period, slow4Length, 0, ribbonMode, ribbonAppliedTo); slow5MaHandler = iMA( _Symbol, _Period, slow5Length, 0, ribbonMode, ribbonAppliedTo); // result = fast1MaHandler != INVALID_HANDLE && fast2MaHandler != INVALID_HANDLE && fast3MaHandler != INVALID_HANDLE && fast4MaHandler != INVALID_HANDLE && fast5MaHandler != INVALID_HANDLE && slow1MaHandler != INVALID_HANDLE && slow2MaHandler != INVALID_HANDLE && slow3MaHandler != INVALID_HANDLE && slow4MaHandler != INVALID_HANDLE && slow5MaHandler != INVALID_HANDLE; // if (!result) { // string message = "Error Initializing Handlers ..."; Print(message); } // return result; } // // Define Indexes and Styles ... void DefineBuffers() { // // FAST ... ENUM_DRAW_TYPE fastDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(fastMaBuffer, true); SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, showFastMa); PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastDrawType); // // SLOW ... ENUM_DRAW_TYPE slowDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(slowMaBuffer, true); SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, showSlowMa); PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowDrawType); // // DATA ... ENUM_DRAW_TYPE ribbonDrawType = showRibbon ? DRAW_LINE : DRAW_NONE; // ArraySetAsSeries(fast1Buffer, true); SetIndexBuffer(fast1BufferIndex, fast1Buffer, INDICATOR_DATA); PlotIndexSetInteger(fast1BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(fast2Buffer, true); SetIndexBuffer(fast2BufferIndex, fast2Buffer, INDICATOR_DATA); PlotIndexSetInteger(fast2BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(fast3Buffer, true); SetIndexBuffer(fast3BufferIndex, fast3Buffer, INDICATOR_DATA); PlotIndexSetInteger(fast3BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(fast4Buffer, true); SetIndexBuffer(fast4BufferIndex, fast4Buffer, INDICATOR_DATA); PlotIndexSetInteger(fast4BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(fast5Buffer, true); SetIndexBuffer(fast5BufferIndex, fast5Buffer, INDICATOR_DATA); PlotIndexSetInteger(fast5BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(slow1Buffer, true); SetIndexBuffer(slow1BufferIndex, slow1Buffer, INDICATOR_DATA); PlotIndexSetInteger(slow1BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(slow2Buffer, true); SetIndexBuffer(slow2BufferIndex, slow2Buffer, INDICATOR_DATA); PlotIndexSetInteger(slow2BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(slow3Buffer, true); SetIndexBuffer(slow3BufferIndex, slow3Buffer, INDICATOR_DATA); PlotIndexSetInteger(slow3BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(slow4Buffer, true); SetIndexBuffer(slow4BufferIndex, slow4Buffer, INDICATOR_DATA); PlotIndexSetInteger(slow4BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); // ArraySetAsSeries(slow5Buffer, true); SetIndexBuffer(slow5BufferIndex, slow5Buffer, INDICATOR_DATA); PlotIndexSetInteger(slow5BufferIndex, PLOT_SHOW_DATA, showRibbon); PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_BEGIN, maxLength); PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); } // // 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 ) { // // Retireve Values ... // double fast1Value = fast1Buffer[bar_index]; double fast2Value = fast2Buffer[bar_index]; double fast3Value = fast3Buffer[bar_index]; double fast4Value = fast4Buffer[bar_index]; double fast5Value = fast5Buffer[bar_index]; // double slow1Value = slow1Buffer[bar_index]; double slow2Value = slow2Buffer[bar_index]; double slow3Value = slow3Buffer[bar_index]; double slow4Value = slow4Buffer[bar_index]; double slow5Value = slow5Buffer[bar_index]; // double fastValue = (fast1Value + fast2Value + fast3Value + fast4Value + fast5Value) / 5; fastMaBuffer[bar_index] = fastValue; // double slowValue = (slow1Value + slow2Value + slow3Value + slow4Value + slow5Value) / 5; slowMaBuffer[bar_index] = slowValue; } // // END Functions ... //