Skip to content

revert strategy equity sizing regression #213

revert strategy equity sizing regression

revert strategy equity sizing regression #213

Triggered via push July 23, 2026 16:54
Status Failure
Total duration 31s
Artifacts

quality.yml

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

Annotations

10 errors and 1 warning
tests/strategy-execution-hardening.test.ts > strategy execution hardening > Long-Term Trend Guard uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("Long-Term Trend Guard", 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(5, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("D", "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(50, "Fast EMA", minval=1) + emaSlowLen = input.int(100, "Slow EMA", minval=1) + longMaLen = input.int(200, "Long MA", minval=1) + rsiLen = input.int(14, "RSI length", minval=2) + rsiLongLevel = input.float(50, "RSI long threshold") + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(1, "Volume multiplier", minval=0.1, step=0.05) + htf = input.timeframe("W", "Higher timeframe") + atrLen = input.int(14, "ATR length", minval=1) + atrMultiple = input.float(3, "ATR stop multiple", minval=0.1) + riskReward = input.float(4, "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) + atrValue = ta.atr(atrLen) + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.sma(close, 40)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 close > longMa and rsiValue >= rsiLongLevel and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + longTrigger = ta.crossover(emaFast, emaSlow) + var int lastSignalBar = na + cooldownOk = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars + longSignal = chartTimeframeAllowed and longSetup and longTrigger and cooldownOk + if longSignal + 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)) : na : na, title="Setup bar color") + bgcolor(showTrendRibbon and visualProfile != "Clean" ? (htfBull ? color.new(color.lime, 95) : color.new(color.red, 95)) : 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) + if longSignal + label.new(bar_index, low, "LONG\n" + str.tostring(close, format.mintick), style=label.style_label_up, color=color.lime, textcolor=color.black, size=size.normal) + bgcolor(showTrendRibbon and visualProfile != "Clean" ? (htfBull ? color.new(color.green, 99) : color.new(color.red, 99)) : na, title="HTF bias") + var table dashboard = table.new(position.top_right, 2, 5, border_width=1) + if barstate.islast + table.cell(dashboard, 0, 0, "PineForge", bgcolor=color.new(color.blue, 70), text_color=color.white, text_
tests/strategy-execution-hardening.test.ts > strategy execution hardening > Selective Multi-Timeframe uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("Selective Multi-Timeframe", 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(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(55, "RSI long threshold") + rsiShortLevel = input.float(45, "RSI short threshold") + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(1.2, "Volume multiplier", minval=0.1, step=0.05) + adxLen = input.int(14, "ADX length", minval=2) + adxThreshold = input.float(20, "ADX threshold") + htf = input.timeframe("240", "Higher timeframe") + 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) + vwapValue = ta.vwap(hlc3) + rsiValue = ta.rsi(close, rsiLen) + [macdLine, macdSignal, macdHist] = ta.macd(close, 12, 26, 9) + [plusDI, minusDI, adxValue] = ta.dmi(adxLen, adxLen) + volumeAverage = ta.sma(volume, volumeLen) + atrValue = ta.atr(atrLen) + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.ema(close, 100)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 close > longMa and close > vwapValue and rsiValue >= rsiLongLevel and macdLine > macdSignal and macdHist > 0 and adxValue >= adxThreshold and plusDI > minusDI and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + shortSetup = emaFast < emaSlow and close < longMa and close < vwapValue and rsiValue <= rsiShortLevel and macdLine < macdSignal and macdHist < 0 and adxValue >= adxThreshold and minusDI > plusDI and volume >= volumeAverage * volumeMultiplier and htfBear and confirmationOk + longTrigger = ta.crossover(close, emaFast) + shortTrigger = ta.crossunder(close, emaFast) + 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 =
tests/strategy-execution-hardening.test.ts > strategy execution hardening > RSI Divergence Reversal uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@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(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 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 = 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 + las
tests/strategy-execution-hardening.test.ts > strategy execution hardening > Breakout Momentum uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("Breakout Momentum", 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(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(55, "RSI long threshold") + rsiShortLevel = input.float(45, "RSI short threshold") + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(1.5, "Volume multiplier", minval=0.1, step=0.05) + adxLen = input.int(14, "ADX length", minval=2) + adxThreshold = input.float(20, "ADX threshold") + breakoutLen = input.int(20, "Breakout lookback", minval=2) + htf = input.timeframe("240", "Higher timeframe") + 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) + [macdLine, macdSignal, macdHist] = ta.macd(close, 12, 26, 9) + [plusDI, minusDI, adxValue] = ta.dmi(adxLen, adxLen) + volumeAverage = ta.sma(volume, volumeLen) + atrValue = ta.atr(atrLen) + previousHigh = ta.highest(high, breakoutLen)[1] + previousLow = ta.lowest(low, breakoutLen)[1] + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.ema(close, 100)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 close > longMa and rsiValue >= rsiLongLevel and macdLine > macdSignal and macdHist > 0 and adxValue >= adxThreshold and plusDI > minusDI and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + shortSetup = emaFast < emaSlow and close < longMa and rsiValue <= rsiShortLevel and macdLine < macdSignal and macdHist < 0 and adxValue >= adxThreshold and minusDI > plusDI and volume >= volumeAverage * volumeMultiplier and htfBear and confirmationOk + longTrigger = ta.crossover(close, previousHigh) + shortTrigger = ta.crossunder(close, previousLow) + 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(
tests/strategy-execution-hardening.test.ts > strategy execution hardening > Supertrend Volume uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("Supertrend Volume", 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(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) + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(1.25, "Volume multiplier", minval=0.1, step=0.05) + stAtrLen = input.int(10, "Supertrend ATR length", minval=1) + stFactor = input.float(3, "Supertrend factor", minval=0.1) + htf = input.timeframe("240", "Higher timeframe") + 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) + [supertrendValue, supertrendDirection] = ta.supertrend(stFactor, stAtrLen) + volumeAverage = ta.sma(volume, volumeLen) + atrValue = ta.atr(atrLen) + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.ema(close, 100)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 = close > longMa and supertrendDirection < 0 and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + shortSetup = close < longMa and supertrendDirection > 0 and volume >= volumeAverage * volumeMultiplier and htfBear and confirmationOk + longTrigger = ta.change(supertrendDirection) < 0 + shortTrigger = ta.change(supertrendDirection) > 0 + 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" ? (htfBull ? color.new(color.lime, 95) : color.new(color.red, 95)) : 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) + plot(supertrendValue, "Supertrend", color=supertrendDirection < 0 ? color.lime : color.red,
tests/strategy-execution-hardening.test.ts > strategy execution hardening > Spot Accumulation uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("Spot Accumulation", 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(5, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("D", "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(50, "Fast EMA", minval=1) + emaSlowLen = input.int(100, "Slow EMA", minval=1) + longMaLen = input.int(200, "Long MA", minval=1) + rsiLen = input.int(14, "RSI length", minval=2) + rsiLongLevel = input.float(45, "RSI long threshold") + rsiExitLevel = input.float(65, "RSI spot exit threshold") + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(1, "Volume multiplier", minval=0.1, step=0.05) + htf = input.timeframe("W", "Higher timeframe") + + // === 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) + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.ema(close, 50)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 close > longMa and rsiValue >= rsiLongLevel and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + longTrigger = ta.crossover(close, emaFast) + var int lastSignalBar = na + cooldownOk = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars + buySetup = longSetup + var bool spotActive = false + buySignal = chartTimeframeAllowed and buySetup and longTrigger and cooldownOk and not spotActive + rawExitSignal = confirmationOk and (ta.crossunder(close, longMa) or ta.crossunder(emaFast, emaSlow) or ta.crossunder(rsiValue, rsiExitLevel) or htfBear and not htfBear[1]) + exitSignal = rawExitSignal and spotActive + if buySignal + spotActive := true + lastSignalBar := bar_index + if exitSignal + spotActive := false + + // === Visuals === + barcolor(colorSignalBars and visualProfile != "Clean" ? buySetup ? (visualProfile == "Advanced" ? color.new(color.rgb(0, 165, 90), 15) : color.new(color.lime, 60)) : na : na, title="Setup bar color") + bgcolor(showTrendRibbon and visualProfile != "Clean" ? (htfBull ? color.new(color.lime, 95) : color.new(color.red, 95)) : 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) + plotshape(buySignal, title="Spot buy", style=shape.labelup, location=location.belowbar, color=color.lime, text="BUY", textcolor=color.black, size=size.tiny) + plotshape(exitSignal, title="Spot exit", style=shape.labeldown, location=location.abovebar, color=color.orange, text="EXIT", textcolor=color.black, size=size.tiny) + bg
tests/strategy-execution-hardening.test.ts > strategy execution hardening > 4H Swing Trend uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("4H Swing Trend", 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(5, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("240", "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(50, "Fast EMA", minval=1) + emaSlowLen = input.int(100, "Slow EMA", minval=1) + longMaLen = input.int(200, "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(1, "Volume multiplier", minval=0.1, step=0.05) + adxLen = input.int(14, "ADX length", minval=2) + adxThreshold = input.float(22, "ADX threshold") + htf = input.timeframe("D", "Higher timeframe") + atrLen = input.int(14, "ATR length", minval=1) + atrMultiple = input.float(2.5, "ATR stop multiple", minval=0.1) + riskReward = input.float(3, "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) + [plusDI, minusDI, adxValue] = ta.dmi(adxLen, adxLen) + volumeAverage = ta.sma(volume, volumeLen) + atrValue = ta.atr(atrLen) + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.ema(close, 200)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 close > longMa and rsiValue >= rsiLongLevel and adxValue >= adxThreshold and plusDI > minusDI and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + shortSetup = emaFast < emaSlow and close < longMa and rsiValue <= rsiShortLevel and adxValue >= adxThreshold and minusDI > plusDI and volume >= volumeAverage * volumeMultiplier and htfBear and confirmationOk + longTrigger = ta.crossover(close, emaFast) + shortTrigger = ta.crossunder(close, emaFast) + 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" ? (htfBull ? color.new(color.lime, 95) : color.new(color.red
tests/strategy-execution-hardening.test.ts > strategy execution hardening > VWAP Session Trader uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("VWAP Session Trader", 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(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(9, "Fast EMA", minval=1) + emaSlowLen = input.int(21, "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(1, "Volume multiplier", minval=0.1, step=0.05) + tradeSession = input.session("0930-1600", "Trading session") + sessionTimezoneMode = input.string("America/New_York", "Session timezone", options=["exchange", "America/New_York", "Europe/London", "Europe/Istanbul", "UTC"]) + sessionTimezone = sessionTimezoneMode == "exchange" ? syminfo.timezone : sessionTimezoneMode + 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) + vwapValue = ta.vwap(hlc3) + rsiValue = ta.rsi(close, rsiLen) + volumeAverage = ta.sma(volume, volumeLen) + atrValue = ta.atr(atrLen) + + // === 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 + sessionOk = not na(time(timeframe.period, tradeSession, sessionTimezone)) + longSetup = emaFast > emaSlow and close > vwapValue and rsiValue >= rsiLongLevel and volume >= volumeAverage * volumeMultiplier and sessionOk and confirmationOk + shortSetup = emaFast < emaSlow and close < vwapValue and rsiValue <= rsiShortLevel and volume >= volumeAverage * volumeMultiplier and sessionOk and confirmationOk + longTrigger = ta.crossover(close, vwapValue) + shortTrigger = ta.crossunder(close, vwapValue) + 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(em
tests/strategy-execution-hardening.test.ts > strategy execution hardening > Fast EMA Scalper uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("Fast EMA Scalper", 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(3, "Signal cooldown bars", minval=0) + expectedChartTimeframe = input.timeframe("5", "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(21, "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(1.2, "Volume multiplier", minval=0.1, step=0.05) + htf = input.timeframe("60", "Higher timeframe") + atrLen = input.int(14, "ATR length", minval=1) + atrMultiple = input.float(1.5, "ATR stop multiple", minval=0.1) + riskReward = input.float(1.5, "Risk/reward", minval=0.1) + + // === Core calculations === + emaFast = ta.ema(close, emaFastLen) + emaSlow = ta.ema(close, emaSlowLen) + longMa = ta.sma(close, longMaLen) + vwapValue = ta.vwap(hlc3) + rsiValue = ta.rsi(close, rsiLen) + volumeAverage = ta.sma(volume, volumeLen) + atrValue = ta.atr(atrLen) + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.ema(close, 50)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 close > vwapValue and rsiValue >= rsiLongLevel and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + shortSetup = emaFast < emaSlow and close < vwapValue and rsiValue <= rsiShortLevel and volume >= volumeAverage * volumeMultiplier and htfBear and confirmationOk + longTrigger = ta.crossover(emaFast, emaSlow) + shortTrigger = ta.crossunder(emaFast, emaSlow) + 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" ? (htfBull ? color.new(color.lime, 95) : color.new(color.red, 95)) : 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) + plot(vwapValue, "VWAP",
tests/strategy-execution-hardening.test.ts > strategy execution hardening > Balanced Intraday uses executable equity sizing in Strategy mode: tests/strategy-execution-hardening.test.ts#L15
AssertionError: expected '//@Version=6\n// Generated determinis…' to contain 'calc_on_order_fills=true' - Expected + Received - calc_on_order_fills=true + //@Version=6 + // Generated deterministically by PineForge Studio + // Review and test this script in TradingView before using it with real capital. + strategy("Balanced Intraday", 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(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(55, "RSI long threshold") + rsiShortLevel = input.float(45, "RSI short threshold") + volumeLen = input.int(20, "Volume average", minval=1) + volumeMultiplier = input.float(1, "Volume multiplier", minval=0.1, step=0.05) + htf = input.timeframe("240", "Higher timeframe") + 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) + vwapValue = ta.vwap(hlc3) + rsiValue = ta.rsi(close, rsiLen) + volumeAverage = ta.sma(volume, volumeLen) + atrValue = ta.atr(atrLen) + + // Uses the previous confirmed higher-timeframe candle with lookahead_on to avoid future leakage. + htfBull = request.security(syminfo.tickerid, htf, close[1] > ta.ema(close, 100)[1], lookahead=barmerge.lookahead_on) + htfBear = not htfBull + + // === 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 close > longMa and close > vwapValue and rsiValue >= rsiLongLevel and volume >= volumeAverage * volumeMultiplier and htfBull and confirmationOk + shortSetup = emaFast < emaSlow and close < longMa and close < vwapValue and rsiValue <= rsiShortLevel and volume >= volumeAverage * volumeMultiplier and htfBear and confirmationOk + longTrigger = ta.crossover(close, emaFast) + shortTrigger = ta.crossunder(close, emaFast) + 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" ? (htfBull ? color.new(color.lime, 95) : color.new(color.red, 95)) : 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, linewi
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/