The Relative Strength Index (RSI) is one of the most widely used indicators in technical analysis, originally developed by J. Welles Wilder. Its main function is to measure the relative strength of an asset by comparing upward and downward price movements over a specific period. Traditionally, the RSI is used to identify overbought (levels above 70) and oversold (levels below 30) conditions, as well as potential trend reversals.
However, the classic RSI has limitations in markets with dominant cycles or irregular trends, as its standard calculation can produce less accurate signals. To improve its performance, the RSI Cyclic Smoothed (CRSI) was created, an advanced version that incorporates cyclic smoothing and cyclic memory to better adapt to market movements.
The RSI Cyclic Smoothed not only smooths the original RSI but also calculates dynamic bands (UpperBand and LowerBand), which adjust automatically to the asset’s cyclical levels, providing clearer signals in varying market conditions.
In this article, we will analyze how this indicator works, how to interpret it, and how you can configure it in the ProRealTime platform. Finally, the complete code in ProBuilder will be included for you to implement it in your charts.
The RSI Cyclic Smoothed (CRSI) is an advanced version of the classic RSI that incorporates two key elements to improve its performance: cyclic smoothing and cyclic memory. This allows it to adapt better to market cycles and offer more accurate signals compared to the standard RSI. Below, we break down its operation step by step:
The process begins with calculating the classic RSI, but instead of using a fixed period, an exponential smoothing factor is introduced to reduce fluctuations:
srcUp = max(src - src[1], 0) → Upward movement.srcDw = -min(src - src[1], 0) → Downward movement.if barindex = length then
up = average[length](srcUp)
dw = average[length](srcDw)
else
up = alpha * srcUp + (1 - alpha) * up[1]
dw = alpha * srcDw + (1 - alpha) * dw[1]
endif
Where:
dw = 0), RSI = 100.up = 0), RSI = 0.myrsi = 100 - 100 / (1 + up / dw)
To synchronize the RSI with market cycles, a phase adjustment is introduced using the vibration parameter:
torque = 2 / (vibration + 1)
phasinglag = floor((vibration - 1) / 2)
crsi = torque * (2 * myrsi - myrsi[phasinglag]) + (1 - torque) * crsi[1]
A unique feature of the RSI Cyclic Smoothed is the incorporation of dynamic bands, calculated based on the CRSI. These bands provide reference levels that adjust to the asset’s cyclical behavior:
The bands are determined by analyzing the CRSI history over the cyclic memory period:
for i = 0 to periodMinusone do
if crsi[i] > maxima then maxima = crsi[i]
if crsi[i] < minima then minima = crsi[i]
next
The stepfactor adjusts the precision of these levels:
stepfactor = (maxima - minima) / 100
The area between the UpperBand and LowerBand is highlighted for clarity, helping to identify consolidation or range-bound cycles.
| Parameter | Default Value | Description |
|---|---|---|
| domcycle | 20 | Duration of the dominant market cycle. |
| vibration | 10 | Smooths CRSI by reducing noise. |
| leveling | 10 | Controls the precision of dynamic bands. |
| cyclicmemory | domcycle * 2 | Historical period used to calculate dynamic bands. |
The RSI Cyclic Smoothed is a powerful enhancement to the classic RSI, offering greater adaptability through cyclic smoothing and dynamic bands. Its ability to adjust to market cycles makes it a valuable tool for identifying overbought/oversold conditions and potential trend reversals. By fine-tuning its parameters, you can optimize its performance across different timeframes and market environments.
//-------------------------------------//
//PRC_RSI Cyclic Smoothed
//version = 0
//19.11.2024
//Iván González @ www.prorealcode.com
//Sharing ProRealTime knowledge
//-------------------------------------//
//Inputs
//-------------------------------------//
src=close
domcycle=20
cyclelen=domcycle/2
vibration=10
leveling=10
cyclicmemory=domcycle*2
once crsi=0
//-------------------------------------//
// CRSI calculation
//-------------------------------------//
torque=2/(vibration+1)
phasinglag=floor((vibration-1)/2)
length = cyclelen
alpha = 1/length
srcUp = max(src-src[1],0)
if barindex = length then
up = average[length](srcUp)
else
up = alpha*srcUp + (1-alpha)*up[1]
endif
srcDw = -min(src-src[1],0)
if barindex = length then
dw = average[length](srcdw)
else
dw = alpha*srcdw + (1-alpha)*dw[1]
endif
if dw=0 then
myrsi=100
elsif up=0 then
myrsi=0
else
myrsi=100-100/(1+up/dw)
endif
if barindex>cyclicmemory then
crsi=torque*(2*myrsi-myrsi[phasinglag])+(1-torque)*crsi[1]
endif
//-------------------------------------//
// LowBand and HighBand calculation
//-------------------------------------//
Period=cyclicMemory
percent = leveling/100
periodMinusone = period-1
maxima = -999999.0
minima = 999999.0
for i=0 to periodMinusone do
if crsi[i] > maxima then
maxima = crsi[i]
elsif crsi[i] < minima then
minima = crsi[i]
endif
next
stepfactor = (maxima-minima)/100
lowband = 0
for steps=0 to 100 do
testvalue = minima+stepfactor*steps
below=0
for m=0 to periodMinusone do
if crsi[m]<testvalue then
below=below+1
endif
next
if below/period >= percent then
lowband = testvalue
break
endif
next
highband=0
for steps=0 to 100 do
testvalue=maxima-stepfactor*steps
above=0
for m=0 to periodMinusone do
if crsi[m]>=testvalue then
above=above+1
endif
next
if above/Period >= percent then
highband=testvalue
break
endif
next
colorbetween(highband,lowband,204,204,119,90)
//-------------------------------------//
// Plot
//-------------------------------------//
h1=30
h2=70
//-------------------------------------//
return highband as "UpperBand"coloured("aqua"),lowband as "LowerBand"coloured("aqua"),crsi as "CRSI"coloured("fuchsia")style(line,2), h1 as "OB level"style(dottedline), h2 as "OS level"style(dottedline)