0
votes

I want to use an "RSI-Ping-Pong-Indicator" as a prerequisite for a backtest with other conditions. For that, I define a RSI and a RSI-long and -short zone, e.g. rsi(25) = long and rsi(75) = short.

rsiShortLevel = input(75, title="RSI Short Level")
rsiLongLevel = input(25, title="RSI Long Level")

If the RSI falls (crossunder()) below the long zone (rsi < 25), the indicator should switch to "long". The indicator remains "long" until the RSI reaches (crossover()) next time the short zone (rsi > 75), then the indicator switches to "short". The same applies vice versa like a "RSI Ping-Pong". Between a long-crossing and the next short-crossing, the RSI can re-cross the long-level multiple times and can move a long time in this "between-zone", but it will stay "long" until the RSI cross over the short-level.

Then I can plot the crossing-conditions with a pingpong-condition as a blue line. For better visual understanding in Tradingview, the following long-short-conditions displays the value of the long-level (rsiLongLevel = 25) for "long" and the value of the short-level (rsiShortLevel = 75) for a "short":

///RSI Crossings
rsiLongCondition = crossunder(rsi, rsiLongLevel)
rsiShortCondition = crossover(rsi, rsiShortLevel)

///RSI Ping-Pong
pingpong = if(rsiLongCondition)
    rsiLongLevel
else
    if(rsiShortCondition)
        rsiShortLevel

plot(showPingpong ? pingpong : na, color=color.blue, style=plot.style_line, linewidth=2, title='RSI Ping-Pong')

However, it is obvious that the value of 25 or 75 is only output at the actual crossing, but not between the crossings: in between the crossings, the value is na.

Now I want to achieve that the value after the long crossing continues the output value (here: 25 aka "long") until the short zone is crossed and the value changes to 75 (aka "short").

I can display this behavior if I use a trick and bring "strategy.entry" and "strategy.position_size" into play and link them to an iff-condition:

if(rsiLongCondition)
    strategy.entry(id="LE-RSI-Cross", long=true, qty=1)
if(rsiShortCondition)
    strategy.entry(id="SE-RSI-Cross", long=false, qty=1)

pingpongPositionSize = iff(strategy.position_size > 0, rsiLongLevel, iff(strategy.position_size < 0, rsiShortLevel, na))

If I plot the variable pingpongPositionSize (black line) and set background-color-condition (red = short, green = long), the indicator shows the corresponding values and background color correctly:

plot(showPingpongSize ? pingpongPositionSize : na, color=color.black, style=plot.style_line, linewidth=4, title='RSI-Position-Size Ping-Pong')
bgcolor(showBGSize and strategy.position_size > 0 ? color.green : showBGSize and strategy.position_size < 0 ? color.red : na, transp=70)



My question: how can I build my desired indicator so that it behaves the same as with the "strategy.position_size" trick?

Full Script

/@version=4
strategy("RSI Ping-Pong", overlay=false)

// GENERAL SETTINGS

rsiLenght = input(14, title="RSI Lenght")
rsiShortLevel = input(75, title="RSI Short Level")
rsiLongLevel = input(25, title="RSI Long Level")
showBGCrossings = input(false, title="Show RSI-Crossings with bgcolor?")
showPingpong = input(true, title="Show RSI Ping-Pong?")
showPingpongSize = input(true, title="Show RSI-Position-Size Ping-Pong?")
showBGSize = input(true, title="Show RSI Position Size Changes with bgcolor?")


// CALCULATIONS
rsi = rsi(close, rsiLenght)

///RSI Crossings
rsiLongCondition = crossunder(rsi, rsiLongLevel)
rsiShortCondition = crossover(rsi, rsiShortLevel)

///RSI Ping-Pong
pingpong = if(rsiLongCondition)
    rsiLongLevel
else
    if(rsiShortCondition)
        rsiShortLevel

/// RSI Ping-Pong with Strategy Position Size
if(rsiLongCondition)
    strategy.entry(id="LE-RSI-Cross", long=true, qty=1)
if(rsiShortCondition)
    strategy.entry(id="SE-RSI-Cross", long=false, qty=1)

pingpongPositionSize = iff(strategy.position_size > 0, rsiLongLevel, iff(strategy.position_size < 0, rsiShortLevel, na))

// PLOTTING
plot(rsi, color=color.purple, style=plot.style_line, linewidth=2, title='RSI')
plot(showPingpong ? pingpong : na, color=color.blue, style=plot.style_line, linewidth=2, title='RSI Ping-Pong')
bgcolor(showBGCrossings and rsiLongCondition ? color.green : rsiShortCondition ? color.red : na, transp=0)
plot(showPingpongSize ? pingpongPositionSize : na, color=color.black, style=plot.style_line, linewidth=4, title='RSI-Position-Size Ping-Pong')
bgcolor(showBGSize and strategy.position_size > 0  ? color.green : showBGSize and strategy.position_size < 0 ? color.red : na, transp=70)
hlong = hline(rsiLongLevel, title="RSI Long Level")
hshort = hline(rsiShortLevel, title="RSI Short Level")
1

1 Answers

0
votes

Use:

///RSI Ping-Pong
var pingpong = 0.
if(rsiLongCondition)
    pingpong := rsiLongLevel
else
    if(rsiShortCondition)
        pingpong := rsiShortLevel

The var initialization only initializes the variable on the first bar, and its value is only changed upon crosses, so its value is propagated across bars after a change. See the usrman on the subject.

enter image description here