Indicator MAMA

Indicator for professional Forex traders.

MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA
MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA
MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA
MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA
MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA
MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA
MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA
MAMA indicator for trading forex, commodities, stocks, precious metals, and the like.
MAMA









The indicator MAMA (MAMA FAME) created by John F. Ehlers is described in his book "Cybernetic Analysis for Stocks and Futures". Cybernetic Analysis for Stocks and Futures seeks to restore the balance between computational power and user proficiency. In this book, John Ehlers develops and demonstrates profoundly effective new trading tools through the application of modern digital signal processing techniques. Indicator MAMA (MAMA FAME) stands for MESA Adaptive Moving Average, based on the EMA algorithm, it has also been dubbed Mother of All Moving Averages. This is a MA that adjusts itself to up/down cycles and adapted to a financial instrument current volatility. The indicator consists of two averages - fast MAMA (red line) and slow FAMA (green line). Crossover of the averages provide signals for market entries and exits. This indicator can be used to complete trading strategy and not just the Forex market ...

Indicator MAMA MQ4 Code Base (Copy Code)
//+------------------------------------------------------------------+
//|                                                         MAMA.mq4 |
//|                                Copyright © 2009, TrendLaboratory |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                               Web: http://plusforex.blogspot.com |
//+------------------------------------------------------------------+
// 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        =     0;   //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<mBars;y++)
   {
      if(Price <= 6) price[y] = iMA(NULL,TimeFrame,1,0,0,Price,mBars-y-1);   
      else
      if(Price > 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<limit;shift++)
      {
      if (Time[shift] < iTime(NULL,TimeFrame,y)) y++; 
      MAMA[shift] = mMAMA[mBars-y-1];
      FAMA[shift] = mFAMA[mBars-y-1];   
         if(SignalMode > 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);
}    

Indicator MAMA MQ5 Code Base (Copy Code)
//+------------------------------------------------------------------+
//|                                                         MAMA.mq5 |
//|              MQL5 Code:     Copyright © 2010,   Nikolay Kositsin |
//|                              Khabarovsk,   farria@mail.redcom.ru |
//+------------------------------------------------------------------+
//---- author of the indicator
#property copyright "Copyright © 2010, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//---- indicator version number
#property version   "1.00"
//---- drawing the indicator in the main window
#property indicator_chart_window
//----two buffers are used for calculation and drawing the indicator
#property indicator_buffers 2
//---- two plots are used
#property indicator_plots   2
//+----------------------------------------------+
//|  FAMA indicator drawing parameters           |
//+----------------------------------------------+
//---- drawing indicator 1 as a line
#property indicator_type1   DRAW_LINE
//---- lime color is used as the color of the bullish line of the indicator
#property indicator_color1  Lime
//---- line of the indicator 1 is a solid curve
#property indicator_style1  STYLE_SOLID
//---- thickness of line of the indicator 1 is equal to 1
#property indicator_width1  1
//---- displaying of the bullish label of the indicator
#property indicator_label1  "MAMA"
//+----------------------------------------------+
//|  MAMA indicator drawing parameters           |
//+----------------------------------------------+
//---- drawing indicator 2 as a line
#property indicator_type2   DRAW_LINE
//---- red color is used as the color of the bearish indicator line
#property indicator_color2  Red
//---- line of the indicator 2 is a solid curve
#property indicator_style2  STYLE_SOLID
//---- thickness of line of the indicator 2 is equal to 1
#property indicator_width2  1
//---- displaying of the bearish label of the indicator
#property indicator_label2  "FAMA"
//+----------------------------------------------+
//| Input parameters of the indicator            |
//+----------------------------------------------+
extern double FastLimit = 0.5;
extern double SlowLimit = 0.05;
//+----------------------------------------------+
//---- declaration of dynamic arrays that further  
//---- will be used as indicator buffers
double MAMABuffer[];
double FAMABuffer[];
//---- Declaration of the integer variables for the start of data calculation
int StartBar;
//+------------------------------------------------------------------+
//| CountVelue() function                                            |
//+------------------------------------------------------------------+
double CountVelue(double  &Array1[],double  &Array2[])
  {
//----
   double Resalt=
                 (0.0962*Array1[0]
                 +0.5769*Array1[2]
                 -0.5769*Array1[4]
                 -0.0962*Array1[6])
                 *(0.075*Array2[1]+0.54);
//----
   return(Resalt);
  }
//+------------------------------------------------------------------+
//| ReCountArray() function                                          |
//+------------------------------------------------------------------+
void ReCountArray(double  &Array[])
  {
//----
   Array[6]=Array[5];
   Array[5]=Array[4];
   Array[4]=Array[3];
   Array[3]=Array[2];
   Array[2]=Array[1];
   Array[1]=Array[0];
//----
   return;
  }
//+------------------------------------------------------------------+
//| SmoothVelue() function                                           |
//+------------------------------------------------------------------+
double SmoothVelue(double  &Array[])
  {
//----
   return(0.2*Array[0]+0.8*Array[1]);
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+  
void OnInit()
  {
//---- initialization of constants
   StartBar=7+1;
//---- transformation of the MAMABuffer dynamic array into an indicator buffer
   SetIndexBuffer(0,MAMABuffer,INDICATOR_DATA);
//--- creation of a label to be displayed in the Data Window
   PlotIndexSetString(0,PLOT_LABEL,"MAMA");
//---- shifting the start of drawing of the indicator
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartBar);

//---- transformation of the FAMABuffer dynamic array into an indicator buffer
   SetIndexBuffer(1,FAMABuffer,INDICATOR_DATA);
//--- creation of a label to be displayed in the Data Window
   PlotIndexSetString(1,PLOT_LABEL,"FAMA");
//---- shifting the start of drawing of the indicator
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartBar+1);

//---- initializations of variable for indicator short name
   string shortname;
   StringConcatenate(shortname,"The MESA Adaptive Moving Average(",FastLimit,", ",SlowLimit,")");
//---- creating name for displaying in a separate sub-window and in a tooltip
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//---- determination of accuracy of displaying of the indicator values
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//----
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(
                const int rates_total,    // amount of history in bars at the current tick
                const int prev_calculated,// amount of history in bars at the previous tick
                const int begin,          // number of beginning of reliable counting of bars
                const double &price[]     // price array for calculation of the indicator
                )
  {
//---- checking the number of bars to be enough for the calculation
   if(rates_total<StartBar+begin) return(0);

//---- memory variables introduction  
   static double smooth[7],detrender[7],Q1[7],I1[7],I2[7];
   static double Q2[7],jI[7],jQ[7],Re[7],Im[7],period[7],Phase[7];

//---- declarations of local variables
   int first,bar;
   double DeltaPhase, alpha;

//---- calculation of the starting number 'first' for the bars recalculation loop
   if(prev_calculated==0) // checking for the first start of the indicator calculation
     {
      first=StartBar+begin; // starting number for calculation of all bars
      //----
      ArrayInitialize(smooth,0.0);
      ArrayInitialize(detrender,0.0);
      ArrayInitialize(period,0.0);
      ArrayInitialize(Phase,0.0);
      ArrayInitialize(Q1,0.0);
      ArrayInitialize(I1,0.0);
      ArrayInitialize(I2,0.0);
      ArrayInitialize(Q2,0.0);
      ArrayInitialize(jI,0.0);
      ArrayInitialize(jQ,0.0);
      ArrayInitialize(Re,0.0);
      ArrayInitialize(Im,0.0);
      //----
      MAMABuffer[first-1] = price[first-1];
      FAMABuffer[first-1] = price[first-1];

     }
   else first=prev_calculated-1; // starting number for calculation of new bars

//---- main loop of calculation of the indicator
   for(bar=first; bar<rates_total; bar++)
     {
      smooth[0]=(4*price[bar-0]+3*price[bar-1]+2*price[bar-2]+1*price[bar-3])/10.0;
      //----
      detrender[0]=CountVelue(smooth,period);
      Q1[0]=CountVelue(detrender,period);
      I1[0] = detrender[3];
      jI[0] = CountVelue(I1, I1);
      jQ[0] = CountVelue(Q1, Q1);
      I2[0] = I1[0] - jQ[0];
      Q2[0] = Q1[0] - jI[0];
      I2[0] = SmoothVelue(I2);
      Q2[0] = SmoothVelue(Q2);
      Re[0] = I2[0]*I2[1] + Q2[0]*Q2[1];
      Im[0] = I2[0]*Q2[1] - Q2[0]*I2[1];
      Re[0] = SmoothVelue(Re);
      Im[0] = SmoothVelue(Im);
      //----
      if(Im[0]!=0 && Re[0]!=0) period[0]=6.285714/MathArctan(Im[0]/Re[0]);

      if(period[0]>1.50*period[1]) period[0]=1.50*period[1];
      if(period[0]<0.67*period[1]) period[0]=0.67*period[1];
      if(period[0]<6.00) period[0]=6.00;
      if(period[0]>50.0) period[0]=50.0;
      //----
      period[0]=0.2*period[0]+0.8*period[1];
      //----
      if(I1[0]!=0) Phase[0]=57.27272987*MathArctan(Q1[0]/I1[0]);
      //----
      DeltaPhase=Phase[1]-Phase[0];
      if(DeltaPhase<1) DeltaPhase=1.0;
      //----
      alpha=FastLimit/DeltaPhase;
      if(alpha<SlowLimit)alpha=SlowLimit;
      //----
      MAMABuffer[bar]=alpha*price[bar]+(1.0-alpha)*MAMABuffer[bar-1];
      FAMABuffer[bar]=0.5*alpha*MAMABuffer[bar]+(1.0-0.5*alpha)*FAMABuffer[bar-1];
      //----
      if(bar<rates_total-1)
        {
         ReCountArray(smooth);
         ReCountArray(detrender);
         ReCountArray(period);
         ReCountArray(Phase);
         ReCountArray(Q1);
         ReCountArray(I1);
         ReCountArray(I2);
         ReCountArray(Q2);
         ReCountArray(jI);
         ReCountArray(jQ);
         ReCountArray(Re);
         ReCountArray(Im);
        }
     }
//----    
   return(rates_total);
  }
//+------------------------------------------------------------------+