A common TradingView pattern is a strategy that consumes a separate indicator's output series via
input.source() ("indicator-on-indicator" wiring, set through the chart UI on TV). We have a short-only
BTC strategy whose divergence signal is produced by a companion "divergence" indicator and read into the
strategy through input.source().
On TradingView this reconciles to our research. In headless PyneCore (CLI / API over a single .ohlcv
file) the same strategy reproduces only ~23% of the TradingView trades. The same divergence logic
embedded inline in the strategy reproduces faithfully. This points at the input.source() series
binding/delivery in headless execution rather than at the divergence engine itself.
We are not sure whether this is (a) a bug in how a companion indicator's series is delivered into a
strategy's input.source() headlessly, or (b) an unsupported pattern in headless mode with a
recommended idiom. Either answer unblocks us.
What we observe
Engine is faithful. Our standalone divergence engine vs the companion indicator's exported series:
F1 = 0.9967 over 116,796 bars (BTCUSDT.P 30m, 2019-2026); 0 false positives, 11 false negatives
(pairing-layer edge cases). Armed-state agreement at all 113 strategy entry bars: 113/113.
Via input.source() (headless PyneCore): ~23% FIFO trade match vs TradingView (26/113 trades).
PnL parity on the matched trades is ~100% (so the trades that DO match are exact — consistent with a
series-binding/delivery gap rather than an engine error).
Inlined (no input.source()): faithful on TradingView.
Minimal reproduction (sketch — full repro available on request)
pine// Companion indicator: plots a deterministic, non-trivial series
//@Version=6
indicator("emit_producer")
plot(bar_index % 7 == 0 ? 1 : 0, "emit")
pine// Consumer strategy: reads the companion plot via input.source()
//@Version=6
strategy("emit_consumer", process_orders_on_close=true)
src = input.source(close, "Emit series") // on TV: point this at emit_producer's "emit"
if src > 0
strategy.entry("L", strategy.long)
if src <= 0 and strategy.position_size > 0
strategy.close_all()
On TradingView the consumer trades on the producer's emit. We would like to know how to reproduce that
same wiring headlessly (CLI/API) so PyneCore delivers the producer's series into the consumer's
input.source().
What would help us (any one)
The supported way to feed a companion indicator's output into a strategy's input.source() in
headless PyneCore (e.g., an extra data column, a companion-script mechanism, or a config binding).
Confirmation that indicator-on-indicator input.source() is unsupported headlessly, with the
recommended idiom (we currently inline the producer logic into the consumer, which works and is our
shipped pattern).
If it should work, a pointer to a known-good fixture exercising a strategy input.source() bound to
a second script, so we can diff.
Environment
PyneCore: 6.4.8 (pynesys-pynecore 6.4.8)
Python: 3.11+
Data: TV-parity BTCUSDT.P 30m continuous history (2019-2026)
OS: Windows 11 (Python venv)
A common TradingView pattern is a strategy that consumes a separate indicator's output series via
input.source() ("indicator-on-indicator" wiring, set through the chart UI on TV). We have a short-only
BTC strategy whose divergence signal is produced by a companion "divergence" indicator and read into the
strategy through input.source().
On TradingView this reconciles to our research. In headless PyneCore (CLI / API over a single .ohlcv
file) the same strategy reproduces only ~23% of the TradingView trades. The same divergence logic
embedded inline in the strategy reproduces faithfully. This points at the input.source() series
binding/delivery in headless execution rather than at the divergence engine itself.
We are not sure whether this is (a) a bug in how a companion indicator's series is delivered into a
strategy's input.source() headlessly, or (b) an unsupported pattern in headless mode with a
recommended idiom. Either answer unblocks us.
What we observe
Engine is faithful. Our standalone divergence engine vs the companion indicator's exported series:
F1 = 0.9967 over 116,796 bars (BTCUSDT.P 30m, 2019-2026); 0 false positives, 11 false negatives
(pairing-layer edge cases). Armed-state agreement at all 113 strategy entry bars: 113/113.
Via input.source() (headless PyneCore): ~23% FIFO trade match vs TradingView (26/113 trades).
PnL parity on the matched trades is ~100% (so the trades that DO match are exact — consistent with a
series-binding/delivery gap rather than an engine error).
Inlined (no input.source()): faithful on TradingView.
Minimal reproduction (sketch — full repro available on request)
pine// Companion indicator: plots a deterministic, non-trivial series
//@Version=6
indicator("emit_producer")
plot(bar_index % 7 == 0 ? 1 : 0, "emit")
pine// Consumer strategy: reads the companion plot via input.source()
//@Version=6
strategy("emit_consumer", process_orders_on_close=true)
src = input.source(close, "Emit series") // on TV: point this at emit_producer's "emit"
if src > 0
strategy.entry("L", strategy.long)
if src <= 0 and strategy.position_size > 0
strategy.close_all()
On TradingView the consumer trades on the producer's emit. We would like to know how to reproduce that
same wiring headlessly (CLI/API) so PyneCore delivers the producer's series into the consumer's
input.source().
What would help us (any one)
The supported way to feed a companion indicator's output into a strategy's input.source() in
headless PyneCore (e.g., an extra data column, a companion-script mechanism, or a config binding).
Confirmation that indicator-on-indicator input.source() is unsupported headlessly, with the
recommended idiom (we currently inline the producer logic into the consumer, which works and is our
shipped pattern).
If it should work, a pointer to a known-good fixture exercising a strategy input.source() bound to
a second script, so we can diff.
Environment
PyneCore: 6.4.8 (pynesys-pynecore 6.4.8)
Python: 3.11+
Data: TV-parity BTCUSDT.P 30m continuous history (2019-2026)
OS: Windows 11 (Python venv)