MAMA_v1mtf_alert_001

Download script
Author: Copyright � 2009, TrendLaboratory
MAMA_v1mtf_alert_001

Functional Overview

This script is a sophisticated technical analysis tool designed to help traders identify market trends and potential entry or exit points. It utilizes a complex mathematical approach to smooth out price fluctuations, making it easier to see the underlying "flow" of the market while attempting to minimize the delay (lag) often found in standard moving averages.

Core Logic and Mechanisms

1. Adaptive Price Processing The tool can analyze various types of price data. While it defaults to a median calculation, it is capable of processing standard prices (Open, High, Low, Close), weighted closes, or specialized "Heiken Ashi" values. This flexibility allows the user to choose which data points best represent the market's behavior for their specific trading style.

2. Intelligent Smoothing and Detrending Instead of using a simple average, the logic employs a multi-layered smoothing process. It breaks down price movement into components to "detrend" the data—essentially filtering out the noise to find the momentum. This is achieved through a sequence of mathematical calculations that analyze the relationship between current prices and previous historical data.

3. Dynamic Period and Phase Analysis The script calculates the "period" and "phase" of the market cycle dynamically.

  • Phase: It identifies the current angle or direction of the price movement.
  • Period: It determines the speed/frequency of those movements. By calculating the change in these phases, the tool automatically adjusts its sensitivity. If the market moves rapidly, the indicator adapts to be more responsive; if the market moves slowly, it remains stable to avoid false signals.

4. The MAMA and FAMA Lines The script produces two primary visual lines:

  • MAMA (Moving Average Momentum Applied): This is the core adaptive line that reacts to the price flow calculated in the steps above.
  • FAMA (Following Adaptive Moving Average): This acts as a secondary "slow" line that follows the MAMA. The interaction between these two lines—specifically when they cross or change their relative positioning—is used to determine the overall trend direction.

5. Signal Generation and Alerts Beyond just providing visual lines, the script includes an automated signal system:

  • Trend Detection: It monitors the relationship between the MAMA and FAMA. When specific conditions are met (e.g., the MAMA moves above or below the FAMA in a certain way), the trend is flagged as "Up" or "Down."
  • Visual Cues: The script can place specific markers (arrows) on the chart to indicate these shifts in momentum.
  • Alerts: If enabled, the tool can provide audible sounds and visual pop-up alerts on the platform the moment a trend shift is detected, allowing for real-time monitoring without constantly staring at the screen.

6. Multi-Timeframe Compatibility The logic is designed to handle data from different timeframes. It can calculate data based on a higher timeframe (like a daily chart) and project those results onto a lower timeframe (like a 15-minute chart), helping traders ensure that their short-term trades are aligned with the larger market trend.

Price Data Components
Series array that contains open time of each barSeries array that contains close prices for each barSeries array that contains open prices of each barSeries array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Indicators Used
Moving average indicatorIndicator of the average true range
Miscellaneous
Implements a curve of type %1It plays sound alerts
12 Views
0 Downloads
0 Favorites
MAMA_v1mtf_alert_001
//+------------------------------------------------------------------+
//|                                                      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        =     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="MN"; 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);
}        		

Comments