Author: Copyright � 2007, MetaQuotes Software Corp.
nma40

This script is designed as a custom technical indicator for the MetaTrader 4 platform. Its primary purpose is to calculate and display a specialized moving average that reacts to price changes based on historical volatility and logarithmic scaling.

Core Logic Overview

The indicator processes historical price data to create a "smoothed" line on your chart. Unlike standard moving averages that treat every period with equal importance, this script uses a complex mathematical approach to determine how much weight to give to recent price movements.

Step-by-Step Breakdown

1. Logarithmic Price Transformation The logic begins by converting the closing prices of the market into logarithmic values. By using logarithms instead of raw prices, the script effectively normalizes the data. This helps in viewing percentage-based changes rather than absolute point changes, making the indicator more stable across different price levels.

2. Volatility Difference Calculation The script looks back at a specific window of historical data (approximately 40 bars). For each of these bars, it calculates the difference between consecutive logarithmic prices. It then takes the "absolute value" of these differences, which means it is measuring the magnitude of price movement regardless of whether the price went up or down.

3. Weighted Volatility Analysis The script performs two different types of summations to compare the current market state:

  • Standard Sum: A total count of all price movements over the lookback period.
  • Adjusted Sum: A calculation where each price movement is multiplied by a specific square root factor. This creates a "weighted" volatility profile.

4. The Ratio Calculation By dividing the Adjusted Sum by the Standard Sum, the script generates a unique Ratio. This ratio represents the current balance between "standard" price activity and "weighted" price activity. It essentially tells the indicator how aggressively it should respond to new information based on the prevailing market volatility.

5. Dynamic Smoothing (The Output) Finally, the script applies this Ratio to a self-adjusting Moving Average. Instead of using a fixed multiplier (like the standard 2 or 3 used in typical EMAs), it uses the calculated Ratio to determine how much of the newest price change should be integrated into the current line value.

Visual Representation

The result is a moving average line that dynamically adjusts its "smoothness." When market volatility behaves in a specific way, the ratio changes, causing the indicator to potentially react faster or slower to price swings than a traditional moving average would.

11 Views
0 Downloads
0 Favorites
nma40
//+------------------------------------------------------------------+
//|                                                          nmm.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property indicator_buffers 4
#property indicator_chart_window
double extmapbuffer1[];
double extmapbuffer2[];
double extmapbuffer3[];
double extmapbuffer4[];
#property indicator_color1 Blue
#property indicator_color2 Blue
#property indicator_color3 Green
#property indicator_color4 Yellow
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  SetIndexStyle (0,DRAW_LINE);
  SetIndexStyle (1,DRAW_LINE);
  SetIndexStyle (2,DRAW_LINE);
  SetIndexStyle (3, DRAW_LINE);

  SetIndexBuffer (0, extmapbuffer1);
  SetIndexBuffer (1, extmapbuffer2);
  SetIndexBuffer (2, extmapbuffer3);
  SetIndexBuffer (3, extmapbuffer4);

  string short_name = "NMR";
  IndicatorShortName (short_name);
