precision_trend_2
Download scriptThis script is designed to help traders identify and visualize market trends by analyzing price movements with a focus on "precision." It functions by calculating the volatility and direction of price action to determine whether the current market bias is bullish (upward) or bearish (downward).
Core Logic Overview
The indicator operates by measuring the range of price movement—specifically the distance between the high and low points of each candle—and comparing that range against a moving average. By doing this, the script filters out minor market "noise" and focuses on significant price shifts.
How it Works
- Volatility Analysis: The tool looks at a specific number of past periods (defined by the Average Period) to calculate an average volatility score. It then applies a sensitivity multiplier to these results. This allows the user to decide how aggressively the indicator should react to new price movements.
- Dynamic Trend Tracking: Instead of just looking at simple price levels, the logic tracks "dynamic boundaries." It establishes upper and lower zones based on the current average volatility.
- Trend Detection:
- If the price breaks above a calculated upper boundary, the script identifies a bullish trend.
- If the price drops below a calculated lower boundary, it identifies a bearish trend.
- State Awareness: The logic is "persistent," meaning it remembers the current trend direction and only switches signals when the price confirms a significant enough break to overcome the previous momentum.
Visual Representation
The script translates these calculations into visual cues on your chart:
- When the market is identified as being in an upward trend, it highlights the data points accordingly (typically represented in Green).
- When the market shifts into a downward trend, it updates the visuals to reflect that change (typically represented in Red).
Summary for the User
In simple terms, this tool acts as a smart filter. It ignores small, insignificant price flickers and only signals a trend change when the price moves with enough strength to exceed the established "normal" volatility of the market. This helps traders stay aligned with the primary direction of the trend while avoiding getting caught in minor fluctuations.
//+------------------------------------------------------------------+
//| precision trend.mq4 |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link "mladenfx@gmail.com"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Green
#property indicator_color2 Red
#property indicator_width1 1
#property indicator_width2 1
#property strict
//
//
//
//
//
extern int avgPeriod = 30; // Average period
extern double sensitivity = 3; // Sensitivity
double upBuffer[],dnBuffer[];
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
int OnInit()
{
SetIndexBuffer(0,upBuffer); SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(1,dnBuffer); SetIndexStyle(1,DRAW_HISTOGRAM);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) { return; }
int OnCalculate (const int rates_total,
const int prev_calculated,
const datetime& btime[],
const double& open[],
const double& high[],
const double& low[],
const double& close[],
const long& tick_volume[],
const long& volume[],
const int& spread[] )
{
int counted_bars = prev_calculated;
if(counted_bars < 0) return(-1);
if(counted_bars > 0) counted_bars--;
int limit=MathMin(rates_total-counted_bars,rates_total-1);
//
//
//
//
//
for(int i=limit; i>=0 && !_StopFlag; i--)
{
upBuffer[i] = EMPTY_VALUE;
dnBuffer[i] = EMPTY_VALUE;
double trend = iPrecisionTrend(high,low,close,avgPeriod,sensitivity,i,rates_total);
if (trend == 1) { upBuffer[i] = High[i]; dnBuffer[i] = Low[i]; }
if (trend == -1) { dnBuffer[i] = High[i]; upBuffer[i] = Low[i]; }
}
return(rates_total);
}
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
#define _ptInstances 1
#define _ptInstancesSize 7
double _ptWork[][_ptInstances*_ptInstancesSize];
#define __range 0
#define __trend 1
#define __avgr 2
#define __avgd 3
#define __avgu 4
#define __minc 5
#define __maxc 6
double iPrecisionTrend(const double& _high[], const double& _low[], const double& _close[], int _period, double _sensitivity, int i, int bars, int instanceNo=0)
{
if (ArrayRange(_ptWork,0)!=bars) ArrayResize(_ptWork,bars); instanceNo*=_ptInstancesSize; int r=bars-i-1;
//
//
//
//
//
_ptWork[r][instanceNo+__range] = _high[i]-_low[i];
_ptWork[r][instanceNo+__avgr] = _ptWork[r][instanceNo+__range];
int k=1; for (; k<_period && (r-k)>=0; k++) _ptWork[r][instanceNo+__avgr] += _ptWork[r-k][instanceNo+__range];
_ptWork[r][instanceNo+__avgr] /= k;
_ptWork[r][instanceNo+__avgr] *= _sensitivity;
//
//
//
//
//
if (i==(bars-1))
{
_ptWork[r][instanceNo+__trend] = 0;
_ptWork[r][instanceNo+__avgd] = _close[i]-_ptWork[r][instanceNo+__avgr];
_ptWork[r][instanceNo+__avgu] = _close[i]+_ptWork[r][instanceNo+__avgr];
_ptWork[r][instanceNo+__minc] = _close[i];
_ptWork[r][instanceNo+__maxc] = _close[i];
}
else
{
_ptWork[r][instanceNo+__trend] = _ptWork[r-1][instanceNo+__trend];
_ptWork[r][instanceNo+__avgd] = _ptWork[r-1][instanceNo+__avgd];
_ptWork[r][instanceNo+__avgu] = _ptWork[r-1][instanceNo+__avgu];
_ptWork[r][instanceNo+__minc] = _ptWork[r-1][instanceNo+__minc];
_ptWork[r][instanceNo+__maxc] = _ptWork[r-1][instanceNo+__maxc];
//
//
//
//
//
switch((int)_ptWork[r-1][instanceNo+__trend])
{
case 0 :
if (_close[i]>_ptWork[r-1][instanceNo+__avgu])
{
_ptWork[r][instanceNo+__minc] = _close[i];
_ptWork[r][instanceNo+__avgd] = _close[i]-_ptWork[r][instanceNo+__avgr];
_ptWork[r][instanceNo+__trend] = 1;
}
if (_close[i]<_ptWork[r-1][instanceNo+__avgd])
{
_ptWork[r][instanceNo+__maxc] = _close[i];
_ptWork[r][instanceNo+__avgu] = _close[i]+_ptWork[r][instanceNo+__avgr];
_ptWork[r][instanceNo+__trend] = -1;
}
break;
case 1 :
_ptWork[r][instanceNo+__avgd] = _ptWork[r-1][instanceNo+__minc] - _ptWork[r][instanceNo+__avgr];
if (_close[i]>_ptWork[r-1][instanceNo+__minc]) _ptWork[r][instanceNo+__minc] = _close[i];
if (_close[i]<_ptWork[r-1][instanceNo+__avgd])
{
_ptWork[r][instanceNo+__maxc] = _close[i];
_ptWork[r][instanceNo+__avgu] = _close[i]+_ptWork[r][instanceNo+__avgr];
_ptWork[r][instanceNo+__trend] = -1;
}
break;
case -1 :
_ptWork[r][instanceNo+__avgu] = _ptWork[r-1][instanceNo+__maxc] + _ptWork[r][instanceNo+__avgr];
if (_close[i]<_ptWork[r-1][instanceNo+__maxc]) _ptWork[r][instanceNo+__maxc] = _close[i];
if (_close[i]>_ptWork[r-1][instanceNo+__avgu])
{
_ptWork[r][instanceNo+__minc] = _close[i];
_ptWork[r][instanceNo+__avgd] = _close[i]-_ptWork[r][instanceNo+__avgr];
_ptWork[r][instanceNo+__trend] = 1;
}
}
}
return(_ptWork[r][instanceNo+__trend]);
}
Comments