Merging of MACD and RSI

 

This indicator has on the chart buttons that makes it switch between RSI and MACD. The problem is in the fixed min and max in the common tab, there is a prominent difference in readings between MACD and RSI which is the levels. RSI oscillates between 30 and 70 with variations according to the period chosen, while MACD is way tiny as it ranges between 1 and -1, sometimes with readings much less than that.


The "fixed minimum and maximum check" which stays as they are in the indicator settings "either checked or unchecked", i couldn't find a way to switch being checked automatically when using the buttons to switch from RSI to MACD. Is there a possible way to do that? 


#property strict
#property indicator_separate_window
#property indicator_minimum    0
#property indicator_maximum    100
#property indicator_buffers 7
#property indicator_plots   7
#property indicator_level1     30.0
#property indicator_level3     50.0
#property indicator_level5     70.0
#property indicator_levelcolor clrSilver
#property indicator_levelstyle STYLE_DOT

#include <MovingAverages.mqh>

// Input Parameters
input string Separator1 = "-------------------MACD1 Settings-------------------";
input int    InpFastEMA1 = 12;               // Fast EMA1 Period
input int    InpSlowEMA1 = 26;               // Slow EMA1 Period
input int    InpSignalSMA1 = 9;             // Signal SMA1 Period

input string Separator2 = "-------------------MACD2 Settings-------------------";
input int    InpFastEMA2 = 12;               // Fast EMA2 Period
input int    InpSlowEMA2 = 26;               // Slow EMA2 Period
input int    InpSignalSMA2 = 9;             // Signal SMA2 Period

input string Separator3 = "-------------------RSI Settings-------------------";
input int    RSI1_Period = 14;               // RSI1 Period
input int    RSI2_Period = 18;               // RSI2 Period
input int    RSI3_Period = 25;              // RSI3 Period

input string ButtonSeparator = "-------------------Button Settings-------------------";
input int    ButtonX = 150;                 // X position of buttons
input int    ButtonY = 20;                  // Y position of buttons
input int    ButtonWidth = 127;             // Width of buttons
input int    ButtonHeight = 30;             // Height of buttons
input int    ButtonSpacing = 30;            // Spacing between buttons
input int    ButtonCorner = CORNER_LEFT_UPPER;  // Corner for button placement

input color  ButtonTextColor = clrWhite;    // Button Text Color
input color  ButtonBackgroundColor = clrDodgerBlue; // Button Background Color

// Indicator buffers
double ExtMacdBuffer1[];
double ExtSignalBuffer1[];
double ExtMacdBuffer2[];
double ExtSignalBuffer2[];
double RSI1_Buffer[];
double RSI2_Buffer[];
double RSI3_Buffer[];

// Global variables for colors
color OriginalMacdColor1 = Silver;
color OriginalSignalColor1 = Red;
color OriginalMacdColor2 = Green;
color OriginalSignalColor2 = Blue;
color OriginalRSI1Color = Red;
color OriginalRSI2Color = DarkGoldenrod;
color OriginalRSI3Color = DodgerBlue;

bool ExtParameters = false;

