LowPassFilter_v1

Download script
Author: Copyright � 2007, TrendLaboratory Ltd.
LowPassFilter_v1

This technical tool is designed to help traders identify and visualize market trends by applying a sophisticated "smoothing" process to price data. By filtering out the minor fluctuations and "noise" of the market, it aims to reveal the underlying direction of price movement more clearly.

How the Logic Works

1. Initial Smoothing (Pre-processing) Before calculating the main trend, the script first takes the raw price data (such as Close, Open, High, Low, or Median prices) and applies a preliminary smoothing layer. This step ensures that the subsequent calculations are based on a stabilized version of the price rather than volatile, tick-by-tick movements.

2. The Filter Engine The core of the script is the "Low Pass Filter," which processes the smoothed data through three different mathematical models depending on your preference:

  • Basic Smoothing: A standard moving average approach for a straightforward trend line.
  • Second Order: A more advanced calculation that uses geometric constants to create a smoother, less reactive curve.
  • Third Order: The highest level of complexity, designed to provide the smoothest possible output by neutralizing as much market "jitter" as possible.

3. Dynamic Volatility Adjustment (Optional) The script includes a specialized feature that looks at standard deviation—a measure of how much the price is swinging. If enabled, the filter can detect when movements are too small to be considered significant and will "hold" the trend line steady until a movement large enough to be meaningful occurs. This prevents the indicator from flickering during sideways market conditions.

4. Trend Detection and Visuals Once the filtered line is calculated, the script determines the direction of the market:

  • Trend Identification: It compares the current value of the filter against its previous value. If the line moves up significantly, it identifies an "Up Trend"; if it moves down, it marks a "Down Trend."
  • Visual Feedback: The tool plots these trends on your chart using different colors (Yellow, Light Blue, and Tomato) to make it easy to see where the trend is shifting. It can also highlight specific bars to indicate the exact moment a trend reversal occurred.

5. Alerts and Notifications To help traders who cannot watch the screens constantly, the script includes an automated notification system. When the logic detects a definitive flip from a Down Trend to an Up Trend (or vice versa), it can trigger:

  • Visual Alerts: On-screen messages identifying the specific symbol and timeframe.
  • Audio Warnings: Sound files that play at the moment of the trend shift.

In summary, this script acts as a sophisticated "lens" for price action. It strips away the distractions of minor price movements to show you the primary path of the market, providing visual cues and alerts when that path changes direction.

Indicators Used
Moving average indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1It plays sound alerts
14 Views
0 Downloads
0 Favorites
LowPassFilter_v1
//+------------------------------------------------------------------+
//|                                             LowPassFilter_v1.mq4 |
//|                           Copyright © 2007, TrendLaboratory Ltd. |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|                                   E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, TrendLaboratory Ltd."
#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-Close,1-Open,2-High,3-Low,4-Median,5-Typical,6-Weighted
extern int     Order          = 3;  //Filter Order: 1-EMA,2-2nd Order,3-3rd Order
extern int     FilterPeriod   =14;  //Filter Period 
extern int     PreSmooth      = 1;  //Pre-smoothing period
extern int     PreSmoothMode  = 0;  //Pre-smoothing MA Mode: 0-SMA,1-EMA,2-SMMA,3-LWMA
extern double  PctFilter      = 0;  //Dynamic filter in decimal(multiplier for StdDev)
extern int     ColorMode      = 0;  //Color Mode: 0-off,1-on
extern int     ColorBarBack   = 1;  //Should be 0 or 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     Filter[];
double     UpTrend[];
double     DnTrend[];
double     Smoother[];
double     trend[];
double     Del[];
double     AvgDel[];

