Author: Copyright � 2010, TrendLaboratory
ALMA_v1

This script introduces an advanced technical analysis tool called the ALMA (Arnaud Legoux Moving Average). Its primary purpose is to provide a smoother, more responsive trend-following line on a trading chart compared to traditional moving averages. By balancing speed and smoothness, it aims to reduce "market noise" while minimizing the time lag that typically causes traders to enter a position too late.

Core Logic and Mechanism

1. Weighted Gaussian Distribution Unlike standard moving averages that give equal weight to all data points or follow a simple linear progression, this script uses a Gaussian distribution. This means it applies a specific mathematical "weight" to price data points based on their distance from the center of the look-back window. By using these weights, the indicator prioritizes the most relevant information, resulting in a curve that feels more fluid and less erratic than standard tools.

2. Dynamic Trend Filtering The script includes a sophisticated filtering system designed to prevent "whipsaws"—those small, frequent direction changes that can trigger false signals in a sideways market.

  • It calculates the current volatility (Standard Deviation) of the average's movement.
  • If the price movement is smaller than a specific percentage of that volatility (based on the user-defined filter), the indicator "flattens" its response, holding the previous value to ensure it only reacts to significant, meaningful trend shifts.

3. Visual Trend Identification The script distinguishes between upward and downward movements automatically:

  • Uptrend Recognition: When the average moves upward beyond the calculated threshold, it highlights the path in a specific color (representing an "Uptrend").
  • Downtrend Recognition: Conversely, when it moves downward significantly, it tracks that movement separately (representing a "Downtrend").
  • Color Transitions: The logic ensures that these visual lines connect logically, providing a continuous visual history of the market's direction.

4. Automated Alerts and Notifications The script is designed to be proactive for the user. It monitors for specific "crosses"—moments where the trend flips from negative to positive (Buy signal) or vice versa (Sell signal). When these occur:

  • It can trigger a visual Alert Box on the platform screen.
  • It can play an Audio Warning sound.
  • It checks for volume activity to ensure that these signals are occurring during active market participation.

Summary for the User

Essentially, this tool acts as a "smart" trend line. It looks at recent price history, applies a smooth mathematical curve to it, filters out minor fluctuations that might trick a trader, and then draws clear visual paths showing you exactly when the momentum has shifted from one direction to another.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It plays sound alerts
11 Views
0 Downloads
0 Favorites
ALMA_v1
//+------------------------------------------------------------------+
//|                                                      ALMA_v1.mq4 |
//| ALMA by Arnaud Legoux / Dimitris Kouzis-Loukas / Anthony Cascino |
//|                                             www.arnaudlegoux.com |                     
//|                         Written by IgorAD,igorad2003@yahoo.co.uk |   
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |                                      
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, TrendLaboratory"
#property link      "http://finance.groups.yahoo.com/group/TrendLaboratory"
//---- indicator settings
#property indicator_chart_window 
#property indicator_buffers 3 
#property indicator_color1 Yellow 
#property indicator_color2 LightBlue 
#property indicator_color3 Tomato 
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2 
//---- indicator parameters
extern int     Price             =   0;  //Price Mode (0...6)
extern int     WindowSize        =   9;  //Window Size  
extern double  Sigma             = 6.0;  //Sigma parameter 
extern double  Offset            =0.85;  //Offset of Gaussian distribution (0...1)
extern double  PctFilter         =   0;  //Dynamic filter in decimal
extern int     Shift             =   0;  //
extern int     ColorMode         =   1;  //0-off,1-on
extern int     ColorBarBack      =   1;  //
extern int     AlertMode         =   0;  //Sound Alert switch (0-off,1-on) 
extern int     WarningMode       =   0;  //Sound Warning switch(0-off,1-on) 
//---- indicator buffers
double     ALMA[];
double     Uptrend[];
double     Dntrend[];
double     trend[];
double     Del[];

int        draw_begin;
bool       UpTrendAlert=false, DownTrendAlert=false;
double     wALMA[]; 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicator buffers mapping
   IndicatorBuffers(5);
   SetIndexBuffer(0,ALMA);
   SetIndexBuffer(1,Uptrend);
   SetIndexBuffer(2,Dntrend);
   SetIndexBuffer(3,trend);  
   SetIndexBuffer(4,Del);
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   draw_begin = WindowSize;
   SetIndexDrawBegin(0,draw_begin);
   SetIndexDrawBegin(1,draw_begin);
   SetIndexDrawBegin(2,draw_begin);
   SetIndexShift(0,Shift);
   SetIndexShift(1,Shift);
   SetIndexShift(2,Shift);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("ALMA("+WindowSize +")");
   SetIndexLabel(0,"ALMA");
   SetIndexLabel(1,"ALMA Uptrend");
   SetIndexLabel(2,"ALMA Dntrend");
