Author: Copyright � 2006, MetaQuotes Software Corp.
AMA_STL

This technical script is designed as a sophisticated trend-tracking tool for financial charts. It functions by calculating and visualizing two distinct moving average lines to help identify market momentum while attempting to smooth out the "noise" typically found in volatile price action.

Core Logic and Methodology

The script operates using a multi-layered calculation process to differentiate between meaningful price movements and minor fluctuations:

  • Volatility Assessment (Noise Calculation): To understand the true movement of the market, the script first measures "Noise." It looks back over a specific range of previous price bars to calculate the cumulative sum of price changes. By establishing this baseline of activity, the tool can determine if a current price move is significant or just a minor jitter in the market.

  • Efficiency Ratio (ER): The script uses the noise measurement to calculate an Efficiency Ratio. This represents the net displacement of price divided by the total "effort" (noise) taken to get there. A high efficiency suggests a strong, clear trend, while low efficiency suggests a choppy or sideways market.

  • Adaptive Moving Average (AMA): Based on the Efficiency Ratio, the script calculates an Adaptive Moving Average. Unlike standard moving averages that weight all data points equally, this logic adjusts its sensitivity based on market conditions. When the market is trending efficiently, the average reacts more quickly; when the market becomes erratic or noisy, the average stabilizes to prevent false signals.

  • The Filtering Mechanism: The script contains a secondary layer of logic acting as a "filter." This is intended to keep the moving average line smooth during periods of consolidation. It calculates the standard deviation of the movements and compares them against a user-defined threshold. If a price movement is too small to be considered a significant trend change, the script "holds" the previous value of the average rather than letting it jump, resulting in a cleaner, more readable line on the chart.

Practical Application

For the user, this logic provides a visual representation of price trends that is less prone to "whipsaws"—those rapid, insignificant price movements that often trigger false signals in simpler indicators. By combining volatility sensing with an adaptive filtering system, it seeks to highlight the underlying direction of the market more clearly.

Miscellaneous
Implements a curve of type %1
10 Views
0 Downloads
0 Favorites
AMA_STL
//+------------------------------------------------------------------+
//|                                                      AMA STL.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//----
extern int FastMA = 3;
extern int SlowMA = 100;
extern int Range = 160;
extern int filter = 25;
extern int NBars = 5000;
//----
double fAMA[];
double mAMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(2);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, fAMA);
   SetIndexBuffer(1, mAMA);
//----
   IndicatorShortName("AMA_STL(" + FastMA + ", " + SlowMA + ", " + Range + "; " + 
                      filter + ")");   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int counted_bars = IndicatorCounted();
   int cb, i;
   double  k1, k2, Noise, ER, SSC, AMA, sdAMA, dAMA;
//----
   if(Bars <= NBars) 
       return(0);
   else
     {
       k1 = 2.0 / (SlowMA + 1);
       k2 = 2.0 / (FastMA + 1) - k1;
       AMA = Close[NBars-Range];
       mAMA[NBars-Range] = Close[NBars-Range+1];
       //----
       for(cb = NBars - counted_bars - Range - 1; cb >= 0; cb--)
         {
           Noise = 0;
           //----
           for(i = cb; i <= cb + Range - 1; i++)
             {
               Noise = Noise + MathAbs(Close[i] - Close[i+1]);
             }
           //----
           if(Noise != 0)
             {
               ER = MathAbs(Close[cb] - Close[cb+Range]) / Noise;
             }
           else
             {
               ER = 0;
             }
           SSC = (ER*k2 + k1);
           AMA = AMA + NormalizeDouble(SSC*SSC*(Close[cb] - AMA), 4);
           mAMA[cb] = AMA;
           //----
           if(filter < 1)
             {
               fAMA[cb] = mAMA[cb];
             }
           else
             {
               for(i = cb; i <= cb + SlowMA - 1; i++)
                 {
                   sdAMA = sdAMA + MathAbs(mAMA[i] - mAMA[i+1]);
                 }
               dAMA = mAMA[cb] - mAMA[cb+1];
               //----
               if(dAMA >= 0)
                 {
                   if(dAMA < NormalizeDouble(filter*sdAMA / (100*SlowMA), 4) && 
                      High[cb] <= High[Highest(NULL, 0, MODE_HIGH, 4, cb)] + 10*Point)
                     {
                       fAMA[cb] = fAMA[cb+1];
                     }
                   else
                     {
                       fAMA[cb] = mAMA[cb];
                     }
                 }
               else
                 {
                   if(MathAbs(dAMA) < NormalizeDouble(filter*sdAMA / (100*SlowMA), 4) && 
                      Low[cb] > Low[Lowest(NULL, 0, MODE_LOW, 4, cb)] - 10*Point)
                     {
                       fAMA[cb] = fAMA[cb+1];
                     }
                   else
                     {
                       fAMA[cb] = mAMA[cb];
                     }
                 }
               sdAMA=0.0;
             }
         }
     }
   return(0);
  }
//+------------------------------------------------------------------+

Comments