int OnInit()
{
    IndicatorDigits(Digits + 1);
    
    // Set up MACD1
    SetIndexBuffer(0, ExtMacdBuffer1);
    SetIndexBuffer(1, ExtSignalBuffer1);
    SetIndexStyle(0, DRAW_HISTOGRAM, STYLE_SOLID, 2, OriginalMacdColor1);
    SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 1, OriginalSignalColor1);
    SetIndexLabel(0, "MACD1");
    SetIndexLabel(1, "Signal1");
    
    // Set up MACD2
    SetIndexBuffer(2, ExtMacdBuffer2);
    SetIndexBuffer(3, ExtSignalBuffer2);
    SetIndexStyle(2, DRAW_HISTOGRAM, STYLE_SOLID, 2, OriginalMacdColor2);
    SetIndexStyle(3, DRAW_LINE, STYLE_SOLID, 1, OriginalSignalColor2);
    SetIndexLabel(2, "MACD2");
    SetIndexLabel(3, "Signal2");
    
    // Set up RSI1, RSI2, RSI3
    SetIndexBuffer(4, RSI1_Buffer);
    SetIndexBuffer(5, RSI2_Buffer);
    SetIndexBuffer(6, RSI3_Buffer);
    SetIndexStyle(4, DRAW_LINE, STYLE_SOLID, 2, OriginalRSI1Color);
    SetIndexStyle(5, DRAW_LINE, STYLE_SOLID, 2, OriginalRSI2Color);
    SetIndexStyle(6, DRAW_LINE, STYLE_SOLID, 1, OriginalRSI3Color);
    SetIndexLabel(4, "RSI1");
    SetIndexLabel(5, "RSI2");
    SetIndexLabel(6, "RSI3");
    
    IndicatorShortName("Merged MACD and RSI");
    
    if ((InpFastEMA1 <= 1 || InpSlowEMA1 <= 1 || InpSignalSMA1 <= 1 || InpFastEMA1 >= InpSlowEMA1) ||
        (InpFastEMA2 <= 1 || InpSlowEMA2 <= 1 || InpSignalSMA2 <= 1 || InpFastEMA2 >= InpSlowEMA2))
    {
        Print("Wrong input parameters");
        ExtParameters = false;
        return(INIT_FAILED);
    }
    else
        ExtParameters = true;

    // Create buttons
    CreateButton("ButtonMACD1", "Show MACD1", ButtonX, ButtonY, ButtonWidth, ButtonHeight);
    CreateButton("ButtonMACD2", "Show MACD2", ButtonX, ButtonY + ButtonSpacing, ButtonWidth, ButtonHeight);
    CreateButton("ButtonRSI1", "Show RSI1", ButtonX, ButtonY + 2*ButtonSpacing, ButtonWidth, ButtonHeight);
    CreateButton("ButtonRSI2", "Show RSI2", ButtonX, ButtonY + 3*ButtonSpacing, ButtonWidth, ButtonHeight);
    CreateButton("ButtonRSI3", "Show RSI3", ButtonX, ButtonY + 4*ButtonSpacing, ButtonWidth, ButtonHeight);

    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[])
{
    if (rates_total <= InpSignalSMA1 || rates_total <= InpSignalSMA2 || !ExtParameters)
        return(0);
        
    int limit = rates_total - prev_calculated;
    if (prev_calculated > 0)
        limit++;
        
    // Calculate MACD1 and MACD2
    for (int i = 0; i < limit; i++)
    {
        ExtMacdBuffer1[i] = iMA(NULL, 0, InpFastEMA1, 0, MODE_EMA, PRICE_CLOSE, i) -
            iMA(NULL, 0, InpSlowEMA1, 0, MODE_EMA, PRICE_CLOSE, i);
        ExtMacdBuffer2[i] = iMA(NULL, 0, InpFastEMA2, 0, MODE_EMA, PRICE_CLOSE, i) -
            iMA(NULL, 0, InpSlowEMA2, 0, MODE_EMA, PRICE_CLOSE, i);
    }
    SimpleMAOnBuffer(rates_total, prev_calculated, 0, InpSignalSMA1, ExtMacdBuffer1, ExtSignalBuffer1);
    SimpleMAOnBuffer(rates_total, prev_calculated, 0, InpSignalSMA2, ExtMacdBuffer2, ExtSignalBuffer2);
    
    // Calculate RSI1, RSI2, RSI3
    for (int i = 0; i < limit; i++)
    {
        RSI1_Buffer[i] = iRSI(NULL, 0, RSI1_Period, PRICE_CLOSE, i);
        RSI2_Buffer[i] = iRSI(NULL, 0, RSI2_Period, PRICE_CLOSE, i);
        RSI3_Buffer[i] = iRSI(NULL, 0, RSI3_Period, PRICE_CLOSE, i);
    }
    
    return(rates_total);
}

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
    if (id == CHARTEVENT_OBJECT_CLICK)
    {
        if (sparam == "ButtonMACD1")
        {
            ShowOnlyOne(0);
            ResetButtonState("ButtonMACD1");
        }
        else if (sparam == "ButtonMACD2")
        {
            ShowOnlyOne(2);
            ResetButtonState("ButtonMACD2");
        }
        else if (sparam == "ButtonRSI1")
        {
            ShowOnlyOne(4);
            ResetButtonState("ButtonRSI1");
        }
        else if (sparam == "ButtonRSI2")
        {
            ShowOnlyOne(5);
            ResetButtonState("ButtonRSI2");
        }
        else if (sparam == "ButtonRSI3")
        {
            ShowOnlyOne(6);
            ResetButtonState("ButtonRSI3");
        }
    }
}

