The classical RSI is computed on bar-to-bar price changes. The Market Structure RSI takes a different approach: instead of feeding RSI with raw price returns, it feeds it with a series that counts how many recent swing highs price has broken above (positive contribution) and how many recent swing lows price has broken below (negative contribution). The RSI formula is then applied to that running count.
The result is an oscillator that does not respond to every tick of price action, but to the structural events of the market — the moments when price actually breaks meaningful pivots. When it pushes towards 100 the market has been making higher highs by repeatedly violating swing highs; when it sinks towards 0 the market has been taking out swing lows. Around 50 the structural picture is balanced.
A 3-bar pivot is the simplest possible structural marker:
Each new pivot is appended to a list with its price and bar index. The result is a chronological catalogue of recent structural turning points, growing one entry at a time.
On every bar the indicator scans the most recent pivots from newest to oldest:
A single bar can therefore break several pivots in cascade — a strong impulsive move that takes out three previous pivot highs in one go contributes +3 to the count, while a quiet bar in the middle of a range contributes nothing.
The cumulative break-count series is fed into a standard RSI of length rsiLength. RSI takes the role it was designed for — measuring the relative weight of positive vs. negative changes over a window — but it now operates on structural events rather than on raw price changes. Optional moving-average smoothing on top of the RSI provides a slower confirmation line.
The Market Structure RSI is read like a classical RSI but with a structural meaning attached to each level:
Because the input is a count of structural events rather than continuous price, the oscillator tends to be less noisy than a standard RSI in choppy markets: as long as no pivots are broken, the count series stays flat and the RSI reverts towards 50.
//------------------------------------------------------------//
//PRC_Market Structure RSI
//version = 0
//27.05.24
//Iván González @ www.prorealcode.com
//Sharing ProRealTime knowledge
//------------------------------------------------------------//
//-----Inputs-------------------------------------------------//
rsiLength=20
OBlvl=80
OSlvl=20
strCloseType=0
maBool=1
maSelection=1
maLength=8
color=1
signals=0
//------------------------------------------------------------//
//-----Close Type---------------------------------------------//
if strCloseType then
closeTypeBull=close[1]
closeTypeBear=close[1]
else
closeTypeBull=high[1]
closeTypeBear=low[1]
endif
//-----Get Pivots---------------------------------------------//
pH=high[3]<high[2] and high[2]>high[1]
pL=low[3]>low[2] and low[2]<low[1]
if pH then
$highprice[z+1]=high[2]
$highidx[z+1]=barindex[2]
z=z+1
endif
if pL then
$lowprice[t+1]=low[2]
$lowidx[t+1]=barindex[2]
t=t+1
endif
//------------------------------------------------------------//
//-----Get Source for RSI calculation-------------------------//
$count[0]=0
if isset($highprice[z]) then
for i=z downto 0 do
if closeTypeBull>$highprice[i] then
$highprice[i]=exp(10)
$count[r+1]=$count[r]+1
r=r+1
else
break
endif
next
endif
if isset($lowprice[t]) then
for j=t downto 0 do
if closeTypeBear<$lowprice[j] then
$lowprice[j]=0
$count[r+1]=$count[r]-1
r=r+1
else
break
endif
next
endif
//------------------------------------------------------------//
//-----Get total array count----------------------------------//
total=0
for k=0 to r do
total=total+$count[r]
next
//------------------------------------------------------------//
//-----RSI total----------------------------------------------//
rsitotal=rsi[rsilength](total)
//------------------------------------------------------------//
//-----RSI Moving Average-------------------------------------//
if maBool then
rsmMATotal=average[maLength,maSelection](rsitotal)
else
rsmMATotal=undefined
endif
//------------------------------------------------------------//
//-----Plot configuration-------------------------------------//
if color then
if rsitotal > 50 then
rc=0
gc=255
else
rc=255
gc=0
endif
colorbetween(rsitotal,50,rc,gc,0,50)
endif
//------------------------------------------------------------//
//-----Draw Signals-------------------------------------------//
if signals then
if rsiTotal crosses under OBlvl then
drawpoint(barindex,OBlvl,2)coloured("red")
elsif rsiTotal crosses over OSlvl then
drawpoint(barindex,OSlvl,2)coloured("green")
endif
endif
//------------------------------------------------------------//
return rsitotal, rsmMATotal coloured("blue")style(line,4), OBlvl as "Overbought Level"style(dottedline2), OSlvl as "Oversold level"style(dottedline2)