Skip to content

test RSI pane stability after script rename #292

test RSI pane stability after script rename

test RSI pane stability after script rename #292

Triggered via push July 23, 2026 19:50
Status Failure
Total duration 28s
Artifacts

quality.yml

on: push
test-and-build
25s
test-and-build
Fit to window
Zoom out
Zoom in

Annotations

4 errors and 1 warning
test-and-build
Process completed with exit code 1.
tests/strategy-divergence-alignment.test.ts > Strategy divergence alignment > keeps the integrated pane on the generic indicator compiler path: tests/strategy-divergence-alignment.test.ts#L37
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain '// === Integrated RSI divergence pane…' - Expected + Received - // === Integrated RSI divergence pane === + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + indicator("RSI Divergence Reversal", overlay=true, max_labels_count=500, max_lines_count=500) + + // === Inputs === + confirmedOnly = input.bool(true, "Confirmed candles only") + cooldownBars = input.int(5, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("15", "Expected chart timeframe") + enforceChartTimeframe = input.bool(true, "Block signals on a different chart timeframe") + visualProfile = "Clean" // Selected in PineForge Studio + colorSignalBars = input.bool(false, "Color bars by current setup") + showTrendRibbon = input.bool(false, "Show trend ribbon") + showRiskOutcomeLabels = input.bool(true, "Show stop/target outcome labels") + emaFastLen = input.int(20, "Fast EMA", minval=1) + emaSlowLen = input.int(50, "Slow EMA", minval=1) + longMaLen = input.int(100, "Long MA", minval=1) + rsiLen = input.int(14, "RSI length", minval=2) + rsiLongLevel = input.float(40, "RSI long threshold") + rsiShortLevel = input.float(60, "RSI short threshold") + atrLen = input.int(14, "ATR length", minval=1) + atrMultiple = input.float(2, "ATR stop multiple", minval=0.1) + riskReward = input.float(2, "Risk/reward", minval=0.1) + + // === Core calculations === + emaFast = ta.ema(close, emaFastLen) + emaSlow = ta.ema(close, emaSlowLen) + longMa = ta.sma(close, longMaLen) + rsiValue = ta.rsi(close, rsiLen) + atrValue = ta.atr(atrLen) + + // Confirmed pivot-based RSI divergence. Pivots appear after right-side bars complete. + pricePivotLow = ta.pivotlow(low, 5, 5) + pricePivotHigh = ta.pivothigh(high, 5, 5) + rsiPivotLow = ta.pivotlow(rsiValue, 5, 5) + rsiPivotHigh = ta.pivothigh(rsiValue, 5, 5) + prevPriceLow = ta.valuewhen(not na(pricePivotLow), pricePivotLow, 1) + prevRsiLow = ta.valuewhen(not na(rsiPivotLow), rsiPivotLow, 1) + prevPriceHigh = ta.valuewhen(not na(pricePivotHigh), pricePivotHigh, 1) + prevRsiHigh = ta.valuewhen(not na(rsiPivotHigh), rsiPivotHigh, 1) + bullishDivergence = not na(pricePivotLow) and not na(rsiPivotLow) and pricePivotLow < prevPriceLow and rsiPivotLow > prevRsiLow + bearishDivergence = not na(pricePivotHigh) and not na(rsiPivotHigh) and pricePivotHigh > prevPriceHigh and rsiPivotHigh < prevRsiHigh + + // === Filters and triggers === + confirmationOk = not confirmedOnly or barstate.isconfirmed + chartTimeframeAliasOk = (timeframe.period == "1D" and expectedChartTimeframe == "D") or (timeframe.period == "D" and expectedChartTimeframe == "1D") + chartTimeframeOk = timeframe.period == expectedChartTimeframe or chartTimeframeAliasOk + chartTimeframeAllowed = not enforceChartTimeframe or chartTimeframeOk + longSetup = rsiValue >= rsiLongLevel and bullishDivergence and confirmationOk + shortSetup = rsiValue <= rsiShortLevel and bearishDivergence and confirmationOk + longTrigger = true + shortTrigger = true + var int lastSignalBar = na + cooldownOk = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars + longSignal = chartTimeframeAllowed and longSetup and longTrigger and cooldownOk + shortSignal = chartTimeframeAllowed and shortSetup and shortTrigger and cooldownOk + if longSignal or shortSignal + lastSignalBar := bar_index + + // === Visuals === + barcolor(colorSignalBars and visualProfile != "Clean" ? longSetup ? (visualProfile == "Advanced" ? color.new(color.rgb(0, 165, 90), 15) : color.new(color.lime, 60)) : shortSetup ? (visualProfile == "Advanced" ? color.new(color.rgb(220, 50, 60), 15) : color.new(color.red, 60)) : na : na, title="Setup bar color") + bgcolor(showTrendRibbon and visualProfile != "Clean" ? (longSetup ? color.new(color.lime, 95) : shortSetup ? color.new(color.red, 95) : na) : na, title="Trend ribbon") + plot(emaFast, "Fast EMA", color=color.aqua) + plot(emaSlow, "Slow EMA", color=color.orange) + plot(longMa, "Long MA",
tests/rsi-divergence-risk-consistency.test.ts > RSI Divergence Reversal consistency > reuses the main RSI calculation for divergence in the generic compiler: tests/rsi-divergence-risk-consistency.test.ts#L12
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'divRsi = rsiValue' - Expected + Received - divRsi = rsiValue + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + indicator("RSI Divergence Reversal", overlay=true, max_labels_count=500, max_lines_count=500) + + // === Inputs === + confirmedOnly = input.bool(true, "Confirmed candles only") + cooldownBars = input.int(5, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("15", "Expected chart timeframe") + enforceChartTimeframe = input.bool(true, "Block signals on a different chart timeframe") + visualProfile = "Clean" // Selected in PineForge Studio + colorSignalBars = input.bool(false, "Color bars by current setup") + showTrendRibbon = input.bool(false, "Show trend ribbon") + showRiskOutcomeLabels = input.bool(true, "Show stop/target outcome labels") + emaFastLen = input.int(20, "Fast EMA", minval=1) + emaSlowLen = input.int(50, "Slow EMA", minval=1) + longMaLen = input.int(100, "Long MA", minval=1) + rsiLen = input.int(14, "RSI length", minval=2) + rsiLongLevel = input.float(40, "RSI long threshold") + rsiShortLevel = input.float(60, "RSI short threshold") + atrLen = input.int(14, "ATR length", minval=1) + atrMultiple = input.float(2, "ATR stop multiple", minval=0.1) + riskReward = input.float(2, "Risk/reward", minval=0.1) + + // === Core calculations === + emaFast = ta.ema(close, emaFastLen) + emaSlow = ta.ema(close, emaSlowLen) + longMa = ta.sma(close, longMaLen) + rsiValue = ta.rsi(close, rsiLen) + atrValue = ta.atr(atrLen) + + // Confirmed pivot-based RSI divergence. Pivots appear after right-side bars complete. + pricePivotLow = ta.pivotlow(low, 5, 5) + pricePivotHigh = ta.pivothigh(high, 5, 5) + rsiPivotLow = ta.pivotlow(rsiValue, 5, 5) + rsiPivotHigh = ta.pivothigh(rsiValue, 5, 5) + prevPriceLow = ta.valuewhen(not na(pricePivotLow), pricePivotLow, 1) + prevRsiLow = ta.valuewhen(not na(rsiPivotLow), rsiPivotLow, 1) + prevPriceHigh = ta.valuewhen(not na(pricePivotHigh), pricePivotHigh, 1) + prevRsiHigh = ta.valuewhen(not na(rsiPivotHigh), rsiPivotHigh, 1) + bullishDivergence = not na(pricePivotLow) and not na(rsiPivotLow) and pricePivotLow < prevPriceLow and rsiPivotLow > prevRsiLow + bearishDivergence = not na(pricePivotHigh) and not na(rsiPivotHigh) and pricePivotHigh > prevPriceHigh and rsiPivotHigh < prevRsiHigh + + // === Filters and triggers === + confirmationOk = not confirmedOnly or barstate.isconfirmed + chartTimeframeAliasOk = (timeframe.period == "1D" and expectedChartTimeframe == "D") or (timeframe.period == "D" and expectedChartTimeframe == "1D") + chartTimeframeOk = timeframe.period == expectedChartTimeframe or chartTimeframeAliasOk + chartTimeframeAllowed = not enforceChartTimeframe or chartTimeframeOk + longSetup = rsiValue >= rsiLongLevel and bullishDivergence and confirmationOk + shortSetup = rsiValue <= rsiShortLevel and bearishDivergence and confirmationOk + longTrigger = true + shortTrigger = true + var int lastSignalBar = na + cooldownOk = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars + longSignal = chartTimeframeAllowed and longSetup and longTrigger and cooldownOk + shortSignal = chartTimeframeAllowed and shortSetup and shortTrigger and cooldownOk + if longSignal or shortSignal + lastSignalBar := bar_index + + // === Visuals === + barcolor(colorSignalBars and visualProfile != "Clean" ? longSetup ? (visualProfile == "Advanced" ? color.new(color.rgb(0, 165, 90), 15) : color.new(color.lime, 60)) : shortSetup ? (visualProfile == "Advanced" ? color.new(color.rgb(220, 50, 60), 15) : color.new(color.red, 60)) : na : na, title="Setup bar color") + bgcolor(showTrendRibbon and visualProfile != "Clean" ? (longSetup ? color.new(color.lime, 95) : shortSetup ? color.new(color.red, 95) : na) : na, title="Trend ribbon") + plot(emaFast, "Fast EMA", color=color.aqua) + plot(emaSlow, "Slow EMA", color=color.orange) + plot(longMa, "Long MA", color=color.yellow, linewidth=2) + var float ri
tests/rsi-divergence-entry-alignment.test.ts > RSI divergence entry alignment > uses the same regular divergence events for pane labels and entries in the generic compiler: tests/rsi-divergence-entry-alignment.test.ts#L12
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'bullishDivergence = divRegularBullAle…' - Expected + Received - bullishDivergence = divRegularBullAlert + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + indicator("RSI Divergence Reversal", overlay=true, max_labels_count=500, max_lines_count=500) + + // === Inputs === + confirmedOnly = input.bool(true, "Confirmed candles only") + cooldownBars = input.int(5, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("15", "Expected chart timeframe") + enforceChartTimeframe = input.bool(true, "Block signals on a different chart timeframe") + visualProfile = "Clean" // Selected in PineForge Studio + colorSignalBars = input.bool(false, "Color bars by current setup") + showTrendRibbon = input.bool(false, "Show trend ribbon") + showRiskOutcomeLabels = input.bool(true, "Show stop/target outcome labels") + emaFastLen = input.int(20, "Fast EMA", minval=1) + emaSlowLen = input.int(50, "Slow EMA", minval=1) + longMaLen = input.int(100, "Long MA", minval=1) + rsiLen = input.int(14, "RSI length", minval=2) + rsiLongLevel = input.float(40, "RSI long threshold") + rsiShortLevel = input.float(60, "RSI short threshold") + atrLen = input.int(14, "ATR length", minval=1) + atrMultiple = input.float(2, "ATR stop multiple", minval=0.1) + riskReward = input.float(2, "Risk/reward", minval=0.1) + + // === Core calculations === + emaFast = ta.ema(close, emaFastLen) + emaSlow = ta.ema(close, emaSlowLen) + longMa = ta.sma(close, longMaLen) + rsiValue = ta.rsi(close, rsiLen) + atrValue = ta.atr(atrLen) + + // Confirmed pivot-based RSI divergence. Pivots appear after right-side bars complete. + pricePivotLow = ta.pivotlow(low, 5, 5) + pricePivotHigh = ta.pivothigh(high, 5, 5) + rsiPivotLow = ta.pivotlow(rsiValue, 5, 5) + rsiPivotHigh = ta.pivothigh(rsiValue, 5, 5) + prevPriceLow = ta.valuewhen(not na(pricePivotLow), pricePivotLow, 1) + prevRsiLow = ta.valuewhen(not na(rsiPivotLow), rsiPivotLow, 1) + prevPriceHigh = ta.valuewhen(not na(pricePivotHigh), pricePivotHigh, 1) + prevRsiHigh = ta.valuewhen(not na(rsiPivotHigh), rsiPivotHigh, 1) + bullishDivergence = not na(pricePivotLow) and not na(rsiPivotLow) and pricePivotLow < prevPriceLow and rsiPivotLow > prevRsiLow + bearishDivergence = not na(pricePivotHigh) and not na(rsiPivotHigh) and pricePivotHigh > prevPriceHigh and rsiPivotHigh < prevRsiHigh + + // === Filters and triggers === + confirmationOk = not confirmedOnly or barstate.isconfirmed + chartTimeframeAliasOk = (timeframe.period == "1D" and expectedChartTimeframe == "D") or (timeframe.period == "D" and expectedChartTimeframe == "1D") + chartTimeframeOk = timeframe.period == expectedChartTimeframe or chartTimeframeAliasOk + chartTimeframeAllowed = not enforceChartTimeframe or chartTimeframeOk + longSetup = rsiValue >= rsiLongLevel and bullishDivergence and confirmationOk + shortSetup = rsiValue <= rsiShortLevel and bearishDivergence and confirmationOk + longTrigger = true + shortTrigger = true + var int lastSignalBar = na + cooldownOk = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars + longSignal = chartTimeframeAllowed and longSetup and longTrigger and cooldownOk + shortSignal = chartTimeframeAllowed and shortSetup and shortTrigger and cooldownOk + if longSignal or shortSignal + lastSignalBar := bar_index + + // === Visuals === + barcolor(colorSignalBars and visualProfile != "Clean" ? longSetup ? (visualProfile == "Advanced" ? color.new(color.rgb(0, 165, 90), 15) : color.new(color.lime, 60)) : shortSetup ? (visualProfile == "Advanced" ? color.new(color.rgb(220, 50, 60), 15) : color.new(color.red, 60)) : na : na, title="Setup bar color") + bgcolor(showTrendRibbon and visualProfile != "Clean" ? (longSetup ? color.new(color.lime, 95) : shortSetup ? color.new(color.red, 95) : na) : na, title="Trend ribbon") + plot(emaFast, "Fast EMA", color=color.aqua) + plot(emaSlow, "Slow EMA", color=color.orange) + plot(longMa, "Long MA", co
test-and-build
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v4, actions/setup-node@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/