//+------------------------------------------------------------------+ //| MACD_iRSI_iBands_SMA_Levels.mq4 | //| Copyright 2025, Firmament Level Trust Trading Company. | //| https://www.mql5.com/en/users/laxin| //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MACD_iRSI_iBands_SMA_Levels.ex4" #property link "https://www.mql5.com/en/users/laxin/seller" #property version "2.00" #property strict #property indicator_separate_window #property indicator_buffers 24 #property indicator_levelstyle STYLE_DOT #property indicator_levelcolor clrDarkGray #property indicator_level1 15 #property indicator_level2 25 #property indicator_level3 50 #property indicator_level4 75 #property indicator_level5 85 //--- Buffers double macdArray[]; double rsiArray[]; double zeroLine[]; double UB1[]; double UB2[]; double UB3[]; double UB4[]; double UB5[]; double UB6[]; double MidB[]; double LB1[]; double LB2[]; double LB3[]; double LB4[]; double LB5[]; double LB6[]; double maArray[]; double levelOffsets[]; // parsed numeric offsets int levelCount = 0; // Buffers for up to 8 levels double level1[], level2[], level3[], level4[]; double level5[], level6[], level7[], level8[]; extern string iMACD_Settings = " iMACD Settings "; //--- MACD / RSI / Bands Inputs input int FastEMA = 5; input int SlowEMA = 25; input int SignalSMA = 2; input ENUM_APPLIED_PRICE MACD_Price = PRICE_CLOSE; extern string MACDRSI = " MACD-RSI-Line-Settings "; input int RSIPeriod = 7; input int RSI_Style = STYLE_SOLID; input int RSI_Width = 2; input color RSI_Color = clrYellow; extern string Bands_Deviation_Inputs = " Band Deviation Inputs "; input int BandsPeriod = 10; input double BandDeviation1 = 0.3535; input double BandDeviation2 = 0.707; input double BandDeviation3 = 1.0605; input double BandDeviation4 = 1.414; input double BandDeviation5 = 1.5907; input double BandDeviation6 = 1.7675; input int BandsShift = 0; extern string DebugModeSettings = " Debug Mode Settings Settings "; input bool DebugMode = false; // if true, print debug info input int LastBarIndex = 1; // Debug/ShortName = 1 (last closed bar) extern string Moving_Average_Inputs = " Moving Average Inputs "; input bool UseLevels = true; //--- Moving Average on Bollinger array input int MAPeriod = 10; input ENUM_MA_METHOD MAMethod = MODE_SMA; input ENUM_LINE_STYLE MA_Style = STYLE_SOLID; input int MA_Width = 1; input color MA_Color = clrRed; input string Levels = "22,-22,24,-24"; // comma-separated levels input ENUM_LINE_STYLE Level_Style = STYLE_DOT; input int Level_Width = 1; input color Level_Color = clrLime; extern string UpperBand = " Upper Band "; input int TopStyle4 = STYLE_SOLID; input int TopWidth4 = 1; input color TopColor4 = clrRed; extern string MiddleBand = " Middle Band "; input int StyleMid1 = STYLE_SOLID; input int WidthMid1 = 1; input color ColorMid1 = clrRed; extern string LowerBand = " Lower Band "; input int BottomStyle4 = STYLE_SOLID; input int BottomWidth4 = 1; input color BottomColor4 = clrRed; extern string MACDZeroLine = " MACD Zero Line "; input int StyleZero = STYLE_SOLID; input int WidthZero = 2; input color ColorZero = clrLimeGreen; extern string UpperWarnineLine6 = " Upper Warning Line 6 "; input int TopStyle6 = STYLE_DOT; input int TopWidth6 = 1; input color TopColor6 = clrDodgerBlue; extern string UpperWarningLine5 = " Upper Warning Line 5 "; input int TopStyle5 = STYLE_DOT; input int TopWidth5 = 1; input color TopColor5 = clrDodgerBlue; extern string UpperWarnineLine3 = " Upper Warning Line 3 "; input int TopStyle3 = STYLE_DOT; input int TopWidth3 = 1; input color TopColor3 = clrDodgerBlue; extern string UpperWarningLine2 = " Upper Warning Line 2 "; input int TopStyle2 = STYLE_DOT; input int TopWidth2 = 1; input color TopColor2 = clrDodgerBlue; extern string UpperWarningLine1 = " Upper Warning Line 1 "; input int TopStyle1 = STYLE_DOT; input int TopWidth1 = 1; input color TopColor1 = clrDodgerBlue; extern string LowerWarningLine1 = " Lower Warning Line 1 "; input int BottomStyle1 = STYLE_DOT; input int BottomWidth1 = 1; input color BottomColor1 = clrDodgerBlue; extern string LowerWarningLine2 = " Lower Warning Line 2 "; input int BottomStyle2 = STYLE_DOT; input int BottomWidth2 = 1; input color BottomColor2 = clrDodgerBlue; extern string LowerWarningLine3 = " Lower Warning Line 3 "; input int BottomStyle3 = STYLE_DOT; input int BottomWidth3 = 1; input color BottomColor3 = clrDodgerBlue; extern string LowerWarningLine5 = " Lower Warning Line 5 "; input int BottomStyle5 = STYLE_DOT; input int BottomWidth5 = 1; input color BottomColor5 = clrDodgerBlue; extern string LowerWarningLine6 = " Lower Warning Line 6 "; input int BottomStyle6 = STYLE_DOT; input int BottomWidth6 = 1; input color BottomColor6 = clrDodgerBlue; int ParseLevels(string text, double &out[]) { string parts[]; int count = StringSplit(text, ',', parts); ArrayResize(out, count); for(int i=0; i 8) levelCount = 8; // cap at 8 // Bind buffers for as many levels as we parsed if(levelCount > 0) { SetIndexBuffer(17, level1); SetIndexStyle(17, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(17, NULL); } if(levelCount > 1) { SetIndexBuffer(18, level2); SetIndexStyle(18, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(18, NULL); } if(levelCount > 2) { SetIndexBuffer(19, level3); SetIndexStyle(19, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(19, NULL); } if(levelCount > 3) { SetIndexBuffer(20, level4); SetIndexStyle(20, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(20, NULL); } if(levelCount > 4) { SetIndexBuffer(21, level5); SetIndexStyle(21, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(21, NULL); } if(levelCount > 5) { SetIndexBuffer(22, level6); SetIndexStyle(22, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(22, NULL); } if(levelCount > 6) { SetIndexBuffer(23, level7); SetIndexStyle(23, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(23, NULL); } if(levelCount > 7) { SetIndexBuffer(24, level8); SetIndexStyle(24, DRAW_LINE, Level_Style, Level_Width, Level_Color); SetIndexLabel(24, NULL); } ArraySetAsSeries(level1,true); ArraySetAsSeries(level2,true); ArraySetAsSeries(level3,true); ArraySetAsSeries(level4,true); ArraySetAsSeries(level5,true); ArraySetAsSeries(level6,true); ArraySetAsSeries(level7,true); ArraySetAsSeries(level8,true); } //--- return(INIT_SUCCEEDED); } 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[]) { int start = prev_calculated-1; if(start > 0) start--; ArrayResize(macdArray, rates_total); ArraySetAsSeries(macdArray, true); for(int i = 0; i < rates_total; i++) { macdArray[i] = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, MACD_Price, MODE_MAIN, i); } ArrayResize(rsiArray, rates_total); ArraySetAsSeries(rsiArray, true); for (int i = 0; i < rates_total; i++) { rsiArray[i] = iRSIOnArray(macdArray, rates_total, RSIPeriod, i); } ArrayResize(maArray, rates_total); ArrayResize(level1, rates_total); ArrayResize(level2, rates_total); ArrayResize(level3, rates_total); ArrayResize(level4, rates_total); ArrayResize(level5, rates_total); ArrayResize(level6, rates_total); ArrayResize(level7, rates_total); ArrayResize(level8, rates_total); for(int i=0; i 0) level1[i] = maVal + levelOffsets[0]; if(levelCount > 1) level2[i] = maVal + levelOffsets[1]; if(levelCount > 2) level3[i] = maVal + levelOffsets[2]; if(levelCount > 3) level4[i] = maVal + levelOffsets[3]; if(levelCount > 4) level5[i] = maVal + levelOffsets[4]; if(levelCount > 5) level6[i] = maVal + levelOffsets[5]; if(levelCount > 6) level7[i] = maVal + levelOffsets[6]; if(levelCount > 7) level8[i] = maVal + levelOffsets[7]; } ArrayResize(UB1, rates_total); ArrayResize(LB1, rates_total); ArrayResize(UB2, rates_total); ArrayResize(LB2, rates_total); ArrayResize(UB3, rates_total); ArrayResize(LB3, rates_total); ArrayResize(UB4, rates_total); ArrayResize(LB4, rates_total); ArrayResize(UB5, rates_total); ArrayResize(LB5, rates_total); ArrayResize(UB6, rates_total); ArrayResize(LB6, rates_total); ArrayResize(MidB, rates_total); double deviations[6]; deviations[0] = BandDeviation1; deviations[1] = BandDeviation2; deviations[2] = BandDeviation3; deviations[3] = BandDeviation4; deviations[4] = BandDeviation5; deviations[5] = BandDeviation6; for (int i = 0; i < rates_total; i++) { // Mid band (only once) MidB[i] = iBandsOnArray(rsiArray, rates_total, BandsPeriod, 0, BandsShift, MODE_MAIN, i); // Upper/Lower bands for(int d=0; d<6; d++) { double dev = deviations[d]; double ubVal = iBandsOnArray(rsiArray, rates_total, BandsPeriod, dev, BandsShift, MODE_UPPER, i); double lbVal = iBandsOnArray(rsiArray, rates_total, BandsPeriod, dev, BandsShift, MODE_LOWER, i); switch(d) { case 0: UB1[i] = ubVal; LB1[i] = lbVal; break; case 1: UB2[i] = ubVal; LB2[i] = lbVal; break; case 2: UB3[i] = ubVal; LB3[i] = lbVal; break; case 3: UB4[i] = ubVal; LB4[i] = lbVal; break; case 4: UB5[i] = ubVal; LB5[i] = lbVal; break; case 5: UB6[i] = ubVal; LB6[i] = lbVal; break; } } } // --- Latest values for short name int last = LastBarIndex; double macdMain = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_WEIGHTED, MODE_MAIN, last); double rsiVal = rsiArray[last]; double bandMid = MidB[last]; // build short name string string shortName = StringFormat( "MACD(%d,%d,%d) %.6f -> RSI(%d) %.2f -> Bands(%d) %.2f ", FastEMA, SlowEMA, SignalSMA, macdMain, RSIPeriod, rsiVal, BandsPeriod, bandMid ); IndicatorShortName(shortName); // --- optional debug output if(DebugMode) { Print("DEBUG >> Bar=", last, " MACD(", FastEMA, ",", SlowEMA, ",", SignalSMA, ")=", macdMain, " RSI(", RSIPeriod, ")=", rsiVal, " Bands(", BandsPeriod, ") Mid=", bandMid, " | ShortName=", shortName); } return(rates_total); } //+------------------------------------------------------------------+ void DeleteAllLines() { int total = ObjectsTotal(); for(int i = total-1; i >= 0; i--) { string name = ObjectName(i); if(StringFind(name, "MACD-RSI") >= 0 || StringFind(name, "MidBand") >= 0 || StringFind(name, "LowerBand") >= 0 || StringFind(name, "MACD(%d,%d,%d) %.6f -> MA(%d) %.2f -> Bands(%d) %.2f") >= 0 || StringFind(name, "UpperBand") >= 0) { ObjectDelete(name); Print("Deleted object: ", name); } } }