Skip to content

remove unverified BNB profile from production compiler #247

remove unverified BNB profile from production compiler

remove unverified BNB profile from production compiler #247

Triggered via push July 23, 2026 18:09
Status Failure
Total duration 33s
Artifacts

quality.yml

on: push
test-and-build
30s
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/validated-bnb-divergence-profile.test.ts > validated BNBUSDT 30m divergence profile > keeps Indicator and Strategy entry conditions aligned: tests/validated-bnb-divergence-profile.test.ts#L47
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'regularBullishDivergence = pivotLowFo…' - Expected + Received - regularBullishDivergence = pivotLowFound and rsiHigherLow and priceLowerLow + //@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=false, max_labels_count=500, max_lines_count=500) + + // === Inputs === + confirmedOnly = input.bool(true, "Confirmed candles only") + cooldownBars = input.int(0, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("30", "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(9, "Fast EMA", minval=1) + emaSlowLen = input.int(45, "Slow EMA", minval=1) + longMaLen = input.int(100, "Long MA", minval=1) + rsiLen = input.int(14, "RSI length", minval=2) + rsiLongLevel = input.float(55, "RSI long threshold") + rsiShortLevel = input.float(45, "RSI short threshold") + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(0.8, "Volume multiplier", minval=0.1, step=0.05) + swingLen = input.int(15, "Swing stop lookback", minval=2) + riskReward = input.float(1.8, "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) + volumeAverage = ta.sma(volume, volumeLen) + + // Entry divergence is shared with the integrated RSI pane below. + + // === Integrated RSI divergence pane === + // Divergence reuses the main RSI period and source. + divPivotLeft = input.int(5, "Divergence pivot left", minval=1) + divPivotRight = input.int(5, "Divergence pivot right", minval=1) + divRangeMinimum = input.int(5, "Divergence minimum pivot range", minval=1) + divRangeMaximum = input.int(60, "Divergence maximum pivot range", minval=2) + showRegularBullDiv = input.bool(true, "Show regular bullish divergence") + showHiddenBullDiv = input.bool(false, "Show hidden bullish divergence") + showRegularBearDiv = input.bool(true, "Show regular bearish divergence") + showHiddenBearDiv = input.bool(false, "Show hidden bearish divergence") + + divRsi = rsiValue + divRegularBullColor = color.green + divRegularBearColor = color.red + divHiddenBullColor = color.new(color.green, 35) + divHiddenBearColor = color.new(color.red, 35) + divTransparentColor = color.new(color.white, 100) + + plot(divRsi, "RSI divergence", linewidth=2, color=color.rgb(41, 98, 255)) + divMiddleLine = hline(50, "RSI middle", color=color.rgb(120, 123, 134), linestyle=hline.style_dotted) + divOverboughtLine = hline(70, "RSI overbought", color=color.rgb(120, 123, 134), linestyle=hline.style_dotted) + divOversoldLine = hline(30, "RSI oversold", color=color.rgb(120, 123, 134), linestyle=hline.style_dotted) + fill(divOverboughtLine, divOversoldLine, color=color.rgb(33, 150, 243, 90), title="RSI divergence background") + + divPivotLowFound = not na(ta.pivotlow(divRsi, divPivotLeft, divPivotRight)) + divPivotHighFound = not na(ta.pivothigh(divRsi, divPivotLeft, divPivotRight)) + + divInRange(condition) => + divBarsSince = ta.barssince(condition) + divRangeMinimum <= divBarsSince and divBarsSince <= divRangeMaximum + + divPreviousLowInRange = divInRange(divPivotLowFound[1]) + divRsiHigherLow = divRsi[divPivotRight] > ta.valuewhen(divPivotLowFound, divRsi[divPivotRight], 1) and divPreviousLowInRange + divPriceLowerLow = low[divPivotRight] < ta.valuewhen(divPivotLowFound, low[divPivotRight], 1) + divRegularBullAlert = divPriceLowerLow and divRsiHigherLow and divPivotLowFound + divRegularBull = showRegularBullDiv and divRegularBullAlert + pl
tests/validated-bnb-divergence-profile.test.ts > validated BNBUSDT 30m divergence profile > generates the same confirmed signal and frozen-risk rules in Strategy mode: tests/validated-bnb-divergence-profile.test.ts#L21
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'expectedTicker = "BNBUSDT"' - Expected + Received - expectedTicker = "BNBUSDT" + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("RSI Divergence Reversal", overlay=true, pyramiding=0, process_orders_on_close=true, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.1) + + // === Inputs === + confirmedOnly = input.bool(true, "Confirmed candles only") + cooldownBars = input.int(0, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("30", "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(9, "Fast EMA", minval=1) + emaSlowLen = input.int(45, "Slow EMA", minval=1) + longMaLen = input.int(100, "Long MA", minval=1) + rsiLen = input.int(14, "RSI length", minval=2) + rsiLongLevel = input.float(55, "RSI long threshold") + rsiShortLevel = input.float(45, "RSI short threshold") + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(0.8, "Volume multiplier", minval=0.1, step=0.05) + swingLen = input.int(15, "Swing stop lookback", minval=2) + riskReward = input.float(1.8, "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) + volumeAverage = ta.sma(volume, volumeLen) + + // Confirmed regular RSI divergence shared with Indicator mode. + divPivotLeft = input.int(5, "Divergence pivot left", minval=1) + divPivotRight = input.int(5, "Divergence pivot right", minval=1) + divRangeMinimum = input.int(5, "Divergence minimum pivot range", minval=1) + divRangeMaximum = input.int(60, "Divergence maximum pivot range", minval=2) + divPivotLowFound = not na(ta.pivotlow(rsiValue, divPivotLeft, divPivotRight)) + divPivotHighFound = not na(ta.pivothigh(rsiValue, divPivotLeft, divPivotRight)) + divInRange(condition) => + divBarsSince = ta.barssince(condition) + divRangeMinimum <= divBarsSince and divBarsSince <= divRangeMaximum + divPreviousLowInRange = divInRange(divPivotLowFound[1]) + divRsiHigherLow = rsiValue[divPivotRight] > ta.valuewhen(divPivotLowFound, rsiValue[divPivotRight], 1) and divPreviousLowInRange + divPriceLowerLow = low[divPivotRight] < ta.valuewhen(divPivotLowFound, low[divPivotRight], 1) + bullishDivergence = divPriceLowerLow and divRsiHigherLow and divPivotLowFound + divPreviousHighInRange = divInRange(divPivotHighFound[1]) + divRsiLowerHigh = rsiValue[divPivotRight] < ta.valuewhen(divPivotHighFound, rsiValue[divPivotRight], 1) and divPreviousHighInRange + divPriceHigherHigh = high[divPivotRight] > ta.valuewhen(divPivotHighFound, high[divPivotRight], 1) + bearishDivergence = divPriceHigherHigh and divRsiLowerHigh and divPivotHighFound + + // === 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 = emaFast > emaSlow and bullishDivergence and volume >= volumeAverage * volumeMultiplier and confirmationOk + shortSetup = emaFast < emaSlow and bearishDivergence and volume >= volumeAverage * volumeMultiplier and confirmationOk + longTrigger = true + shortTrigger = true + var int lastSignalBar = na + cooldownOk = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars + longSignal = chartTi
tests/compiler.test.ts > preset behavior fixtures > RSI Divergence Reversal satisfies validation, Pine and explanation contracts: tests/compiler.test.ts#L26
AssertionError: [ { "level": "error", "code": "profile.market_missing", "message": "Validated profile is missing required rule: expectedTicker = \"BNBUSDT\"" }, { "level": "error", "code": "profile.timeframe_missing", "message": "Validated profile is missing required rule: expectedTimeframe = \"30\"" }, { "level": "error", "code": "profile.bullish_divergence_missing", "message": "Validated profile is missing required rule: regularBullishDivergence =" }, { "level": "error", "code": "profile.bearish_divergence_missing", "message": "Validated profile is missing required rule: regularBearishDivergence =" }, { "level": "error", "code": "profile.long_confirmation_missing", "message": "Validated profile is missing required rule: ta.crossover(ema9, wma45)" }, { "level": "error", "code": "profile.short_confirmation_missing", "message": "Validated profile is missing required rule: ta.crossunder(ema9, wma45)" }, { "level": "error", "code": "profile.long_trend_missing", "message": "Validated profile is missing required rule: longTrendOk = ema50 > ema200 and close > ema200" }, { "level": "error", "code": "profile.short_trend_missing", "message": "Validated profile is missing required rule: shortTrendOk = ema50 < ema200 and close < ema200" }, { "level": "error", "code": "profile.long_stop_missing", "message": "Validated profile is missing required rule: activeStop := ta.lowest(low, swingLength)" }, { "level": "error", "code": "profile.short_stop_missing", "message": "Validated profile is missing required rule: activeStop := ta.highest(high, swingLength)" }, { "level": "error", "code": "profile.long_target_missing", "message": "Validated profile is missing required rule: activeTarget := close + (close - activeStop) * riskReward" }, { "level": "error", "code": "profile.short_target_missing", "message": "Validated profile is missing required rule: activeTarget := close - (activeStop - close) * riskReward" }, { "level": "error", "code": "indicator.risk_stop_missing", "message": "Validated indicator requires the frozen swing stop plot." }, { "level": "error", "code": "indicator.risk_target_missing", "message": "Validated indicator requires the 1.8R target plot." } ]: expected [ { level: 'error', …(2) }, …(13) ] to deeply equal [] - Expected + Received - [] + [ + { + "code": "profile.market_missing", + "level": "error", + "message": "Validated profile is missing required rule: expectedTicker = \"BNBUSDT\"", + }, + { + "code": "profile.timeframe_missing", + "level": "error", + "message": "Validated profile is missing required rule: expectedTimeframe = \"30\"", + }, + { + "code": "profile.bullish_divergence_missing", + "level": "error", + "message": "Validated profile is missing required rule: regularBullishDivergence =", + }, + { + "code": "profile.bearish_divergence_missing", + "level": "error", + "message": "Validated profile is missing required rule: regularBearishDivergence =", + }, + { + "code": "profile.long_confirmation_missing", + "level": "error", + "message": "Validated profile is missing required rule: ta.crossover(ema9, wma45)", + }, + { + "code": "profile.short_confirmation_missing", + "level": "error", + "message": "Validated profile is missing required rule: ta.crossunder(ema9, wma45)", + }, + { + "code": "profile.long_trend_missing", + "level": "error", + "message": "Validated profile is missing required rule: longTrendOk = ema50 > ema200 and close > ema200", + }, + { + "code": "profile.short_trend_missing", + "level": "error", + "message": "Validated profile is missing required rule: shortTrendOk = ema50 < ema200 and close < ema200", + }, + { + "code": "profile.long_stop_missing", + "level": "error", + "message": "Validated profile is missing required rule: ac
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/