//---- 
   
   double m = MathFloor(Offset * (WindowSize - 1));
	double s = WindowSize/Sigma;
	
	ArrayResize(wALMA,WindowSize);
	double wsum = 0;		
	for (int i=0;i < WindowSize;i++) 
	{
	wALMA[i] = MathExp(-((i-m)*(i-m))/(2*s*s));
   wsum += wALMA[i];
   }
   
   for (i=0;i < WindowSize;i++) wALMA[i] = wALMA[i]/wsum; 
   
   return(0);
  }
//+------------------------------------------------------------------+
//| ALMA_v1                                                          |
//+------------------------------------------------------------------+
int start()
{
   int limit,shift,i;
   int counted_bars=IndicatorCounted();
//---- 
   if(counted_bars<1)
   {
      for(i=Bars-1;i>0;i--) 
      {
      ALMA[i]=EMPTY_VALUE; 
      Uptrend[i]=EMPTY_VALUE;
      Dntrend[i]=EMPTY_VALUE;
      }
   }
//---- 
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;

//---- 
   for(shift=limit; shift>=0; shift--)
   {
    
   if (shift > Bars - WindowSize) continue; 
   
	double sum  = 0;
	double wsum = 0;
			
      for(i=0;i < WindowSize;i++) 
      {
         if (i < WindowSize) 
         {
			sum += wALMA[i] * iMA(NULL,0,1,0,0,Price,shift + (WindowSize - 1 - i)); 
			
			}
		}
		
	//if(wsum != 0) 
	ALMA[shift] = sum;

      if(PctFilter>0)
      {
      Del[shift] = MathAbs(ALMA[shift] - ALMA[shift+1]);
   
      double sumdel=0;
      for (int j=0;j<=WindowSize-1;j++) sumdel = sumdel+Del[shift+j];
      double AvgDel = sumdel/WindowSize;
    
      double sumpow = 0;
      for (j=0;j<=WindowSize-1;j++) sumpow+=MathPow(Del[j+shift]-AvgDel,2);
      double StdDev = MathSqrt(sumpow/WindowSize); 
     
      double Filter = PctFilter * StdDev;
     
      if( MathAbs(ALMA[shift]-ALMA[shift+1]) < Filter ) ALMA[shift]=ALMA[shift+1];
      }
      else
      Filter=0;
   
      
      if (ColorMode>0)
      {
         trend[shift] = trend[shift+1];
         if (ALMA[shift] - ALMA[shift+1] > Filter) trend[shift] = 1;
         if (ALMA[shift+1] - ALMA[shift] > Filter) trend[shift] =-1;
    
         if (trend[shift]>0)
         {
            Uptrend[shift] = ALMA[shift]; 
            if (trend[shift+ColorBarBack]<0) Uptrend[shift+ColorBarBack]=ALMA[shift+ColorBarBack];
            Dntrend[shift] = EMPTY_VALUE;
            if (WarningMode>0 && trend[shift+1]<0 && i==0) PlaySound("alert2.wav");
         }
         else              
         if (trend[shift]<0)
         { 
            Dntrend[shift] = ALMA[shift]; 
            if (trend[shift+ColorBarBack]>0) Dntrend[shift+ColorBarBack]=ALMA[shift+ColorBarBack];
            Uptrend[shift] = EMPTY_VALUE;
            if (WarningMode>0 && trend[shift+1]>0 && i==0) PlaySound("alert2.wav");
         }               
      }
   }      
//----------   
   string Message;
   
   if ( trend[2]<0 && trend[1]>0 && Volume[0]>1 && !UpTrendAlert)
	{
	Message = " "+Symbol()+" M"+Period()+": HMA 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()+": HMA Signal for SELL";
	if ( AlertMode>0 ) Alert (Message); 
	DownTrendAlert=true; UpTrendAlert=false;
	} 	         



//---- done
   return(0);
}

Comments