Issue with double-buffered plots (e.g. DRAW_COLOR_LINE) causing subsequent arrow plot to ignore arrow code and render as circle.

 

Hi all,

I’m encountering a rendering quirk with a multi-plot indicator involving arrows and moving averages.

  • Plot 0: Arrow down at bar highs ( DRAW_ARROW , arrow code 233) — renders correctly as expected.

  • Plot 1: Moving average originally drawn as DRAW_LINE (single buffer) — works fine.

  • Plot 1 changed to a plot type that requires two buffers (e.g., DRAW_COLOR_LINE ), using a separate color index buffer.

  • Plot 2: Arrow up at bar lows ( DRAW_ARROW , arrow code 234) — still plots, but ignores the PlotIndexSetInteger(3, PLOT_ARROW, 234) setting and renders as a generic circle instead of the intended arrow.

This issue is not limited to DRAW_COLOR_LINE , but occurs with any plot type requiring two buffers.

When the MA plot is a single-buffer plot ( DRAW_LINE ), both arrows render correctly.

Switching the MA to a double-buffer plot causes the second arrow’s glyph to be ignored and replaced with a circle.


Below is a minimal proof-of-concept example illustrating this behavior:

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   3

//--- Plot 1: Arrow Down at High
#property indicator_label1  "ArrowDownHigh"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- Plot 2: Simple Moving Average
#property indicator_label2  "MovingAverage"
#property indicator_type2   DRAW_COLOR_LINE
#property indicator_color2  clrWhite
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

//--- Plot 3: Arrow Up at Low
#property indicator_label3  "ArrowUpLow"
#property indicator_type3   DRAW_ARROW
#property indicator_color3  clrLime
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

//--- Buffers
double ArrowDownHigh[];
double MA[];
double ColorLineColors[];
double ArrowUpLow[];

input int MAPeriod = 14;

//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, ArrowDownHigh, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_ARROW, 233);

   SetIndexBuffer(1, MA, INDICATOR_DATA);

   SetIndexBuffer(2, ColorLineColors, INDICATOR_COLOR_INDEX);

   SetIndexBuffer(3, ArrowUpLow, INDICATOR_DATA);
   PlotIndexSetInteger(3, PLOT_ARROW, 234);

   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;
}
//+------------------------------------------------------------------+
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 &real_volume[],
                const int &spread[])
{
   if (rates_total < MAPeriod)
      return 0;

   int start = MathMax(prev_calculated - 1, MAPeriod);

   for (int i = start; i < rates_total; i++)
      {
         // SMA calculation
         double sum = 0.0;
         for (int j = 0; j < MAPeriod; j++)
            sum += close[i - j];
         MA[i] = sum / MAPeriod;

         // Arrows at highs and lows
         ArrowDownHigh[i] = high[i];
         ArrowUpLow[i]    = low[i];
      }

   return rates_total;
}
//+------------------------------------------------------------------+


Has anyone encountered this? Any ideas on how to force proper arrow glyphs alongside double-buffer plots?

Thanks in advance.

 
Paul Edunyu Carissimo:

Hi all,

I’m encountering a rendering quirk with a multi-plot indicator involving arrows and moving averages.

  • Plot 0: Arrow down at bar highs ( DRAW_ARROW , arrow code 233) — renders correctly as expected.

  • Plot 1: Moving average originally drawn as DRAW_LINE (single buffer) — works fine.

  • Plot 1 changed to a plot type that requires two buffers (e.g., DRAW_COLOR_LINE ), using a separate color index buffer.

  • Plot 2: Arrow up at bar lows ( DRAW_ARROW , arrow code 234) — still plots, but ignores the PlotIndexSetInteger(3, PLOT_ARROW, 234) setting and renders as a generic circle instead of the intended arrow.


Plot 2 with index 3 ?

You are confused and mix buffers and plots. 4 buffers from 0 to 3 and 3 plots for 0 to 2.

 
Alain Verleyen #:

Plot 2 with index 3 ?

You are confused and mix buffers and plots. 4 buffers from 0 to 3 and 3 plots for 0 to 2.

It's not confusion if you're looking at it from the perspective of OnInit(), regardless, the issue(bug?) still persists.

 
Paul Edunyu Carissimo #:

It's not confusion if you're looking at it from the perspective of OnInit(), regardless, the issue(bug?) still persists.

An other one who can't listen. Good luck.

 
Paul Edunyu Carissimo #It's not confusion if you're looking at it from the perspective of OnInit(), regardless, the issue(bug?) still persists.

The detail Alain mentioned is key: PlotIndexSetInteger() works with plot indices, not buffer indices. As you declared only 3 plots (#property indicator_plots 3), the valid indices are 0, 1 and 2. The index 3 you used is not valid as a plot, that's why the arrow code was not applied and a generic symbol is displayed.

You just need to change that line to:

PlotIndexSetInteger(2, PLOT_ARROW, 234);
 
Miguel Angel Vico Alba #:

The detail Alain mentioned is key: PlotIndexSetInteger() works with plot indices, not buffer indices. As you declared only 3 plots (#property indicator_plots 3), the valid indices are 0, 1 and 2. The index 3 you used is not valid as a plot, that's why the arrow code was not applied and a generic symbol is displayed.

You just need to change that line to:

So basically ?

 SetIndexBuffer(0, ArrowDownHigh, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_ARROW, 233);

   SetIndexBuffer(1, MA, INDICATOR_DATA);

   SetIndexBuffer(2, ColorLineColors, INDICATOR_COLOR_INDEX);

   SetIndexBuffer(3, ArrowUpLow, INDICATOR_DATA);
   PlotIndexSetInteger(2, PLOT_ARROW, 234);
 
Alain Verleyen #:

An other one who can't listen. Good luck.

I'm sorry you feel that way but your instructions were vague,@Miguel Angel Vico Alba articulated what you meant to say well, and if this :

   SetIndexBuffer(3, ArrowUpLow, INDICATOR_DATA);
   PlotIndexSetInteger(2, PLOT_ARROW, 234);

 is the right way to do it, I didn't see such an explanation in documentation or I may have missed it.

 
Just to wrap up: what Alain pointed out was correct from the start, the key is not to confuse plot indices with buffer indices.

In this case, since only 3 plots were declared, the valid indices for PlotIndexSetInteger() are 0, 1, and 2. Using index 3, even if it's tied to a valid buffer, has no effect because it's not associated with any plot.

Thread closed. 😉
 
Miguel Angel Vico Alba #:
Just to wrap up: what Alain pointed out was correct from the start, the key is not to confuse plot indices with buffer indices.

In this case, since only 3 plots were declared, the valid indices for PlotIndexSetInteger() are 0, 1, and 2. Using index 3, even if it's tied to a valid buffer, has no effect because it's not associated with any plot.

Thread closed. 😉

Yes , with your explanation expounding on what he said, what he pointed out was correct after all.

Thank you, I understand this now, thread closed indeed.