Author: Rosh
FRAMA

Overview of the FRAMA Indicator Logic

The FRAMA (Fractal Adaptive Moving Average) is a sophisticated technical analysis tool designed to provide a smoother, more responsive visual representation of market trends. Unlike standard moving averages that apply a constant weight to price data over a fixed period, this script dynamically adjusts its sensitivity based on the prevailing volatility and "fractal" nature of the market.

Core Functional Logic

The indicator operates by analyzing the relationship between different periods of price action to determine how much importance to give to current data versus historical data. Here is a breakdown of the logic used:

1. Dynamic Price Selection The script allows for flexibility in what constitutes "price." Rather than being locked to just the closing price, the user can choose from various metrics, including the high, low, open, or specialized averages (such as Median, Typical, or Weighted prices). This ensures the indicator can be tailored to different trading styles.

2. Volatility and Fractal Analysis The primary strength of this logic lies in its "Fractal Dimension" calculation. The script looks at three distinct windows of time:

  • The immediate recent price action (the current period).
  • A secondary look-back period immediately following the first.
  • A broader, extended look-back period.

By comparing the ranges (highs vs. lows) across these different windows, the script calculates a value that represents the "complexity" of the market movement.

3. The Adaptive Weighting (ALFA) The script uses the fractal dimension result to generate an ALFA value. This is the "brain" of the indicator:

  • In Trending Markets: When the market moves in a clear, organized direction, the logic detects lower complexity and adjusts the weight to follow the trend more closely.
  • In Choppy/Sideways Markets: When the market becomes erratic or highly volatile, the fractal dimension increases, causing the indicator to smooth out more aggressively to avoid "noise" and false signals.

4. The Moving Average Calculation Finally, the script combines these elements into a single line on the chart. It takes the current price (multiplied by the ALFA weight) and blends it with the previous value of the moving average. Because the ALFA weight is constantly changing based on market conditions, the resulting line automatically speeds up during strong trends and slows down duringconsolidation phases.

Summary for Traders

In practical terms, this script aims to solve a common problem in trading: the delay of standard moving averages versus the "jitter" of fast-reacting ones. By using fractal geometry to measure market complexity, it attempts to provide a line that stays tight to the price during momentum and remains smooth when the market is unsure of its direction.

Miscellaneous
Implements a curve of type %1
16 Views
0 Downloads
0 Favorites
FRAMA
//+------------------------------------------------------------------+
//|                                                        FRAMA.mq4 |
//|                                                             Rosh |
//|                    http://www.alpari-idc.ru/ru/experts/articles/ |
//+------------------------------------------------------------------+
#property copyright "Rosh"
#property link      "http://www.alpari-idc.ru/ru/experts/articles/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DarkBlue
//---- input parameters
extern int       PeriodFRAMA=10;
extern int       PriceType=0;
//PRICE_CLOSE 0 Öåíà çàêðûòèÿ 
//PRICE_OPEN 1 Öåíà îòêðûòèÿ 
//PRICE_HIGH 2 Ìàêñèìàëüíàÿ öåíà 
//PRICE_LOW 3 Ìèíèìàëüíàÿ öåíà 
//PRICE_MEDIAN 4 Ñðåäíÿÿ öåíà, (high+low)/2 
//PRICE_TYPICAL 5 Òèïè÷íàÿ öåíà, (high+low+close)/3 
//PRICE_WEIGHTED 6 Âçâåøåííàÿ öåíà çàêðûòèÿ, (high+low+close+close)/4 

//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| âîçâðàùàåò öåíó                                                  |
//+------------------------------------------------------------------+
double Price(int shift)
  {
//----
   double res;
//----
   switch (PriceType)
      {
      case PRICE_OPEN: res=Open[shift]; break;
      case PRICE_HIGH: res=High[shift]; break;
      case PRICE_LOW: res=Low[shift]; break;
      case PRICE_MEDIAN: res=(High[shift]+Low[shift])/2.0; break;
      case PRICE_TYPICAL: res=(High[shift]+Low[shift]+Close[shift])/3.0; break;
      case PRICE_WEIGHTED: res=(High[shift]+Low[shift]+2*Close[shift])/4.0; break;
      default: res=Close[shift];break;
      }
   return(res);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   double Hi1,Lo1,Hi2,Lo2,Hi3,Lo3;   
   double N1,N2,N3,D;
   double ALFA;
   int limit;
   int    counted_bars=IndicatorCounted();
   if (counted_bars==0) limit=Bars-2*PeriodFRAMA;
   if (counted_bars>0) limit=Bars-counted_bars;
   limit--;
      
//----
   for (int i=limit;i>=0;i--)
      {
      Hi1=High[iHighest(Symbol(),0,MODE_HIGH,PeriodFRAMA,i)];
      Lo1=Low[iLowest(Symbol(),0,MODE_LOW,PeriodFRAMA,i)];
      Hi2=High[iHighest(Symbol(),0,MODE_HIGH,PeriodFRAMA,i+PeriodFRAMA)];
      Lo2=Low[iLowest(Symbol(),0,MODE_LOW,PeriodFRAMA,i+PeriodFRAMA)];
      Hi3=High[iHighest(Symbol(),0,MODE_HIGH,2*PeriodFRAMA,i)];
      Lo3=Low[iLowest(Symbol(),0,MODE_LOW,2*PeriodFRAMA,i)];
      N1=(Hi1-Lo1)/PeriodFRAMA;
      N2=(Hi2-Lo2)/PeriodFRAMA;
      N3=(Hi3-Lo3)/(2.0*PeriodFRAMA);
      D=(MathLog(N1+N2)-MathLog(N3))/MathLog(2.0);
      ALFA=MathExp(-4.6*(D-1.0));
      ExtMapBuffer1[i]=ALFA*Price(i)+(1-ALFA)*ExtMapBuffer1[i+1];
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments