[SOLVED] Indicator Changes Behavior after Initial Loop

 

Hello,

I have programmed an indicator which seems to work at first when placed on a chart but will change it's behavior when running. I know it has something to do with how I'm calculating Limit for the for loop. Maybe I'm missing something obvious...

Here's what I've got: (running on the M1 chart)


Here's the code:

#property  copyright "Hilton Global LLC 2014"
#property  version   "1.00"
#property  strict
#property  description "The Modified Moving Average indicator modifies a Moving Average in the following way:"
#property  description "The Modulated Moving Average (MMA) will remain flat until the price moves in a direction strong enough to overcome the Delta Parameter."
#property  description "The MMA will step to the new level and remain flat again until the Delta Parameter is overcome by another strong price movement."
#property  description "MMA is best used for reducing noise of a regular moving average."
#property  indicator_chart_window
#property  indicator_buffers 1
#property  indicator_color1  DarkOrange
#property  indicator_width1 2

extern int MAPeriod = 20; //Period of the Moving Avg.
extern int MAMethod = 1; //0=Simple, 1=Exponential, 2=Smoothed, 3=Linear Weighted
extern int MAAppliedTo = 4; //Applied Price: 0=C 1=O 2=H 3=L 4=(HL/2) 5=(HLC/3) 6=(HLCC/4)
extern double Delta = 0.5; //Modulation Factor (Delta)
extern string DeltaExplained = "Delta is the % by which the price must change before the MA will move.";
double prevStatic = 0.0;
int LastStatic = 0;
double StaticMABuffer[];

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(1);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexEmptyValue(0, 0.0);
   SetIndexLabel(0,"Modulated MA");
   IndicatorDigits(Digits);
   if(!SetIndexBuffer(0,StaticMABuffer)) {Print("cannot set indicator buffers!");}
   IndicatorShortName("Modulated MA("+IntegerToString(MAPeriod)+") Static Level: ("+DoubleToStr(Delta,2)+").");
   return(0);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int deinit(){return(0);}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int start()
  {
   int counted_bars = IndicatorCounted();
   if(counted_bars < 0) {return(-1);}
   int limit= Bars - counted_bars;
   if(counted_bars == 0) {limit--;} //else {limit++;}
   for (int i = limit; i > -1; i--)
   {
      prevStatic = iMA(NULL,0,MAPeriod,0,MAMethod,MAAppliedTo,LastStatic);
      
      StaticMABuffer[i] = shouldMAChange(i, Delta, prevStatic);
      
      if(StaticMABuffer[i] == 0){StaticMABuffer[i] = iMA(NULL,0,MAPeriod,0,MAMethod,MAAppliedTo,LastStatic);}
   }
   return(0);
  }
//+------------------------------------------------------------------+

double shouldMAChange(int index, double delta, double prevStatica)
{
   double DeltaUp = 1 + (delta * 0.001);
   double DeltaDn = 1 - (delta * 0.001);
   double Value = iMA(NULL,0,MAPeriod,0,MAMethod,MAAppliedTo,index);
   double ValueUp = prevStatica * DeltaUp;
   double ValueDn = prevStatica * DeltaDn;
   if(Value > ValueUp){LastStatic = index; return(Value);}
   if(Value < ValueDn){LastStatic = index; return(Value);}
   if(Value <= ValueUp && Value >= ValueDn){return(0);}
   return(0);
}


Exhibit A is the indicator working like it should. Exhibit B is where the indicator was placed on the chart. The chart then runs for a few minutes and will now create some weird bent MA. The MA should either stay flat or jump to a new level as in Exhibit A. It's hard to see in the picture, but there's a flat part of the MA that is two bars long at Exhibit C.

How can I make the indicator always act like Exhibit A in the picture?

Thank you for any insight you have.

 
Hiltos: The chart then runs for a few minutes and will now create some weird bent MA. T
LastStatic = index
Of course it does. As soon as a new bar forms LastStatic is pointing to the wrong bar..
Store lastTime= Time[LastStatic] and at the start of a new tick reset LastStatic = IbarShift(..., lastTime)
 
Oh what a graceful way to handle that! Thank you so much!
Reason: