Assistance Required – Chart Display Issues

 

Hello everyone,

I'm currently facing an issue with my chart script. Although there are no errors in the code, the singleline2 is not appearing on the chart. Additionally, the MA2 Histogram is extending across the entire chart(attached), which is not the intended behavior.

I would appreciate any insights or suggestions on how to resolve these issues. Thank you in advance for your help!

Best regards,


#property indicator_plots 4
#property indicator_buffers 7  // Added buffer count declaration

//--- Plot 1 settings
#property indicator_label1  "MA1 Histogram"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrDarkSlateBlue
#property indicator_width1  6

//--- Plot 2 settings
#property indicator_label2  "MA2 Histogram"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrMaroon
#property indicator_width2  6

//--- Plot 3 settings
#property indicator_label3  "Signal Line"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrYellow
#property indicator_width3  1

//--- Plot 4 settings
#property indicator_label4  "Signal Line2"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrMediumTurquoise
#property indicator_width4  1

//--- Include required libraries
#include <MovingAverages.mqh>

//--- Input parameters
input int                 ma_1 = 28;
input int                 ma_2 = 144;
input ENUM_MA_METHOD      method = MODE_LWMA;
input ENUM_APPLIED_PRICE  price = PRICE_CLOSE;
input int                 signal = 14;
input ENUM_MA_METHOD      s_method = MODE_SMA;
input int                 signal2 = 70;
input ENUM_MA_METHOD      s_method2 = MODE_SMA;
input color               color1 = clrDarkSlateBlue;
input color               color2 = clrMaroon;
input color               color3 = clrYellow;
input color               color4 = clrMediumTurquoise;

//--- Indicator buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double SignalLine[];
double SignalLine2[];
double MACD_Map[];
double SignalMap[];
double SignalMap2[];

//--- MA handles
int ma1_handle;
int ma2_handle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    //--- Set buffer allocations
    SetIndexBuffer(0, ExtMapBuffer1, INDICATOR_DATA);
    SetIndexBuffer(1, ExtMapBuffer2, INDICATOR_DATA);
    SetIndexBuffer(2, SignalLine, INDICATOR_DATA);
    SetIndexBuffer(3, SignalLine2, INDICATOR_DATA);
    SetIndexBuffer(4, MACD_Map, INDICATOR_CALCULATIONS);
    SetIndexBuffer(5, SignalMap, INDICATOR_CALCULATIONS);
    SetIndexBuffer(6, SignalMap2, INDICATOR_CALCULATIONS);

    //--- Initialize MA handles
    ma1_handle = iMA(_Symbol, _Period, ma_1, 0, method, price);
    ma2_handle = iMA(_Symbol, _Period, ma_2, 0, method, price);
    
    if(ma1_handle == INVALID_HANDLE || ma2_handle == INVALID_HANDLE)
    {
        Print("Error creating MA handles");
        return(INIT_FAILED);
    }

   
    
    //--- Set empty value for data buffers
    PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
    PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
{
    //--- Check for minimum bars
    if(rates_total < MathMax(ma_1, ma_2))
        return(0);

    //--- Calculate position
    int start_pos;
    if(prev_calculated == 0)
    {
        start_pos = 0;
        ArrayInitialize(ExtMapBuffer1, EMPTY_VALUE);
        ArrayInitialize(ExtMapBuffer2, EMPTY_VALUE);
        ArrayInitialize(SignalLine, EMPTY_VALUE);
        ArrayInitialize(SignalLine2, EMPTY_VALUE);
    }
    else
        start_pos = prev_calculated - 1;

    //--- Copy MA values
    if(CopyBuffer(ma1_handle, 0, 0, rates_total - start_pos, ExtMapBuffer1) <= 0)
        return(0);
    if(CopyBuffer(ma2_handle, 0, 0, rates_total - start_pos, ExtMapBuffer2) <= 0)
        return(0);

    //--- Calculate MACD Map
    for(int i = start_pos; i < rates_total; i++)
        MACD_Map[i] = ExtMapBuffer1[i] - ExtMapBuffer2[i];

    //--- Calculate Signal Maps
    switch(s_method)
    {
        case MODE_SMA:
            SimpleMAOnBuffer(rates_total, prev_calculated, 0, signal, MACD_Map, SignalMap);
            break;
        case MODE_EMA:
            ExponentialMAOnBuffer(rates_total, prev_calculated, 0, signal, MACD_Map, SignalMap);
            break;
        case MODE_SMMA:
            SmoothedMAOnBuffer(rates_total, prev_calculated, 0, signal, MACD_Map, SignalMap);
            break;
        case MODE_LWMA:
            LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, signal, MACD_Map, SignalMap);
            break;
    }

    switch(s_method2)
    {
        case MODE_SMA:
            SimpleMAOnBuffer(rates_total, prev_calculated, 0, signal2, MACD_Map, SignalMap2);
            break;
        case MODE_EMA:
            ExponentialMAOnBuffer(rates_total, prev_calculated, 0, signal2, MACD_Map, SignalMap2);
            break;
        case MODE_SMMA:
            SmoothedMAOnBuffer(rates_total, prev_calculated, 0, signal2, MACD_Map, SignalMap2);
            break;
        case MODE_LWMA:
            LinearWeightedMAOnBuffer(rates_total, prev_calculated, 0, signal2, MACD_Map, SignalMap2);
            break;
    }

    //--- Calculate final signal lines
    for(int i = start_pos; i < rates_total; i++)
    {
        SignalLine[i] = ExtMapBuffer2[i] + SignalMap[i];
        SignalLine2[i] = ExtMapBuffer2[i] + SignalMap2[i];
    }

    return(rates_total);
 

