Line not displayed or scaled properly

 

Hi,

This is my first time customising my own indicator and I have a problem that I hope some seniors may help me with.

The problem I have now is my indicator's line graph won't draw properly because some values (outliers?) are astronomically high when compared to the rest. The result of this is, the other lesser values appearing as "flat" lines - or worse, being flattened to the bottom of the chart window.

Is there any way to resolve this? I'm not keen on modelling it as an oscillator tho'

Img atc for ref. This is how it appears when zoomed out to the max. It can also happen when there are several outliers in the area.

Zoom Out Max


This is how it appears when zoomed in 3x. It works sometimes, depending if the outliers are inside.

Zoomed in 3x

 

you can add a limit using if statement (i don't have your code so i'm going to write just the guide lines)

double Restrict = 65.0; // or any other value suits you
//code ....
buf_x[i] = your_calculation ...;
if(buf_x[i] >= Restrict)
   buf_x[i] = Restrict;
//code ...


(just an idea)

 
qjol:

you can add a limit using if statement (i don't have your code so i'm going to write just the guide lines)


(just an idea)


Thank for the idea gjol, and for replying so quickly!


Is the limit condition the same as manually limiting the indicator via the min-max limit check boxes? If it is, it's not really what I'm looking for. I am fine not showing negative values, but hiding the outliers is not what I want.

A good example of how the indicator should be scaled is by looking at the tick volume indicator. How do they do they do that?

 
HEvans:


Is the limit condition the same as manually limiting the indicator via the min-max limit check boxes?



i think so

HEvans:


A good example of how the indicator should be scaled is by looking at the tick volume indicator. How do they do they do that?


it's in the same window not a separate window

you can do it by using Objects

 

When you create an indicator you need to consider what the output will be and how it will be displayed.

It is obviously nonsensical to create and display values that range from <100 to >200,000 while expecting to discern differences of 1.0. That would be like trying to look at an entire map of the world at the same time as discerning individual streets. You might try using the sqare root of each value to bring it down to a scalaable size but even that might be still be too wide

 
SDC:

When you create an indicator you need to consider what the output will be and how it will be displayed.

It is obviously nonsensical to create and display values that range from <100 to >200,000 while expecting to discern differences of 1.0. That would be like trying to look at an entire map of the world at the same time as discerning individual streets. You might try using the sqare root of each value to bring it down to a scalaable size but even that might be still be too wide


Yep.

 

I did try another work around method to reduce the difference, but now I keep getting array out of range. Any ideas?

Debugger points to the VolBuffer array.

//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_color1  Maroon
#property  indicator_width1  2

//---- indicator parameters
extern int FastEMA=1;
extern int SlowEMA=26;

//---- indicator buffers
double     MacdBuffer[];
double     VolBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- drawing settings
   IndicatorBuffers(1);
   SetIndexStyle(0,DRAW_HISTOGRAM);

//---- indicator buffers mapping
   SetIndexBuffer(0,MacdBuffer);
   SetIndexBuffer(1,VolBuffer);

//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("MACD Volume-weighted("+FastEMA+","+SlowEMA+")");
   SetIndexLabel(0,"MACD Volume-weighted");
   return(0);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start()
  {
   int limit;
   int counted_bars=IndicatorCounted();
   
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
   
//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
     {
      VolBuffer[i] = Volume[i];
     }
   for(i=0; i<limit; i++)      
     {
      double EmaVolFast = iMAOnArray(VolBuffer,0,FastEMA,0,MODE_EMA,i);
      double EmaVolSlow = iMAOnArray(VolBuffer,0,SlowEMA,0,MODE_EMA,i);
      if(EmaVolFast!=0 && EmaVolSlow!=0)
        MacdBuffer[i] = ((EmaVolFast - EmaVolSlow) * 100) / EmaVolSlow;
     }

//---- done
   return(0);
  }
//+------------------------------------------------------------------+
 
HEvans:

I did try another work around method to reduce the difference, but now I keep getting array out of range. Any ideas?

Debugger points to the VolBuffer array.


I'm a real "genius" -- I didn't declare the buffer in global.

It should have been IndicatorBuffers(2) NOT (1).

Anyhow, could someone teach me how to limit the number of bars calculated? I want to keep my indi as light as possible.


Also, any comments on how I can improve? Is the structure fine? Are there unnecessary things? Generally, is the code optimised?

This is my 2nd try.

 
HEvans:

I'm a real "genius" -- I didn't declare the buffer in global.

It should have been IndicatorBuffers(2) NOT (1).

Anyhow, could someone teach me how to limit the number of bars calculated? I want to keep my indi as light as possible.


Also, any comments on how I can improve? Is the structure fine? Are there unnecessary things? Generally, is the code optimised?

This is my 2nd try.



May be so?


//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_color1  Maroon
#property  indicator_width1  2

//---- indicator parameters
extern int FastEMA=1;
extern int SlowEMA=26;

//---- indicator buffers
double     MacdBuffer[];
//double     VolBuffer[];
datetime time;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- drawing settings
   IndicatorBuffers(1);
   SetIndexStyle(0,DRAW_HISTOGRAM);

//---- indicator buffers mapping
   SetIndexBuffer(0,MacdBuffer);
//  SetIndexBuffer(1,VolBuffer);

//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("MACD Volume-weighted("+FastEMA+","+SlowEMA+")");
   SetIndexLabel(0,"MACD Volume-weighted");
   SetIndexDrawBegin(0,SlowEMA-1);
   return(0);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start()
  {
   int bars=Bars;
   datetime newtime=Time[0];
   int z=bars-IndicatorCounted();
   if(time==newtime && z<=2) return(0);
   time=newtime;

   if(bars<SlowEMA)
     {
      Alert("not enough bars");
      return(0);
     }

   int limit=SlowEMA;
   double Slow[],Fast[];
   ArrayResize(Slow,bars,bars);
   ArrayResize(Fast,bars,bars);

//---- calculation exponential moving average

   if(z>2)
     {
      limit=bars-2;
      Slow[limit+1]=Volume[limit+1];
      Fast[limit+1]=Volume[limit+1];
     }

   double SmoothFactor_Slow=2.0/(1.0+SlowEMA);
   double SmoothFactor_Fast=2.0/(1.0+FastEMA);

   for(int i=limit; i>=0; i--)
     {
      Slow[i]=Volume[i]*SmoothFactor_Slow+Slow[i+1]*(1.0-SmoothFactor_Slow);
      Fast[i]=Volume[i]*SmoothFactor_Fast+Fast[i+1]*(1.0-SmoothFactor_Fast);
      MacdBuffer[i]=((Fast[i]-Slow[i])*100)/Slow[i];
     }

//----

//  for(i=0; i<limit; i++)
//    {
//     VolBuffer[i]=Volume[i];
//    }
//  for(i=0; i<limit; i++)
//    {
//     double EmaVolFast = iMAOnArray(VolBuffer,0,FastEMA,0,MODE_EMA,i);
//     double EmaVolSlow = iMAOnArray(VolBuffer,0,SlowEMA,0,MODE_EMA,i);
//     if(EmaVolFast!=0 && EmaVolSlow!=0)
//        MacdBuffer[i]=((EmaVolFast-EmaVolSlow)*100)/EmaVolSlow;
///    }

//---- done
   return(0);
  }
//+------------------------------------------------------------------+
 
Boeing747:

May be so?



WOW. This is gonna take me some time to digest.

Thanks!

Reason: