/* *** Morris MA *** Version 2 (29th May 2004) ** forex version ** use short duration bars e.g. 5min set length to give required speed of response increase damping to eliminate overshooting Lower length will require Higher damping */ //+##################################################################+ //| MMA.mq4 | //| Copyright © 2003,2004 Tim Morris | //| | //| MQL4 © 2005, Nikolay Kositsin | //| Khabarovsk | //+##################################################################+ #property copyright "" #property link "" #property indicator_chart_window #property indicator_buffers 1 #property indicator_color1 Red //---- input parameters extern int Length = 10;//inverse of driving coefficient extern int damping = 5;//smoothing (percent) extern int maxgap = 30;//maximum week gap ignored (pips) extern int Shift = 0; extern int CountBars = 300;//drawn per call - tune this to avoid //---- buffers double MMA_Buffer []; double MEM[32]; //---- double p=0.0, dmp=0.0, drv=0.0, gap=0.0; double n=0.0, k=0.0, d0=0.0, y0=0.0, y1=0.0, y2=0.0, mg=0.0, err=0.0; //+==================================================================+ //| Custom indicator initialization function | //+==================================================================+ int init() { string short_name; //---- drawing settings SetIndexStyle(0,DRAW_LINE); SetIndexDrawBegin(0, Bars-CountBars); //---- IndexShift SetIndexShift(0,Shift); //---- IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)); //---- name for DataWindow and indicator subwindow label SetIndexLabel (0, "Moris_MA"); IndicatorShortName ("Moris_MA (Length="+Length+", damping="+damping+", maxgap="+maxgap+", Shift="+Shift+")"); //---- indicator buffers mapping IndicatorBuffers(2); SetIndexBuffer(0, MMA_Buffer); SetIndexBuffer(1, MEM); k =1.0/Length; d0 = damping/100.0; mg = maxgap*Point; return(0); } //+==================================================================+ //| MMA | //+==================================================================+ int start() { int counted_bars=IndicatorCounted(); //---- check for possible errors if(counted_bars<0) return(-1); int bar=Bars-counted_bars-1; if (bar==Bars-1) { bar=bar-1; y0=(High[bar]+Low[bar])/2; MMA_Buffer[bar]=y0; MEM[bar+0]=y0; MEM[bar+1]=y0; MEM[bar+2]=y0; bar--; } while (bar>=0) { p=(High[bar]+Low[bar])/2.0; //week} gap compensation------------------------------------------+ if (bar>0&& bar30000) if ((High[bar]High[bar+1])) { gap=p-(High[bar+1]+Low[bar+1])/2.0; if (MathAbs(gap)>mg){MEM[bar+1]+=gap; MEM[bar+2]+=gap;} } //----------------------------------------------------------------+ //*** calculate new average position *** y1 = MEM[bar+1]; y2 = MEM[bar+2]; n = High[bar]-Low[bar];//consider H-L as noise level if(n==0)n=Point/100; err = (p-2.0*y1+y2)/n; //error is difference between price && straight line drv = MathMax(MathMin(k*err*err + k*MathAbs(err),0.5),0.0); //driving function = polynomial of error/noise //small moves have little effect, //big moves have big effect, //spikes have small effect dmp = MathMax(MathMin(k*MathAbs(y1-y2)/n + d0,1.0),0.0); //damping function = polynomial of gradient/noise //if average is moving fast but price isn't - put the brakes on. y0 = y1 + n*err*drv + (y1-y2)*(1.0-dmp); //new average = straight line less damping plus driving MEM[bar+0]=y0; MMA_Buffer[bar]=y0; bar--; } //---- done--- return(0); }