//---- indicators
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   double thisbar, ema, emalast;
   int counted_bars=IndicatorCounted();
   double sum=0,sum2=0, ratio, dif0,dif1,dif2,dif3,dif4,dif5,dif6,dif7,dif8,dif9,dif10,dif11,dif12,dif13,dif14,dif15,dif16,dif17,dif18,dif19,dif20,dif21,dif22,dif23,dif24,dif25,dif26,dif27,dif28,dif29,dif30,dif31,dif32,dif33,dif34,dif35,dif36,dif37,dif38,dif39,dif40;
   double  adif0,adif1,adif2,adif3,adif4,adif5,adif6,adif7,adif8,adif9,adif10,adif11,adif12,adif13,adif14,adif15,adif16,adif17,adif18,adif19,adif20,adif21,adif22,adif23,adif24,adif25,adif26,adif27,adif28,adif29,adif30,adif31,adif32,adif33,adif34,adif35,adif36,adif37,adif38,adif39,adif40;
   int pos = Bars+1;
   for (;pos >=0 ; pos--)
   {
   sum=0;
   sum2=0;
   if (counted_bars<0) return (-1);
   if (counted_bars>0) counted_bars--;
   dif0 = MathAbs(MathLog(Close[pos])*100000 - MathLog(Close [pos+1])*100000);
   dif1 = MathAbs(MathLog(Close[pos+1])*100000 - MathLog(Close [pos+2])*100000);
   dif2 = MathAbs(MathLog(Close[pos+2])*100000 - MathLog(Close [pos+3])*100000) ;
   dif3 = MathAbs(MathLog(Close[pos+3])*100000 - MathLog(Close [pos+4])*100000) ;
   dif4 = MathAbs(MathLog(Close[pos+4])*100000 - MathLog(Close [pos+5])*100000) ;
   dif5 = MathAbs(MathLog(Close[pos+5])*100000 - MathLog(Close [pos+6])*100000) ;
   dif6 = MathAbs(MathLog(Close[pos+6])*100000 - MathLog(Close [pos+7])*100000) ;
   dif7 = MathAbs(MathLog(Close[pos+7])*100000 - MathLog(Close [pos+8])*100000) ;
   dif8 = MathAbs(MathLog(Close[pos+8])*100000 - MathLog(Close [pos+9])*100000) ;
   dif9 = MathAbs(MathLog(Close[pos+9])*100000 - MathLog(Close [pos+10])*100000) ;
   dif10 = MathAbs(MathLog(Close[pos+10])*100000 - MathLog(Close [pos+11])*100000); 
   dif11 = MathAbs(MathLog(Close[pos+11])*100000 - MathLog(Close [pos+12])*100000) ;
   dif12 = MathAbs(MathLog(Close[pos+12])*100000 - MathLog(Close [pos+13])*100000) ;
   dif14 = MathAbs(MathLog(Close[pos+13])*100000 - MathLog(Close [pos+14])*100000) ;
   dif15 = MathAbs(MathLog(Close[pos+14])*100000 - MathLog(Close [pos+15])*100000) ;
   dif16 = MathAbs(MathLog(Close[pos+15])*100000 - MathLog(Close [pos+16])*100000);
   dif17 = MathAbs(MathLog(Close[pos+16])*100000 - MathLog(Close [pos+17])*100000) ;
   dif18 = MathAbs(MathLog(Close[pos+17])*100000 - MathLog(Close [pos+18])*100000) ;
   dif19 = MathAbs(MathLog(Close[pos+18])*100000 - MathLog(Close [pos+19])*100000);
   dif20 = MathAbs(MathLog(Close[pos+19])*100000 - MathLog(Close [pos+20])*100000);
   dif21 = MathAbs(MathLog(Close[pos+20])*100000 - MathLog(Close [pos+21])*100000) ;
   dif22 = MathAbs(MathLog(Close[pos+21])*100000 - MathLog(Close [pos+22])*100000) ;
   dif23 = MathAbs(MathLog(Close[pos+22])*100000 - MathLog(Close [pos+23])*100000) ;
   dif24 = MathAbs(MathLog(Close[pos+23])*100000 - MathLog(Close [pos+24])*100000);
   dif25 = MathAbs(MathLog(Close[pos+24])*100000 - MathLog(Close [pos+25])*100000) ;
   dif26 = MathAbs(MathLog(Close[pos+25])*100000 - MathLog(Close [pos+26])*100000) ;
   dif27 = MathAbs(MathLog(Close[pos+26])*100000 - MathLog(Close [pos+27])*100000) ;
   dif28 = MathAbs(MathLog(Close[pos+27])*100000 - MathLog(Close [pos+28])*100000);
   dif29 = MathAbs(MathLog(Close[pos+28])*100000 - MathLog(Close [pos+29])*100000) ;
   dif30 = MathAbs(MathLog(Close[pos+29])*100000 - MathLog(Close [pos+30])*100000) ;
   dif31 = MathAbs(MathLog(Close[pos+30])*100000 - MathLog(Close [pos+31])*100000) ;
   dif32 = MathAbs(MathLog(Close[pos+32])*100000 - MathLog(Close [pos+33])*100000) ;
   dif34 = MathAbs(MathLog(Close[pos+33])*100000 - MathLog(Close [pos+34])*100000) ;
   dif35 = MathAbs(MathLog(Close[pos+34])*100000 - MathLog(Close [pos+35])*100000) ;
   dif36 = MathAbs(MathLog(Close[pos+36])*100000 - MathLog(Close [pos+37])*100000) ;
   dif38 = MathAbs(MathLog(Close[pos+37])*100000 - MathLog(Close [pos+38])*100000);
   dif39 = MathAbs(MathLog(Close[pos+38])*100000 - MathLog(Close [pos+39])*100000) ;
   dif40 = MathAbs(MathLog(Close[pos+39])*100000 - MathLog(Close [pos+40])*100000) ;
   adif0 = MathAbs(MathLog(Close[pos])*100000 - MathLog(Close [pos+1])*100000) * (MathSqrt(1)-MathSqrt(0));
   adif1 = MathAbs(MathLog(Close[pos+1])*100000 - MathLog(Close [pos+2])*100000) * (MathSqrt(2)-MathSqrt(1));
   adif2 = MathAbs(MathLog(Close[pos+2])*100000 - MathLog(Close [pos+3])*100000) * (MathSqrt(3)-MathSqrt(2));
   adif3 = MathAbs(MathLog(Close[pos+3])*100000 - MathLog(Close [pos+4])*100000) * (MathSqrt(4)-MathSqrt(3));
   adif4 = MathAbs(MathLog(Close[pos+4])*100000 - MathLog(Close [pos+5])*100000) * (MathSqrt(5)-MathSqrt(4));
   adif5 = MathAbs(MathLog(Close[pos+5])*100000 - MathLog(Close [pos+6])*100000)* (MathSqrt(6)-MathSqrt(5));
   adif6 = MathAbs(MathLog(Close[pos+6])*100000 - MathLog(Close [pos+7])*100000) * (MathSqrt(7)-MathSqrt(6));
   adif7 = MathAbs(MathLog(Close[pos+7])*100000 - MathLog(Close [pos+8])*100000) * (MathSqrt(8)-MathSqrt(7));
   adif8 = MathAbs(MathLog(Close[pos+8])*100000 - MathLog(Close [pos+9])*100000) * (MathSqrt(9)-MathSqrt(8));
   adif9 = MathAbs(MathLog(Close[pos+9])*100000 - MathLog(Close [pos+10])*100000) * (MathSqrt(10)-MathSqrt(9));
   adif10 =MathAbs (MathLog(Close[pos+10])*100000 - MathLog(Close [pos+11])*100000) * (MathSqrt(11)-MathSqrt(10));
   adif11 =MathAbs (MathLog(Close[pos+11])*100000 - MathLog(Close [pos+12])*100000) * (MathSqrt(12)-MathSqrt(11));
   adif12 =MathAbs (MathLog(Close[pos+12])*100000 - MathLog(Close [pos+13])*100000) * (MathSqrt(13)-MathSqrt(12));
   adif14 =MathAbs (MathLog(Close[pos+13])*100000 - MathLog(Close [pos+14])*100000) * (MathSqrt(14)-MathSqrt(13));
   adif15 =MathAbs (MathLog(Close[pos+14])*100000 - MathLog(Close [pos+15])*100000) * (MathSqrt(15)-MathSqrt(14));
   adif16 =MathAbs (MathLog(Close[pos+15])*100000 - MathLog(Close [pos+16])*100000) * (MathSqrt(16)-MathSqrt(15));
   adif17 =MathAbs (MathLog(Close[pos+16])*100000 - MathLog(Close [pos+17])*100000) * (MathSqrt(17)-MathSqrt(16));
   adif18 =MathAbs (MathLog(Close[pos+17])*100000 - MathLog(Close [pos+18])*100000) * (MathSqrt(18)-MathSqrt(17));
   adif19 =MathAbs (MathLog(Close[pos+18])*100000 - MathLog(Close [pos+19])*100000) * (MathSqrt(19)-MathSqrt(18));
   adif20 =MathAbs (MathLog(Close[pos+19])*100000 - MathLog(Close [pos+20])*100000) * (MathSqrt(20)-MathSqrt(19));
   adif21 =MathAbs (MathLog(Close[pos+20])*100000 - MathLog(Close [pos+21])*100000) * (MathSqrt(21)-MathSqrt(20));
   adif22 =MathAbs (MathLog(Close[pos+21])*100000 - MathLog(Close [pos+22])*100000) * (MathSqrt(22)-MathSqrt(21));
   adif23 =MathAbs (MathLog(Close[pos+22])*100000 - MathLog(Close [pos+23])*100000) * (MathSqrt(23)-MathSqrt(22));
   adif24 =MathAbs (MathLog(Close[pos+23])*100000 - MathLog(Close [pos+24])*100000) * (MathSqrt(24)-MathSqrt(23));
   adif25 =MathAbs (MathLog(Close[pos+24])*100000 - MathLog(Close [pos+25])*100000) * (MathSqrt(25)-MathSqrt(24));
   adif26 =MathAbs (MathLog(Close[pos+25])*100000 - MathLog(Close [pos+26])*100000) * (MathSqrt(26)-MathSqrt(25));
   adif27 =MathAbs (MathLog(Close[pos+26])*100000 - MathLog(Close [pos+27])*100000) * (MathSqrt(27)-MathSqrt(26));
   adif28 =MathAbs (MathLog(Close[pos+27])*100000 - MathLog(Close [pos+28])*100000) * (MathSqrt(28)-MathSqrt(27));
   adif29 =MathAbs (MathLog(Close[pos+28])*100000 - MathLog(Close [pos+29])*100000) * (MathSqrt(29)-MathSqrt(28));
   adif30 =MathAbs (MathLog(Close[pos+29])*100000 - MathLog(Close [pos+30])*100000) * (MathSqrt(30)-MathSqrt(29));
   adif31 =MathAbs (MathLog(Close[pos+30])*100000 - MathLog(Close [pos+31])*100000) * (MathSqrt(31)-MathSqrt(30));
   adif32 =MathAbs (MathLog(Close[pos+31])*100000 - MathLog(Close [pos+32])*100000) * (MathSqrt(32)-MathSqrt(31));
   adif33 =MathAbs (MathLog(Close[pos+32])*100000 - MathLog(Close [pos+33])*100000) * (MathSqrt(33)-MathSqrt(32));
   adif34 =MathAbs (MathLog(Close[pos+33])*100000 - MathLog(Close [pos+34])*100000) * (MathSqrt(34)-MathSqrt(33));
   adif35 =MathAbs (MathLog(Close[pos+34])*100000 - MathLog(Close [pos+35])*100000) * (MathSqrt(35)-MathSqrt(34));
   adif36 =MathAbs (MathLog(Close[pos+35])*100000 - MathLog(Close [pos+36])*100000) * (MathSqrt(36)-MathSqrt(35));
   adif37 =MathAbs (MathLog(Close[pos+36])*100000 - MathLog(Close [pos+37])*100000) * (MathSqrt(37)-MathSqrt(36));
   adif38 =MathAbs (MathLog(Close[pos+37])*100000 - MathLog(Close [pos+38])*100000) * (MathSqrt(38)-MathSqrt(37));
   adif39 =MathAbs (MathLog(Close[pos+38])*100000 - MathLog(Close [pos+39])*100000) * (MathSqrt(39)-MathSqrt(38));
   adif40 =MathAbs (MathLog(Close[pos+39])*100000 - MathLog(Close [pos+40])*100000) * (MathSqrt(40)-MathSqrt(39));
   sum = dif1+dif2+dif3+dif4+dif5+dif6+dif7+dif8+dif9+dif10+dif11+dif12+dif13+dif14+dif15+dif16+dif17+dif18+dif19+dif20+dif21+dif22+dif23+dif24+dif25+dif26+dif27+dif28+dif29+dif30+dif31+dif32+dif33+dif34+dif35+dif36+dif37+dif38+dif39+dif40;
   sum2 = adif1+adif2+adif3+adif4+adif5+adif6+adif7+adif8+adif9+adif10+adif11+adif12+adif13+adif14+adif15+adif16+adif17+adif18+adif19+adif20+adif21+adif22+adif23+adif24+adif25+adif26+adif27+adif28+adif29+adif30+adif31+adif32+adif33+adif34+adif35+adif36+adif37+adif38+adif39+adif40;
   ratio = MathRound(sum2)/MathRound(sum);

   thisbar=Close[pos];
   ema = ema + (ratio * (thisbar-ema));
   extmapbuffer1[pos] = ema;
   
   }
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments