TrendRSI_v3
Download scriptThe TrendRSI_v3 is a sophisticated technical analysis tool designed to identify and visualize market momentum while filtering out minor price fluctuations. Unlike standard indicators that only show where the price is moving, this script focuses on the "strength" of the movement and identifies structural shifts in the trend by combining three distinct analytical layers: Relative Strength, Exponential Smoothing, and Volatility-based Thresholds.
Core Analytical Components
1. Momentum Calculation (Relative Strength) The logic begins by analyzing the price changes over a specific period. It calculates the difference between consecutive prices to determine whether the market is moving upward or downward. By summing these movements into positive and negative values, the script generates a proprietary strength ratio. This helps establish the underlying "heartbeat" of the market's current direction.
2. Smoothing and Stabilization To prevent the indicator from reacting too aggressively to every minor tick of price movement, the raw momentum data is passed through an Exponential Moving Average (EMA) logic. This creates a smoother, more continuous line that represents the sustained trend rather than temporary spikes. It allows traders to see the "big picture" of the market's flow.
3. Volatility-Based Dynamic Channels One of the most unique features of this script is how it determines trend reversals. Instead of using fixed numbers (like a standard overbought or oversold level), it calculates the Average True Range (ATR) of the indicator itself. It then creates dynamic "boundaries" (upper and lower limits) based on a multiplier (K).
Because these boundaries are calculated based on recent volatility:
- In high-volatility markets, the boundaries widen to prevent "fake-out" signals.
- In low-volatility markets, the boundaries tighten to capture subtle trend shifts.
How the Logic Works in Practice
The script operates as a state machine that monitors whether the smoothed momentum line is breaking out of its dynamic volatility boundaries:
- Trend Identification: When the momentum line pushes above the upper dynamic boundary, the logic registers an "UpTrend." Conversely, when it breaks below the lower boundary, it identifies a "DownTrend."
- Visual Signaling: The tool provides clear visual cues (arrows) to alert the user when these trend shifts occur.
- Support and Resistance Tracking: While identifying a trend, the script also tracks the highest and lowest points of those dynamic boundaries. This allows it to project "support" or "resistance" levels within the current trend, helping traders see where price might find difficulty moving further in one direction.
Summary for the User
Essentially, TrendRSI_v3 doesn't just tell you if the price is going up or down; it tells you how strongly it is moving and identifies the specific moment the momentum breaks its previous volatility limits. It acts as a filter, smoothing out the "noise" of the market to reveal the underlying trend structure.
//+------------------------------------------------------------------+
//| TrendRSI_v3.mq4 |
//| Typical RSI revised By TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2004@list.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, TrendLaboratory Ltd."
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Silver
#property indicator_color2 LightBlue
#property indicator_color3 Tomato
//---- input parameters
extern int RSIPeriod=14;
extern int EMAPeriod= 5;
extern int ATRPeriod=14;
extern double K=4.236;//2.618
//---- buffers
double RSIindex[];
double UpTrend[];
double DnTrend[];
double RSIBuffer[];
double smin[];
double smax[];
double trend[];
int MAPeriod=1;
int Price=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- 2 additional buffers are used for counting.
IndicatorBuffers(7);
//---- indicator line
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,RSIindex);
SetIndexStyle(1,DRAW_ARROW);
SetIndexBuffer(1,UpTrend);
SetIndexStyle(2,DRAW_ARROW);
SetIndexBuffer(2,DnTrend);
SetIndexArrow(1,159);
SetIndexArrow(2,159);
SetIndexBuffer(3,RSIBuffer);
SetIndexBuffer(4,smin);
SetIndexBuffer(5,smax);
SetIndexBuffer(6,trend);
//---- name for DataWindow and indicator subwindow label
short_name="TrendRSI("+RSIPeriod+","+EMAPeriod+","+ATRPeriod+","+DoubleToStr(K,3)+")";
IndicatorShortName(short_name);
SetIndexLabel(0,short_name);
SetIndexLabel(1,"UpTrend");
SetIndexLabel(2,"DownTrend");
//----
SetIndexDrawBegin(0,RSIPeriod+EMAPeriod+ATRPeriod);
SetIndexDrawBegin(1,RSIPeriod+EMAPeriod+ATRPeriod);
SetIndexDrawBegin(2,RSIPeriod+EMAPeriod+ATRPeriod);
//----
return(0);
}
//+------------------------------------------------------------------+
//| TrendRSI_v3 |
//+------------------------------------------------------------------+
int start()
{
int i,limit,counted_bars=IndicatorCounted();
double rel;
//----
if ( counted_bars < 0 ) return(-1);
if ( counted_bars ==0 ) limit=Bars-1;
if ( counted_bars < 1 )
for( i=1;i<RSIPeriod+EMAPeriod+ATRPeriod;i++)
{
RSIindex[Bars-i]=0.0;
UpTrend[Bars-i]=0.0;
DnTrend[Bars-i]=0.0;
}
if(counted_bars>0) limit=Bars-counted_bars;
limit--;
for( i=limit; i>=0; i--)
{
double sumn=0.0,sump=0.0;
for (int k=RSIPeriod-1;k>=0;k--)
{
rel=iMA(NULL,0,MAPeriod,0,MODE_SMA,Price,i+k)-iMA(NULL,0,MAPeriod,0,MODE_SMA,Price,i+k+1);
if(rel>0) sump+=rel; else sumn-=rel;
}
double pos=sump/RSIPeriod;
double neg=sumn/RSIPeriod;
if(neg==0.0) RSIBuffer[i]=100.0;
else
RSIBuffer[i]=100.0-100.0/(1.0+pos/neg);
RSIindex[i]=RSIindex[i+1]+2.0/(1.0+EMAPeriod)*(RSIBuffer[i]-RSIindex[i+1]);
double AvgRange=0;
for ( k=ATRPeriod-1;k>=0;k--)
AvgRange+=MathAbs(RSIindex[i+k]-RSIindex[i+k+1]);
double Range = AvgRange/ATRPeriod;
smax[i]=RSIindex[i]+K*Range;
smin[i]=RSIindex[i]-K*Range;
trend[i]=trend[i+1];
if (RSIindex[i]>smax[i+1]) trend[i]=1;
if (RSIindex[i]<smin[i+1]) trend[i]=-1;
if(trend[i]>0)
{
if (smin[i]<smin[i+1]) smin[i]=smin[i+1];
UpTrend[i]=smin[i];
DnTrend[i]=EMPTY_VALUE;
}
else
{
if(smax[i]>smax[i+1]) smax[i]=smax[i+1];
UpTrend[i]=EMPTY_VALUE;
DnTrend[i]=smax[i];
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments