FAMAMrPip
Download scriptThis script implements a sophisticated technical analysis tool known as the Fractal Adaptive Moving Average (FRAMA). Unlike standard moving averages that use a fixed speed to smooth out price data, this indicator dynamically adjusts its sensitivity based on the market's current volatility and fractal dimension.
How the Logic Works
The core objective of this script is to create a "smart" moving average that reacts quickly to significant price changes while remaining smooth during stable periods. It achieves this through several distinct logical steps:
1. Determining Market Volatility (The Fractal Dimension) Instead of just looking at the price trend, the script analyzes the "roughness" of the price movement over a specific period. It breaks down the recent data into two halves and compares the range of highs and lows in each half against the total range of the entire period. By using logarithmic calculations, it determines a "Fractal Dimension." This number tells the script whether the market is moving in a smooth, trending manner or if it is behaving erratically and noisily.
2. Calculating the Adaptation Factor (Alpha) The script then converts that Fractal Dimension into an "Alpha" value. Think of Alpha as a throttle:
- In a strong, clear trend, the script adjusts the Alpha to make the average more responsive to current price action.
- In a noisy or sideways market, the script lowers the Alpha to prevent the moving average from reacting to insignificant "fake" movements (market noise).
3. The Weighted Calculation Finally, the script produces the actual line you see on your chart by blending two pieces of information:
- The current closing price (multiplied by the adaptation factor).
- The previous value of the moving average (multiplied by the remainder).
Because this calculation happens continuously, the resulting line curves and adapts in real-time. It seeks to stay as close to the price as possible during high-momentum shifts while filtering out the "jitter" of low-volatility markets.
Summary for the Trader
In practical terms, this tool is designed to reduce the "lag" typically associated with moving averages. By automatically sensing the market's behavior—adjusting its own internal speed based on how volatile or stable the price action is—it provides a more responsive visual guide for identifying trends and potential trend reversals.
//+------------------------------------------------------------------+
//| |
//| Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
//
// Description: Fractal Adaptive Moving Average - by John Ehlers
// Version 1.0 8/9/2005
// Notes:
// October 2005 Issue - "FRAMA - Fractal Adaptive Moving Average"
// Length will be forced to be an even number. Odd numbers will be bumped up to the
// next even number.
// Formula Parameters: Defaults:
// RPeriod 16
#property copyright "Copyright © 2005, MrPip "
#property link "http://www.metaquotes.net/"
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- buffers
double ExtMapBuffer1[];
extern int RPeriod = 60;
int shift;
int loopbegin;
double Filt_1 = 0; //previous bar's Filt
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- 1 additional buffers are used for counting.
IndicatorBuffers(1);
//---- drawing settings
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
SetIndexShift(0,0);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- initialization done
return(0);
}
int start()
{
if (Bars < RPeriod) return(0);
Comment("Bars : ",Bars);
loopbegin = Bars - RPeriod - 1;
Filt_1=Close[loopbegin];
for(shift = loopbegin; shift >= 0; shift--)
{
Filt_1 = FAMA();
// if (shift < RPeriod+1) Filt = Close[shift];
//========== COLOR CODING ===========================================
ExtMapBuffer1[shift] = Filt_1;
}
// done
return (0);
}
double FAMA()
{
double Filt = 0;
int count = 0;
int tmp = 0;
int N = 0;
int HalfN = 0;
double N1 = 0;
double N2 = 0;
double N3 = 0;
double HH = 0;
double LL = 0;
double Dimen = 0;
double alpha = 0;
N = MathFloor(RPeriod/2)*2; // Force N to even number
HalfN = MathFloor(N/2);
N3 = (High[Highest(NULL,0,MODE_HIGH,shift + N-1, shift)] - Low[Lowest(NULL,0,MODE_LOW,shift + N-1, shift)]) / N;
// Print("High ",High[Highest(NULL,0,MODE_HIGH,shift+N, shift)],"Low ",Low[Lowest(NULL,0,MODE_LOW,shift+N, shift)]);
HH = High[shift+N-1];
LL = Low[shift+N-1];
// First half
for( count = 0; count <= (HalfN -1); count++) {
tmp = shift + count;
if (High[tmp] > HH) HH = High[tmp];
if (Low[tmp] < LL) LL = Low[tmp];
}
N1 = (HH - LL) / HalfN;
HH = High[shift+HalfN-1];
LL = Low[shift+HalfN-1];
// Second half
for (count = HalfN; count <= (N-1); count++) {
tmp = shift + count;
if (High[tmp] > HH) HH = High[tmp];
if (Low[tmp] < LL) LL = Low[tmp];
}
N2 = (HH - LL) / HalfN;
if (N1 > 0 && N2 > 0 && N3 > 0) {
Dimen = (MathLog(N1 + N2) - MathLog(N3)) / MathLog(2);
}
alpha = MathExp(-4.6*(Dimen - 1));
if (alpha < 0.01) alpha = 0.01;
if (alpha > 1) alpha = 1;
Filt = (alpha*Close[shift]) + (1 - alpha)*Filt_1;
return (Filt);
}
//+------------------------------------------------------------------+
Comments