This custom indicator is designed to provide a smoothed, responsive visualization of price movements on your trading chart. Rather than simply following the raw price—which can often be "noisy" or jagged—this script applies a mathematical filter to help identify underlying trends while attempting to minimize the delay typically associated with moving averages.
Core Logic and Mechanics
Volatility Assessment The script begins by analyzing a specific look-back period of historical data. It calculates the volatility of the market by measuring the changes in the range (the distance between the highest high and lowest low) of previous candles. By averaging these variations, the indicator establishes a "sensitivity threshold." This ensures that the tool understands whether the current market is moving aggressively or calmly.
Price Smoothing & Movement Calculation The tool tracks the midpoint of each candle price to determine its direction. As it processes new data, it calculates the difference between the current price and the previous one. To prevent the indicator from reacting too wildly to sudden, insignificant price spikes, it uses a "smoothing" mechanism. If the price jump exceeds a certain proportion of the calculated volatility (governed by the Alpha setting), the script caps that movement to keep the line stable.
Trend Preservation One of the primary goals of this logic is to maintain the integrity of the trend. The script includes specific checks to ensure that the indicator doesn't "flip" or create false signals prematurely:
- If the price moves in a direction that contradicts the current momentum, the tool adjusts its calculation to reduce the influence of that movement.
- It utilizes a latency factor to refine how quickly the line catches up to new price action.
Visual Output The final result is a continuous red line on your chart. Because it balances reactivity with smoothness, it aims to provide a clearer picture of where the market is heading by filtering out minor fluctuations while still remaining responsive enough to reflect significant shifts in market direction.
//+------------------------------------------------------------------+
//| Copyright (C) Grzegorz Szczerba |
//| grzegorz.szczerba@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Grzegorz Szczerba"
#property link "grzegorz.szczerba@gmail.com"
//---
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---
extern double Alpha=1.0;
extern double Variation=30.0;
extern double Period=20.0;
extern double Latency=1.5;
//---
double buffer[];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(1);
//---
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,buffer);
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
if(counted_bars==0) limit-=2;
//---
for(int i=limit;i>=0;i--)
{
double h0 = iHigh(NULL, 0, i);
double l0 = iLow(NULL, 0, i);
double h1 = iHigh(NULL, 0, i + 1);
double l1 = iLow(NULL, 0, i + 1);
double var= 0;
for(int j = 1; j<= Period; j++)
{
double hv1 = iHigh(NULL, 0, i + j);
double lv1 = iLow(NULL, 0, i + j);
double hv2 = iHigh(NULL, 0, i + j + 1);
double lv2 = iLow(NULL, 0, i + j + 1);
//---
var+=MathAbs((hv1-lv1) -(hv2-lv2));
}
var/=(double)Period;
//---
double val=(h0+l0)/2.0;
//---
if(buffer[i+1]>1000000 || buffer[i+2]>1000000)
{
//FIRST VALUES
buffer[i]=val;
continue;
}
else
{
double diffB= buffer[i+1]-buffer[i+2];
double diff = val -(h1+l1)/2.0;
if(diffB>Alpha*var)
{
diffB=Alpha*var;
}
if(diffB<-Alpha*var)
{
diffB=-Alpha*var;
}
//---
double c=var/Variation;
if(val>buffer[i+1])
{
if(diff<0)
{
c=0;
diffB=diffB/Latency;
}
buffer[i]=buffer[i+1]+diffB+c;
}
else
{
if(diff>0)
{
c=0;
diffB=diffB/Latency;
}
buffer[i]=buffer[i+1]+diffB-c;
}
}
}
return(0);
}
//+------------------------------------------------------------------+
Comments