//+------------------------------------------------------------------+
//|                                               AdvancedAMA_v1.mq4 |
//|                                Copyright © 2006, TrendLaboratory |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                                   E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, TrendLaboratory"
#property link      "http://finance.groups.yahoo.com/group/TrendLaboratory"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Linen
#property indicator_width1 2
#property indicator_color2 SkyBlue
#property indicator_width2 2
#property indicator_color3 Tomato
#property indicator_width3 2

//---- input parameters
extern int     Price        =   0;  //Apply to price
extern int     AMA_Period   =  10;  //Period of AMA
extern int     N_fast       =   2;  //Period of fast EMA
extern int     N_slow       =  30;  //Period of slow EMA
extern int     ER_smooth    =   5;  //Period of smoothing of Efficiency Ratio
extern double  SC_power     =   2;  //Power of smoothing constant
extern double  PctFilter    = 2.0;  //Percentage of dynamic filter
extern int     Mode         =   0;  //Mode switch (0-usual;1-stepped)
extern int     Color        =   0;  //Switch of Color mode (1-color)
extern int     ColorBarBack =   1;  //Bar back for color mode
extern int     AlertMode    =   0;  //Sound Alert switch 
extern int     WarningMode  =   0;  //Warning switch
//---- buffers
double AMA[];
double UpTrend[];
double DnTrend[];
double ER[];
double trend[];
double Del[];
double AvgDel[];
double price[];
bool   UpTrendAlert=false, DownTrendAlert=false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(8);
   
   SetIndexBuffer(0,AMA);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1,UpTrend);   
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2,DnTrend);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(3,ER);
   SetIndexBuffer(4,trend);
   SetIndexBuffer(5,Del);
   SetIndexBuffer(6,AvgDel);
   SetIndexBuffer(7,price);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- name for DataWindow and indicator subwindow label
   string short_name="AdvancedAMA("+AMA_Period+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,"Advanced AMA");
   SetIndexLabel(1,"UpTrend");
   SetIndexLabel(2,"DnTrend");
//----
   SetIndexDrawBegin(0,AMA_Period+N_slow);
   SetIndexDrawBegin(1,AMA_Period+N_slow);
   SetIndexDrawBegin(2,AMA_Period+N_slow);
//----

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| AdvancedAMA_v1                                                   |
//+------------------------------------------------------------------+
int start()
{
   int    i,shift, counted_bars=IndicatorCounted(),limit;
   double direction,noise,SumER,ERsmooth,SC;      
   int FilterPeriod = 20;
   
   if ( counted_bars > 0 )  limit=Bars-counted_bars;
   if ( counted_bars < 0 )  return(0);
   if ( counted_bars ==0 )  limit=Bars-1; 
   if ( counted_bars < 1 ) 
   
   for(i=1;i<N_fast;i++) 
   {
   AMA[Bars-i]=iMA(NULL,0,1,0,1,Price,i);    
   UpTrend[Bars-i]=iMA(NULL,0,1,0,1,Price,i);  
   DnTrend[Bars-i]=iMA(NULL,0,1,0,1,Price,i);
   ER[Bars-i]=0; 
   price[Bars-i]=iMA(NULL,0,1,0,1,Price,i);
   }
   
   for(shift=limit;shift>=0;shift--) 
   {	
   price[shift]=iMA(NULL,0,N_fast,0,3,Price,shift);
   
   direction = MathAbs(price[shift]-price[shift+AMA_Period]);	
  
   noise = 0;
   for (i=0;i<=AMA_Period-1;i++)
   noise += MathAbs(price[i+shift]-price[i+shift+1]);  
   if (noise==0) noise=0.000001;     
   if (noise>0) ER[shift] = direction/noise;   
       
   SumER=0;
   for (i=0;i<=ER_smooth-1;i++) SumER += ER[shift+i];
      
   ERsmooth = SumER/ER_smooth;
      
   SC = ERsmooth*(2.0/(1.0+N_fast) - 2.0/(1.0+N_slow)) + 2.0/(1.0+N_slow);
   
   AMA[shift] = AMA[shift+1] + MathPow(SC,SC_power)*(price[shift]-AMA[shift+1]);
 
      if (PctFilter>0)
      {
      Del[shift] = MathAbs(AMA[shift] - AMA[shift+1]);
   
      double sumdel=0;
      for (i=0;i<=FilterPeriod-1;i++) sumdel = sumdel+Del[shift+i];
      AvgDel[shift] = sumdel/FilterPeriod;
    
      double sumpow = 0;
      for (i=0;i<=FilterPeriod-1;i++) sumpow+=MathPow(Del[shift+i]-AvgDel[shift+i],2);
      double StdDev = MathPow(sumpow/FilterPeriod,0.5); 
     
      double Filter = PctFilter * StdDev;
      if(Filter < Point) Filter = Point;
      }
      else Filter = 0;
      
      if (Mode > 0) if (MathAbs(AMA[shift] - AMA[shift+1])<Filter) AMA[shift] = AMA[shift+1]; 
      
      
      if (Color>0)
      {
      
      double smax = -1000000,smin=100000000;
         
         for (i=0;i<=AMA_Period-1;i++)
         {
         smax = MathMax(smax,AMA[shift+i]);
         smin = MathMin(smin,AMA[shift+i]);
         }
         
      trend[shift]=trend[shift+1];
      if (AMA[shift]-smin > Filter) trend[shift]= 1; 
      if (smax-AMA[shift] > Filter) trend[shift]=-1; 
         if (trend[shift]>0)
         {  
         UpTrend[shift] = AMA[shift];
         if (trend[shift+ColorBarBack]<0) UpTrend[shift+ColorBarBack]=AMA[shift+ColorBarBack];
         DnTrend[shift] = EMPTY_VALUE;
         if (WarningMode>0 && trend[shift+1]<0 && shift==0) PlaySound("alert2.wav");
         }
         if (trend[shift]<0) 
         {
         DnTrend[shift] = AMA[shift];
         if (trend[shift+ColorBarBack]>0) DnTrend[shift+ColorBarBack]=AMA[shift+ColorBarBack];
         UpTrend[shift] = EMPTY_VALUE;
         if (WarningMode>0 && trend[shift+1]>0 && shift==0) PlaySound("alert2.wav");
         }
      }
   }
//----------   
   string Message;
   
   if ( trend[2]<0 && trend[1]>0 && Volume[0]>1 && !UpTrendAlert)
	{
	Message = " "+Symbol()+" M"+Period()+": Signal for BUY";
	if ( AlertMode>0 ) Alert (Message); 
	UpTrendAlert=true; DownTrendAlert=false;
	} 
	 	  
	if ( trend[2]>0 && trend[1]<0 && Volume[0]>1 && !DownTrendAlert)
	{
	Message = " "+Symbol()+" M"+Period()+": Signal for SELL";
	if ( AlertMode>0 ) Alert (Message); 
	DownTrendAlert=true; UpTrendAlert=false;
	} 	         
 
//----
   
   return(0);
}


