//+------------------------------------------------------------------+ //| MAMA_v1.mq4 | //| Copyright © 2009, TrendLaboratory | //| http://finance.groups.yahoo.com/group/TrendLaboratory | //| E-mail: igorad2003@yahoo.co.uk | //+------------------------------------------------------------------+ // List of Prices: // Price = 0 - Close // Price = 1 - Open // Price = 2 - High // Price = 3 - Low // Price = 4 - Median Price = (High+Low)/2 // Price = 5 - Typical Price = (High+Low+Close)/3 // Price = 6 - Weighted Close = (High+Low+Close*2)/4 // Price = 7 - Heiken Ashi Close // Price = 8 - Heiken Ashi Open // Price = 9 - Heiken Ashi High // Price =10 - Heiken Ashi Low #property copyright "Copyright © 2009, TrendLaboratory" #property link "http://finance.groups.yahoo.com/group/TrendLaboratory" #property indicator_chart_window #property indicator_buffers 4 #property indicator_color1 Yellow #property indicator_width1 1 #property indicator_color2 SkyBlue #property indicator_width2 1 #property indicator_color3 SkyBlue #property indicator_width3 2 #property indicator_color4 Tomato #property indicator_width4 2 //---- extern int TimeFrame = 0; //Time Frame in min extern int Price = 4; //Price Mode (0...10) extern double FastLimit = 0.5; //Laguerre Period(or Order,max=10) extern double SlowLimit = 0.05; //Adaptive Factor Length extern int SignalMode = 1; //Switch of Signal mode(0-off,1-on) extern int AlertMode = 0; //Sound Alert switch(0...2) extern int WarningMode = 0; //Warning Mode (0-off,1-on) //---- double MAMA[]; double FAMA[]; double UpSignal[]; double DnSignal[]; double sig[]; //---- double haClose[], haOpen[], haHigh[], haLow[]; int draw_begin, pBars, mcnt_bars, per; string short_name1, short_name2; datetime pTime; bool UpTrendAlert=false, DnTrendAlert=false; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- SetIndexStyle(0,DRAW_LINE); SetIndexStyle(1,DRAW_LINE); SetIndexStyle(2,DRAW_ARROW); SetIndexArrow(2,159); SetIndexStyle(3,DRAW_ARROW); SetIndexArrow(3,159); if(TimeFrame == 0 || TimeFrame < Period()) TimeFrame = Period(); per = 2/SlowLimit; draw_begin=2*per*TimeFrame/Period(); //---- switch(TimeFrame) { case 1 : string TF = "M1"; break; case 5 : TF = "M5"; break; case 15 : TF = "M15"; break; case 30 : TF = "M30"; break; case 60 : TF = "H1"; break; case 240 : TF ="H4"; break; case 1440 : TF="D1"; break; case 10080 : TF="W1"; break; case 43200 : TF="MN1"; break; default : TF="Current"; } short_name1 = "MAMA"; short_name2 = "FAMA"; IndicatorShortName(short_name1+"("+DoubleToStr(FastLimit,2)+","+DoubleToStr(SlowLimit,2)+")"+" "+TF); SetIndexLabel(0,short_name1+"("+DoubleToStr(FastLimit,2)+","+DoubleToStr(SlowLimit,2)+")"+" "+TF); SetIndexLabel(1,short_name2+"("+DoubleToStr(FastLimit,2)+","+DoubleToStr(SlowLimit,2)+")"+" "+TF); SetIndexLabel(2,"UpSignal"); SetIndexLabel(3,"DnSignal"); SetIndexDrawBegin(0,draw_begin); SetIndexDrawBegin(1,draw_begin); SetIndexDrawBegin(2,draw_begin); SetIndexDrawBegin(3,draw_begin); //---- IndicatorBuffers(5); SetIndexBuffer(0,MAMA); SetIndexBuffer(1,FAMA); SetIndexBuffer(2,UpSignal); SetIndexBuffer(3,DnSignal); SetIndexBuffer(4,sig); //---- return(0); } //+------------------------------------------------------------------+ //| MAMA_v1 | //+------------------------------------------------------------------+ int start() { int limit, y, i, shift, cnt_bars=IndicatorCounted(); double price[], mMAMA[], mFAMA[], Smooth[], Detrender[], Q1[], I1[], JL[], JQ[], I2[], Q2[], Re[], Im[], period[], Phase[], mUpsig[], mDnsig[], trend[]; if(TimeFrame!=Period()) int mBars = iBars(NULL,TimeFrame); else mBars = Bars; if(mBars != pBars) { ArrayResize(price,mBars); ArrayResize(mMAMA,mBars); ArrayResize(mFAMA,mBars); ArrayResize(Smooth,mBars); ArrayResize(Detrender,mBars); ArrayResize(Q1,mBars); ArrayResize(I1,mBars); ArrayResize(JL,mBars); ArrayResize(JQ,mBars); ArrayResize(I2,mBars); ArrayResize(Q2,mBars); ArrayResize(Re,mBars); ArrayResize(Im,mBars); ArrayResize(period,mBars); ArrayResize(Phase,mBars); if(Price > 6 && Price <= 10) { ArrayResize(haClose,mBars); ArrayResize(haOpen,mBars); ArrayResize(haHigh,mBars); ArrayResize(haLow,mBars); } if(SignalMode>0) { ArrayResize(trend,mBars); ArrayResize(mUpsig,mBars); ArrayResize(mDnsig,mBars); } pBars = mBars; } if(cnt_bars<1) { for(i=Bars-1;i>0;i--) { MAMA[i]=EMPTY_VALUE; FAMA[i]=EMPTY_VALUE; UpSignal[i]=EMPTY_VALUE; DnSignal[i]=EMPTY_VALUE; } mcnt_bars = 0; } //---- if(mcnt_bars > 0) mcnt_bars--; for(y=mcnt_bars;y 6 && Price <= 10) price[y] = HeikenAshi(TimeFrame,Price-7,mBars-y-1); if(y >= 3) Smooth[y] = (4*price[y] + 3*price[y-1] + 2*price[y-2] + price[y-3])/10.0; Detrender[y] = (0.0962*Smooth[y] + 0.5769*Smooth[y-2] - 0.5769*Smooth[y-4] - 0.0962*Smooth[y-6])*(0.075*period[y-1] + 0.54); Q1[y] = (0.0962*Detrender[y] + 0.5769*Detrender[y-2] - 0.5769*Detrender[y-4] - 0.0962*Detrender[y-6])*(0.075*period[y-1] + 0.54); I1[y] = Detrender[y-3]; JL[y] = (0.0962*I1[y] + 0.5769*I1[y-2] - 0.5769*I1[y-4] - 0.0962*I1[y-6])*(0.075*period[y-1] + 0.54); JQ[y] = (0.0962*Q1[y] + 0.5769*Q1[y-2] - 0.5769*Q1[y-4] - 0.0962*Q1[y-6])*(0.075*period[y-1] + 0.54); I2[y] = I1[y] - JQ[y]; Q2[y] = Q1[y] + JL[y]; I2[y] = 0.2*I2[y] + 0.8*I2[y-1]; Q2[y] = 0.2*Q2[y] + 0.8*Q2[y-1]; Re[y] = I2[y]*I2[y-1] + Q2[y]*Q2[y-1]; Im[y] = I2[y]*Q2[y-1] - Q2[y]*I2[y-1]; Re[y] = 0.2*Re[y] + 0.8*Re[y-1]; Im[y] = 0.2*Im[y] + 0.8*Im[y-1]; double rad2Deg = 45.0/MathArctan(1); if(Im[y] != 0 && Re[y] != 0) period[y] = 360.0/MathArctan(Im[y]/Re[y])/rad2Deg; if(period[y] > 1.5 *period[y-1]) period[y] = 1.5*period[y-1]; if(period[y] < 0.67*period[y-1]) period[y] = 0.67*period[y-1]; if(period[y] < 6) period[y] = 6; if(period[y] > 50) period[y] = 50; period[y] = 0.2*period[y] + 0.8*period[y-1]; if(I1[y] != 0) Phase[y] = MathArctan(Q1[y]/I1[y])*rad2Deg; double DeltaPhase = Phase[y-1] - Phase[y]; if(DeltaPhase < 1) DeltaPhase = 1; double Alpha = FastLimit / DeltaPhase; if(Alpha < SlowLimit) Alpha = SlowLimit; if(Alpha > FastLimit) Alpha = FastLimit; mMAMA[y] = Alpha*price[y] + (1.0 - Alpha)*mMAMA[y-1]; mFAMA[y] = 0.5*Alpha*mMAMA[y] + (1.0 - 0.5*Alpha)*mFAMA[y-1]; if(SignalMode > 0) { trend[y] = trend[y-1]; if(mFAMA[y]-mMAMA[y] < 0 && trend[y-1]<=0) trend[y]= 1; if(mFAMA[y]-mMAMA[y] > 0 && trend[y-1]>=0) trend[y]=-1; if(trend[y] > 0) { if(trend[y-1] <= 0) { mUpsig[y] = mFAMA[y] - 0.5*iATR(NULL,TimeFrame,10,mBars-y-1); if (WarningMode>0 && y==mBars-1) PlaySound("alert2.wav"); } else mUpsig[y]= EMPTY_VALUE; mDnsig[y]= EMPTY_VALUE; } else if (trend[y] < 0) { if(trend[y-1] >= 0) { mDnsig[y] = mFAMA[y] + 0.5*iATR(NULL,TimeFrame,10,mBars-y-1); if (WarningMode>0 && y==mBars-1) PlaySound("alert2.wav"); } else mDnsig[y]= EMPTY_VALUE; mUpsig[y]= EMPTY_VALUE; } } if(TimeFrame == Period()) { MAMA[mBars-y-1] = mMAMA[y]; FAMA[mBars-y-1] = mFAMA[y]; if(SignalMode > 0) { UpSignal[mBars-y-1] = mUpsig[y]; DnSignal[mBars-y-1] = mDnsig[y]; } } mcnt_bars = mBars-1; } if(TimeFrame > Period()) { if(cnt_bars>0) cnt_bars--; limit = Bars-cnt_bars+TimeFrame/Period()-1; for(shift=0,y=0;shift 0) { UpSignal[shift] = mUpsig[mBars-y-1]; DnSignal[shift] = mDnsig[mBars-y-1]; sig[mBars-y-1] = trend[y]; } } } //---------- string Message; if (trend[mBars-2]<0 && trend[mBars-1]>0 && !UpTrendAlert && AlertMode == 1) { Message = " "+Symbol()+" M"+Period()+":MAMA Signal for BUY"; if (isNewBar()) Alert (Message); UpTrendAlert=true; DnTrendAlert=false; } else if (trend[mBars-2]>0 && trend[mBars-1]<0 && !DnTrendAlert && AlertMode == 1) { Message = " "+Symbol()+" M"+Period()+":MAMA Signal for SELL"; if (isNewBar()) Alert (Message); DnTrendAlert=true; UpTrendAlert=false; } return(0); } double HeikenAshi(int tf,int price,int bar) { if(bar == iBars(NULL,TimeFrame)- 1) { haClose[bar] = iClose(NULL,tf,bar); haOpen[bar] = iOpen(NULL,tf,bar); haHigh[bar] = iHigh(NULL,tf,bar); haLow[bar] = iLow(NULL,tf,bar); } else { haClose[bar] = (iOpen(NULL,tf,bar)+iHigh(NULL,tf,bar)+iLow(NULL,tf,bar)+iClose(NULL,tf,bar))/4; haOpen[bar] = (haOpen[bar+1]+haClose[bar+1])/2; haHigh[bar] = MathMax(iHigh(NULL,tf,bar),MathMax(haOpen[bar], haClose[bar])); haLow[bar] = MathMin(iLow(NULL,tf,bar),MathMin(haOpen[bar], haClose[bar])); } switch(price) { case 0: return(haClose[bar]);break; case 1: return(haOpen[bar]);break; case 2: return(haHigh[bar]);break; case 3: return(haLow[bar]);break; } } bool isNewBar() { bool res=false; if (iTime(NULL,TimeFrame,0)!=pTime) { res=true; pTime=iTime(NULL,TimeFrame,0); } return(res); }