Keep fixture mode on and length at 3 to reproduce the tables. The script feeds the first 12 loaded chart bars with the synthetic OHLC matrix and shows their results in a persistent table. After those bars its fixture inputs are na, so the current plot is intentionally empty. The table requires at least 12 completed chart bars. Disable fixture mode for chart OHLC. The pane selector avoids overlaying RVI and RSI on one scale; both remain in the Data Window.
Original comparison indicator with explicit seeding and invalid-data rules. It displays confirmed bars and submits no orders.pine
//@version=6
indicator("Relative Vigor Index vs RSI: same bars", overlay = false, max_bars_back = 500)
fixture = input.bool(true, "Use 12-bar calculation fixture")
length = input.int(3, "Shared length", minval = 1, maxval = 200)
pane = input.string("RVI", "Pane scale", options = ["RVI", "RSI"])
var opens = array.from(100.0, 104.0, 106.0, 108.0, 110.0, 112.0, 104.0, 102.0, 100.0, 98.0, 96.0, 94.0)
var highs = array.from(102.0, 105.0, 107.0, 110.0, 111.0, 113.0, 107.0, 104.0, 102.0, 100.0, 98.0, 96.0)
var lows = array.from(99.0, 102.0, 104.0, 106.0, 108.0, 110.0, 103.0, 101.0, 99.0, 97.0, 95.0, 93.0)
var closes = array.from(101.0, 103.0, 105.0, 107.0, 109.0, 111.0, 105.0, 103.0, 101.0, 99.0, 97.0, 95.0)
weighted4(float x) =>
(x + 2 * x[1] + 2 * x[2] + x[3]) / 6
strictSum(float x, int n) =>
float total = 0.0
for i = 0 to n - 1
total += x[i]
total
// Each call has its own state. Seed with N consecutive changes.
wilder(float x, int n) =>
var float value = na
var float seed = 0.0
var int count = 0
if na(x)
value := na
seed := 0.0
count := 0
else if na(value)
seed += x
count += 1
if count == n
value := seed / n
else
value := ((n - 1) * value + x) / n
value
// Fixture occupies the first 12 loaded chart bars; later input is na.
int k = bar_index
float o = fixture ? (k < 12 ? array.get(opens, k) : na) : open
float h = fixture ? (k < 12 ? array.get(highs, k) : na) : high
float l = fixture ? (k < 12 ? array.get(lows, k) : na) : low
float c = fixture ? (k < 12 ? array.get(closes, k) : na) : close
valid = not na(o) and not na(h) and not na(l) and not na(c) and h >= math.max(o, c) and l <= math.min(o, c)
body = valid ? c - o : na
span = valid ? h - l : na
sourceClose = valid ? c : na
numerator = weighted4(body)
denominator = weighted4(span)
numSum = strictSum(numerator, length)
denSum = strictSum(denominator, length)
rvi = not na(denSum) and denSum > 0 ? numSum / denSum : na
signal = weighted4(rvi)
change = sourceClose - sourceClose[1]
gain = na(change) ? na : math.max(change, 0)
loss = na(change) ? na : math.max(-change, 0)
avgGain = wilder(gain, length)
avgLoss = wilder(loss, length)
// Both averages zero is undefined by this example's explicit policy.
rsi = not na(avgGain) and not na(avgLoss) and avgGain + avgLoss > 0 ? 100 * avgGain / (avgGain + avgLoss) : na
confirmed = barstate.isconfirmed
paired = not na(rvi) and not na(rsi)
plot(confirmed and pane == "RVI" ? rvi : na, "RVI pane", color.blue)
plot(confirmed and pane == "RVI" ? signal : na, "RVI signal pane", color.orange)
plot(confirmed and pane == "RSI" ? rsi : na, "RSI pane", color.blue)
plot(confirmed ? rvi : na, "RVI", display = display.data_window)
plot(confirmed ? signal : na, "Signal", display = display.data_window)
plot(confirmed ? rsi : na, "RSI", display = display.data_window)
plot(confirmed ? numerator : na, "Weighted body", display = display.data_window)
plot(confirmed ? denominator : na, "Weighted range", display = display.data_window)
plot(confirmed ? avgGain : na, "Wilder average gain", display = display.data_window)
plot(confirmed ? avgLoss : na, "Wilder average loss", display = display.data_window)
plot(confirmed and paired ? (rvi > 0 ? 1 : 0) : na, "RVI above zero", display = display.data_window)
plot(confirmed and paired ? (rsi > 50 ? 1 : 0) : na, "RSI above 50", display = display.data_window)
// Persist fixture values in a table so scrolling to the first bars is optional.
var report = table.new(position.top_right, 4, 13, bgcolor = color.white, border_width = 1)
if fixture and barstate.isfirst
table.cell(report, 0, 0, "Bar", text_color = color.black)
table.cell(report, 1, 0, "RVI", text_color = color.black)
table.cell(report, 2, 0, "Signal", text_color = color.black)
table.cell(report, 3, 0, "RSI", text_color = color.black)
if fixture and k < 12 and confirmed
table.cell(report, 0, k + 1, str.tostring(k), text_color = color.black)
table.cell(report, 1, k + 1, str.tostring(rvi, "#.######"), text_color = color.black)
table.cell(report, 2, k + 1, str.tostring(signal, "#.######"), text_color = color.black)
table.cell(report, 3, k + 1, str.tostring(rsi, "#.######"), text_color = color.black)