int        draw_begin;
bool       UpTrendAlert=false, DownTrendAlert=false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
//---- indicator buffers mapping
   IndicatorBuffers(7);
   SetIndexBuffer(0,Filter);
   SetIndexBuffer(1,UpTrend);
   SetIndexBuffer(2,DnTrend);
   SetIndexBuffer(3,Smoother);
   SetIndexBuffer(4,trend);  
   SetIndexBuffer(5,Del);
   SetIndexBuffer(6,AvgDel);
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   draw_begin = FilterPeriod + PreSmooth;
   SetIndexDrawBegin(0,draw_begin);
   SetIndexDrawBegin(1,draw_begin);
   SetIndexDrawBegin(2,draw_begin);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+1);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("LowPassFilter("+Order+","+FilterPeriod+")");
   SetIndexLabel(0,"LowPassFilter");
   SetIndexLabel(1,"UpTrend");
   SetIndexLabel(2,"DnTrend");
//---- initialization done
   return(0);
}
//+------------------------------------------------------------------+
//| LowPassFilter_v1                                                 |
//+------------------------------------------------------------------+
int start()
{
   int limit, i, shift;
   int counted_bars=IndicatorCounted();
   double a, b, c, pi = 3.1415926535;
   
   if(counted_bars<1)
   for(i=1;i<=draw_begin;i++) 
   {
   Filter[Bars-i]=0; 
   UpTrend[Bars-i]=0; 
   DnTrend[Bars-i]=0;
   }
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;

   for(shift=limit; shift>=0; shift--)
   Smoother[shift] = iMA(NULL,0,PreSmooth,0,PreSmoothMode,Price,shift);
   
   for(shift=limit; shift>=0; shift--)
   {
      if(Order == 1) Filter[shift] = iMAOnArray(Smoother,0,FilterPeriod,0,1,shift);
      else
		if(Order == 2) 
		{
		a = MathExp(-MathSqrt(2)*pi/FilterPeriod);
		b = 2*a*MathCos(MathSqrt(2)*pi/FilterPeriod);
    	Filter[shift] = b*Filter[shift+1] - a*a*Filter[shift+2] + (1 - b + a*a)*Smoother[shift];
		}
		else
		if(Order == 3) 
		{
		a = MathExp(-pi/FilterPeriod);
		b = 2*a*MathCos(MathSqrt(3)*pi/FilterPeriod);
    	c = MathExp(-2*pi/FilterPeriod); //a * a;
    	Filter[shift] = (b+c)*Filter[shift+1] - (c+b*c)*Filter[shift+2] + c*c*Filter[shift+3] + (1-b+c)*(1-c)*Smoother[shift];
		}
  
   int Length = FilterPeriod;
      
      if (PctFilter>0)
      {
      Del[shift] = MathAbs(Filter[shift] - Filter[shift+1]);
   
      double sumdel=0;
      for (int j=0;j<=Length-1;j++) sumdel = sumdel+Del[shift+j];
      AvgDel[shift] = sumdel/Length;
    
      double sumpow = 0;
      for (j=0;j<=Length-1;j++) sumpow+=MathPow(Del[j+shift]-AvgDel[j+shift],2);
      double StdDev = MathSqrt(sumpow/Length); 
     
      double filter = PctFilter * StdDev;
     
      if(MathAbs(Filter[shift]-Filter[shift+1]) < filter ) Filter[shift]=Filter[shift+1];
      }
      else
      filter=0;
   
      
      if (ColorMode>0)
      {
         trend[shift] = trend[shift+1];
         if (Filter[shift] - Filter[shift+1] > filter) trend[shift] = 1;
         if (Filter[shift+1] - Filter[shift] > filter) trend[shift] =-1;
    
         if (trend[shift]>0)
         {
            UpTrend[shift] = Filter[shift]; 
            if (trend[shift+ColorBarBack]<0) UpTrend[shift+ColorBarBack]=Filter[shift+ColorBarBack];
            DnTrend[i] = EMPTY_VALUE;
            if (WarningMode>0 && trend[shift+1]<0 && shift==0) PlaySound("alert2.wav");
         }
         else              
         if (trend[shift]<0)
         { 
            DnTrend[shift] = Filter[shift]; 
            if (trend[shift+ColorBarBack]>0) DnTrend[shift+ColorBarBack]=Filter[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()+": 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