void ShowOnlyOne(int index)
{
    for (int i = 0; i < 7; i++)
    {
        if (i == index || (i == index + 1 && index < 4))  // For MACD, show both histogram and signal line
        {
            switch(i)
            {
                case 0: SetIndexStyle(i, DRAW_HISTOGRAM, STYLE_SOLID, 2, OriginalMacdColor1); break;
                case 1: SetIndexStyle(i, DRAW_LINE, STYLE_SOLID, 1, OriginalSignalColor1); break;
                case 2: SetIndexStyle(i, DRAW_HISTOGRAM, STYLE_SOLID, 2, OriginalMacdColor2); break;
                case 3: SetIndexStyle(i, DRAW_LINE, STYLE_SOLID, 1, OriginalSignalColor2); break;
                case 4: SetIndexStyle(i, DRAW_LINE, STYLE_SOLID, 2, OriginalRSI1Color); break;
                case 5: SetIndexStyle(i, DRAW_LINE, STYLE_SOLID, 2, OriginalRSI2Color); break;
                case 6: SetIndexStyle(i, DRAW_LINE, STYLE_SOLID, 2, OriginalRSI3Color); break;
            }
        }
        else
        {
            SetIndexStyle(i, DRAW_NONE);
        }
    }
    ChartRedraw();
}

void CreateButton(string name, string label, int x, int y, int width, int height)
{
    if (!ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0))
        Print("Failed to create the button ", name);
    ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
    ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
    ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
    ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
    ObjectSetString(0, name, OBJPROP_TEXT, label);
    ObjectSetInteger(0, name, OBJPROP_CORNER, ButtonCorner);
    ObjectSetInteger(0, name, OBJPROP_COLOR, ButtonTextColor);
    ObjectSetInteger(0, name, OBJPROP_BGCOLOR, ButtonBackgroundColor);
    ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
    ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
}

void ResetButtonState(string name)
{
    ObjectSetInteger(0, name, OBJPROP_STATE, 0);
}

void OnDeinit(const int reason)
{
    ObjectDelete(0, "ButtonMACD1");
    ObjectDelete(0, "ButtonMACD2");
    ObjectDelete(0, "ButtonRSI1");
    ObjectDelete(0, "ButtonRSI2");
    ObjectDelete(0, "ButtonRSI3");
}
 
You need to modify the fixed min/max properties in the indicator's OnChartEvent function when the buttons are clicked. Specifically, for the RSI, you'll set the min/max range between 0 and 100, and for MACD, you can set a different, narrower range based on the typical MACD values (e.g., between -1 and 1).
 
Nardus Van Staden #:
You need to modify the fixed min/max properties in the indicator's OnChartEvent function when the buttons are clicked. Specifically, for the RSI, you'll set the min/max range between 0 and 100, and for MACD, you can set a different, narrower range based on the typical MACD values (e.g., between -1 and 1).

thank you, this was set right with the RSI but when it comes to MACD the lines and the histogram becomes so tiny to the point it will be difficult to show and will have to uncheck the min/max to make it dynamic every time i want to switch to MACD on the chart

 

Hi

Perhaps you can simply don’t use Fixed min and max then the values of the indicators will be arranged to fill the indicator window.

I know it’s not the best solution but this way results will be visible in both options.

Have a nice day👍📊

 
Make a global int variable to make the correct min and max for RSI when it is one value (0) and make the correct min and max for macd when it's set to another value (1). Set the values of the global variable within the on chart event and assign the indicator minimum and maximum appropriately 

This is an mql5 forum. And you should be in mql4 section
 
Conor Mcnamara #: This is an mql5 forum. And you should be in mql4 section

Correct. Post your MT4 question in the MQL4 section instead of the MT5 Indicators section , (bottom of the Root page)?
          General rules and best pratices of the Forum. - General - MQL5 programming forum? (2017)
Next time, post in the correct place. I have moved this thread.