This script is designed to provide a specialized visual analysis of market price movements by calculating a "normalized" value based on statistical deviations. Unlike standard indicators that simply show moving averages or raw prices, this tool focuses on measuring how extreme a specific price point is relative to recent historical trends.
Core Logic and Functionality
The indicator operates by examining the relationship between current price action and two primary statistical components:
- Moving Average: It identifies the "center" of the price trend over a user-defined period.
- Standard Deviation: It calculates the "volatility" or the typical range within which the price usually moves.
Instead of simply plotting these numbers, the script combines them into a mathematical formula to determine the "distance" of the current price from the average. Specifically, it measures how many standard deviations the price is currently away from its mean.
The Normalization Process
The unique logic of this tool lies in how it interprets that distance:
- Probability Weighting: It treats the market movement as a distribution. By taking the difference between the current price and the average, and dividing it by the standard deviation, it determines the "intensity" of the current move.
- Exponential Smoothing: The script then applies an exponential function to this result. In practical terms, this translates raw, volatile price swings into a smoother, normalized scale. This helps traders see the relative strength or weakness of a move regardless of whether the asset is trading at high or low nominal values.
- Customizable Inputs: Users can choose which specific data point to analyze—such as the Open, High, Low, or Close prices—allowing for a versatile look at different market behaviors (e.g., analyzing "High" price extremes versus "Close" price trends).
Visual Output
The final result is displayed in a separate window on your trading platform. It provides a line that oscillates based on the "normalized" intensity of the price.
- When the value is high, it indicates that the price is moving significantly far away from its recent average.
- When the value is low, it suggests the price is stabilizing or staying very close to its expected trend.
By using this normalization technique, the script filters out some of the "noise" of raw price action, allowing for a clearer view of significant structural deviations in the market.
//+------------------------------------------------------------------+
//| NormalizedVolume.mq4 |
//| Vadim Shumilov (DrShumiloff) |
//| shumiloff@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Vadim Shumilov (DrShumiloff)"
#property link "shumiloff@mail.ru"
//----
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Lime
#property indicator_level1 0
#property indicator_level2 1
#property indicator_level3 0.5
extern string Symbol1 = "";
extern int ClosePeriod = 8;
extern int NrBars = 500;
extern int Shift1=0;
extern int price=PRICE_CLOSE; //PRICE_HIGH,PRICE_LOW,PRICE_OPEN
extern int Period1=PERIOD_W1;
double CloseBuffer[];
int init()
{
if(Symbol1=="")Symbol1=Symbol();
string short_name;
IndicatorBuffers(1);
//SetIndexBuffer(1, CloseBuffer);
SetIndexStyle(0, DRAW_LINE);
SetIndexBuffer(0, CloseBuffer);
//SetIndexDrawBegin(0, CloseBuffer);
short_name="Normalize(" + ClosePeriod + ")";
IndicatorShortName(short_name);
SetIndexLabel(0, short_name);
return(0);
}
int start()
{
double x1;
int i;
//int counted_bars = IndicatorCounted();
//if (counted_bars < 1)
// for (i = 1; i <= ClosePeriod; i++) CloseBuffer[NrBars-i] = 0.0;
//int limit = NrBars - counted_bars;
//if (counted_bars > 0) limit++;
//for(i = 0; i < limit; i++)
//{
// fill_buff(price,Symbol1,Period1,0,i,Shift1,CloseBuffer,x1,1,0,false);
//}
for(i=NrBars; i>=0; i--)
{
fill_buff(price,Symbol1,Period1,0,i,Shift1,CloseBuffer,x1,1,0,false);
}
return(0);
}
double NormalizedClose(int i)
{
double nv = 0;
for (int j = 0; j < ClosePeriod; j++)
nv = nv + Close[j];
nv = nv / ClosePeriod;
return (Close[i] / nv);
}
void fill_buff(int pr,string Symb,int per,int baseper,int i,int shift012,double &Buff[],double &x1,double a,double b,bool log)
{
//double x1;
double nv = 0;
int j;
double ma1;
double sd1;
double t1;
int pos1 = iBarShift(Symb, per, iTime(0,baseper,i), false);
//if(shift012==0)
// if (iTime(Symb,per,pos1+shift012) == iTime(Symb,baseper,i)) // have to be sure the times match.
// {
//x1=iMA(Symb,per,ma,0,0,Price1,pos1+shift012);
if(pr==PRICE_CLOSE)
{
//x1=iClose(Symb,per,pos1+shift012);
//for (j = pos1+shift012; j < pos1+shift012+ClosePeriod; j++)
// nv = nv + iClose(Symb,per,j);
//nv = nv / ClosePeriod;
//x1=(iClose(Symb,per,pos1+shift012)/ nv);
ma1=iMA (Symb,per,ClosePeriod,0,MODE_SMA,PRICE_CLOSE,pos1+shift012);
sd1=iStdDev(Symb,per,ClosePeriod,0,MODE_SMA,PRICE_CLOSE,pos1+shift012);
t1=MathPow(iClose(Symb,per,pos1+shift012)-ma1,2)/(2*MathPow(sd1,2));
x1=MathExp(-t1);
}
else if(pr==PRICE_OPEN)
{
//x1=iOpen(Symb,per,pos1+shift012);
//for (j = pos1+shift012; j < pos1+shift012+ClosePeriod; j++)
// nv = nv + iOpen(Symb,per,j);
//nv = nv / ClosePeriod;
//x1=(iOpen(Symb,per,pos1+shift012)/ nv);
ma1=iMA (Symb,per,ClosePeriod,0,MODE_SMA,PRICE_OPEN,pos1+shift012);
sd1=iStdDev(Symb,per,ClosePeriod,0,MODE_SMA,PRICE_OPEN,pos1+shift012);
t1=MathPow(iOpen(Symb,per,pos1+shift012)-ma1,2)/(2*MathPow(sd1,2));
x1=MathExp(-t1);
}
else if(pr==PRICE_HIGH)
{
//x1=iHigh(Symb,per,pos1+shift012);
//for (j = pos1+shift012; j < pos1+shift012+ClosePeriod; j++)
// nv = nv + iHigh(Symb,per,j);
//nv = nv / ClosePeriod;
//x1=(iHigh(Symb,per,pos1+shift012)/ nv);
ma1=iMA (Symb,per,ClosePeriod,0,MODE_SMA,PRICE_HIGH,pos1+shift012);
sd1=iStdDev(Symb,per,ClosePeriod,0,MODE_SMA,PRICE_HIGH,pos1+shift012);
t1=MathPow(iHigh(Symb,per,pos1+shift012)-ma1,2)/(2*MathPow(sd1,2));
x1=MathExp(-t1);
}
else if(pr==PRICE_LOW)
{
//x1=iLow(Symb,per,pos1+shift012);
//for (j = pos1+shift012; j < pos1+shift012+ClosePeriod; j++)
// nv = nv + iLow(Symb,per,j);
//nv = nv / ClosePeriod;
//x1=(iLow(Symb,per,pos1+shift012)/ nv);
ma1=iMA (Symb,per,ClosePeriod,0,MODE_SMA,PRICE_LOW,pos1+shift012);
sd1=iStdDev(Symb,per,ClosePeriod,0,MODE_SMA,PRICE_LOW,pos1+shift012);
t1=MathPow(iLow(Symb,per,pos1+shift012)-ma1,2)/(2*MathPow(sd1,2));
x1=MathExp(-t1);
}
if(log)
Buff[i]=MathLog(x1);
else
Buff[i]=(x1);
// }
// else
// Buff[i]=x1;
//else
//{
// x1=iMA(Symb,per,ma,0,0,0,pos1+shift012);
// Buff[i]=x1;
//}
}
Comments