/*
*** 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&& bar<Bars-1)
if (Time[bar]-Time[bar+1]>30000)
if ((High[bar]<Low[bar+1])||(Low[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);
}
Comments