It's not ideal to make copybuffer return 0 if an error is encountered, it can be destructive because it can stop the indicator calculating...return rates_total, or just print an error message

You should not copy rates_total - prev_calculated, it will miss incoming data.


adjust it to this:

int to_copy;

if(prev_calculated > rates_total || prev_calculated < 0)
{
      to_copy = rates_total;
}
else
{
      to_copy = rates_total - prev_calculated + 1;
}

 //--- Copy MA values
    if(CopyBuffer(ma1_handle, 0, 0, to_copy, ExtMapBuffer1) <= 0)
        return(rates_total);
    if(CopyBuffer(ma2_handle, 0, 0, to_copy, ExtMapBuffer2) <= 0)
        return(rates_total);


check this blog post so you understand:

https://www.mql5.com/en/blogs/post/760917

Indicator calculation loops and the start index
Indicator calculation loops and the start index
  • www.mql5.com
When an indicator first loads, prev_calculated is 0 on the first execution. On subsequent calls, prev_calculated holds the number of bars processed in the previous execution. So when the indicator has
 

Hi Conor 

Thank you for your assistance. I have implemented some updates, but the issue persists. Could you please provide further guidance or insights to help resolve this matter? 


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 < MathMax(ma_1, ma_2)) return(0);

    //--- Handle data copy
    int to_copy;
    if(prev_calculated > rates_total || prev_calculated < 0)
        to_copy = rates_total;
    else
        to_copy = rates_total - prev_calculated + 1;

    //--- Copy MA values
    if(CopyBuffer(ma1_handle, 0, 0, to_copy, ExtMapBuffer1) <= 0 ||
       CopyBuffer(ma2_handle, 0, 0, to_copy, ExtMapBuffer2) <= 0)
    {
        return(prev_calculated);
    }

    //--- Calculate positions
    int start_pos = (prev_calculated < 1) ? 0 : prev_calculated - 1;

    //--- Calculate MACD values
    for(int i = start_pos; i < rates_total && !IsStopped(); i++)
        MACD_Map[i] = ExtMapBuffer1[i] - ExtMapBuffer2[i];

    //--- Calculate signal lines using proper MQL5 moving averages
    CalculateMA(s_method, signal, MACD_Map, SignalMap, rates_total, prev_calculated);
    CalculateMA(s_method2, signal2, MACD_Map, SignalMap2, rates_total, prev_calculated);

    //--- Update output buffers
    for(int i = start_pos; i < rates_total && !IsStopped(); i++)
    {
        SignalLine[i] = ExtMapBuffer2[i] + SignalMap[i];
        SignalLine2[i] = ExtMapBuffer2[i] + SignalMap2[i];
    }

    return(rates_total);
}

//+------------------------------------------------------------------+
//| Custom MA calculation function                                   |
//+------------------------------------------------------------------+
void CalculateMA(ENUM_MA_METHOD ma_method, int period, double &src[], double &dst[], int rates_total, int prev_calculated)
{
    int start_pos = (prev_calculated < 1) ? 0 : prev_calculated - 1;
    
    switch(ma_method)
    {
        case MODE_SMA:
            SimpleMAOnBuffer(rates_total, prev_calculated, start_pos, period, src, dst);
            break;
        case MODE_EMA:
            ExponentialMAOnBuffer(rates_total, prev_calculated, start_pos, period, src, dst);
            break;
        case MODE_SMMA:
            SmoothedMAOnBuffer(rates_total, prev_calculated, start_pos, period, src, dst);
            break;
        case MODE_LWMA:
            LinearWeightedMAOnBuffer(rates_total, prev_calculated, start_pos, period, src, dst);
            break;
    }
}