Normalizer_3param_ML
Download scriptThis script is designed to take a standard financial trading indicator (such as the MACD or CCI) and "normalize" its data. In simple terms, it converts raw, fluctuating numbers into a consistent scale that is much easier for a trader to interpret visually.
How the Logic Works
1. Indicator Integration The script begins by connecting to a secondary indicator of your choice. It takes the raw output from that indicator and centers it around a specific midpoint. This ensures that the starting point for all subsequent calculations is balanced.
2. Dynamic Period Detection (Learning the Market) One of the unique features of this logic is its ability to "study" the historical behavior of the market. The script scans back through past price data to identify every instance where your chosen indicator crossed the zero line. By measuring how frequently these crossovers occur, it automatically calculates a "characteristic period." This means the script adapts itself to the specific speed or volatility of the asset you are trading.
3. Volatility Scaling To prevent large price swings from making the indicator line jump erratically, the script performs a mathematical calculation based on the characteristic period identified in the previous step. It measures the standard deviation (the intensity of the movements) over that timeframe. By dividing the current indicator value by this volatility measurement, it "flattens" the data. This ensures that the indicator remains within a predictable range regardless of whether the market is moving calmly or violently.
4. The Tanh Smoothing Function Finally, the script applies a mathematical function called Hyperbolic Tangent (Tanh). This acts as a sophisticated smoothing filter. It compresses the data into a specific boundary (usually between -1 and 1), which rounds off sharp, jagged edges and produces a sleek, curved line.
The Result for the User
Instead of looking at raw numbers that might fluctuate wildly from one minute to the next, you see a smoothed, normalized line. This visual representation makes it much easier to identify trends and momentum because the "noise" of market volatility has been filtered out, leaving only the core movement of the asset.
//+------------------------------------------------------------------+
//| Normalizer.mq4 |
//| Copyright © 2008, al_su |
//| al_su31@mail.ru |
//+------------------------------------------------------------------+
//mod Normalizer_3param.mq4
#property copyright "Copyright © 2008, al_su"
#property link "al_su31@mail.ru"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
#property indicator_maximum 1
#property indicator_minimum -1
#property indicator_level1 0.25
#property indicator_level2 0.5
#property indicator_level3 0.75
#property indicator_level4 -0.25
#property indicator_level5 -0.5
#property indicator_level6 -0.75
#property indicator_levelcolor C'74,85,96'//SlateGray
//---- input parameters
#define PERIODS_CHARACTERISTIC 7
extern string Indicator="macd";//macd, cci ... any with zero cross
extern int param1=12;//Íó èëè 9, íå âàæíî...
extern int param2=26;
extern int param3=9;//Ñêîêà íàäî ïàðàìåòðîâ, ñòîêà è çàäàåì
extern int mode=0;
extern double IndMidLevel=0;
extern string note ="type-in Indicator FileName & params: macd, cci ... any with zero level cross";
//---- buffers
double Normalizer[];
double characteristic_period;
double sigma;
//-------------------------------------------------------------------------------
double Indyuk(int shift)
{
return (iCustom(0,0,Indicator,param1,param2,param3,/* è ò.ä.:)*/mode,shift)-IndMidLevel);
}
double MathTanh(double x)
{
double exp;
if(x>0) {exp=MathExp(-2*x);return ((1-exp)/(1+exp));}
else {exp=MathExp(2*x);return ((exp-1)/(1+exp));}
}
double ArrayAverage(double a[])
{
int i;
double s;
if(ArraySize(a)<1) return (0);
s=0;
for(i=0;i<ArraySize(a);i++) s+=a[i];
return (s/ArraySize(a));
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
IndicatorShortName("Normalized "+Indicator);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,Normalizer);
int i;
int count, count_zeros;
count=0;
count_zeros=0;
double periods[];
for(i=Bars-2;i>=0;i--)
{
if(Indyuk(i)*Indyuk(i+1)<0)//ïåðåõîä ÷åðåç 0
{
count++;
ArrayResize(periods,count);
periods[ArraySize(periods)-1]=0;
}
if(ArraySize(periods)>0) periods[ArraySize(periods)-1]++;
}
characteristic_period=2*PERIODS_CHARACTERISTIC*ArrayAverage(periods);
SetIndexDrawBegin(0,characteristic_period);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int i,j, counted_bars=IndicatorCounted();
double S;
//----
// for(i=Bars-counted_bars-characteristic_period-1;i>=0;i--)
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
limit=MathMax(limit,characteristic_period-1);
for (i=limit; i>=0; i--)
{
S=0;
for(j=0;j<characteristic_period;j++) S+=MathPow(Indyuk(i+j),2);
S/=characteristic_period;
S=MathSqrt(S);
if(S!=0) Normalizer[i]=Indyuk(i)/S;
Normalizer[i]=MathTanh(Normalizer[i]);
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments