Performance
request.security in backtests
Most of this release is about the cost of request.security() contexts on
historical bars. Output is unchanged; the per-bar path is still available
with PYNE_NO_SECURITY_BATCH=1.
- Same-timeframe contexts run as one batch round. A static,
dependency-free, same-timeframe context without lookahead no longer
handshakes with the chart on every bar. Its child runs the whole historical
phase at once, and the chart pairs each bar's value out of the shared ring. lookahead_onhigher-timeframe contexts are batched too. A same-symbol
higher-timeframe context withlookahead=barmerge.lookahead_onused to cost
one chart-to-child round trip per chart bar. It now replays the exact round
sequence of the per-bar path (prefill, period closes and every developing
re-tick) as one developing batch round. The plan is generated lazily from
the chart's bar window: on a 30k-bar run the parent's peak RSS dropped from
164 MB to 87 MB, and a 29783-bar window completes in 30 s against 42 s on
the per-bar path. Modes that re-runmain()within a candle
(calc_on_order_fills,calc_on_every_history_tick, script timeframe,
calc_bars_count, bar magnifier, live) keep the per-bar path.- Contexts start lazily. A context's child process is spawned at its
first read instead of its first signal, so arequest.security()call in a
branch the run never takes no longer costs a process and a round per bar.
Producers a consumer depends on are started first. - Scope-aware dependency analysis. The security transformer tracks
locals per function, parameters per call site, returned aliases,
nonlocal/globalwrites, flow-sensitivebreak/continue/return,
read-onlyarray/matrix/mapfunctions, per-loop loop variables, and
module-level field-only classes (Pine types). Spurious "every context
depends on every earlier one" chains, which disabled batching and forced
serial execution, are gone on the scripts where they appeared. On one
multi-context corpus script the last round of this work alone cut the run
time from 126 s to 9 s. - Helper signals are lifted. A
request.security()inside a helper
function called once and unconditionally now signals from the top of
main(), so its context starts in parallel with the others. - Faster higher-timeframe bar-close walk. Session ends are prepared once
per date instead of once per bar, which was the largest parent-side cost of
many-context scripts. A 24h schedule's 23:59:59 end marker is now treated as
midnight, so the last bar of the day is no longer confirmed one second early.
Fixes
request.security
- A runtime-resolved context (symbol or timeframe known only at runtime) that
sits in a branch the run never takes no longer demands a data feed. This
includes ternaries andand/oroperands, which Pine evaluates every bar:
a missing feed now logs a warning at resolution and raises the
"No OHLCV data found" error only at the first real read of the context. - A nested
request.security()(one inside another's expression) is now a
real dependency of the outer context. The outer child previously read the
inner value asnaeven when data existed. - A producer whose symbol or timeframe was still unresolved when its consumer
started could leave the chart waiting forever; it now starts at its own
first signal. - The per-bar path could read the previous step's value on the first chart
bar, because a second wake-up from the child answered the chart's next wait. - A lifted wait placed in front of a helper's
returnmade the chart wait for
each child's whole bar.
Strategy engine
- Pyramid add under
process_orders_on_close. An exit leg created by a
pyramid add filling in the close pass now gets its fill attempt on the same
bar instead of the next one. - Price entry after a pending market reversal. A stop or limit
strategy.entryplaced after a market reversal on the same bar froze its
reversal size at 0, sat out the flip bar and re-armed a bar late. The
pending market entries are now counted. On the affected corpus strategy the
trade match went from 0.9984 to 1.0.
Runtime
barstate.isnewon history. It stayedfalsethrough the whole
historical replay; it is nowtrueon every historical bar, as on
TradingView, soif barstate.isnewreset blocks ofvaripaccumulators
run.varipseries history. Reading the history of avaripseries raised
'float' object is not subscriptable; it now works.nainand/or.and/ornever yieldnain Pine; a comparison
with annaoperand leaked out as the whole expression's value and a plot
exportednawhere TradingView exports 0.- Three-state bool comparisons. In a script that keeps Pine's three-state
bool, a comparison with annaoperand now answersnainstead offalse,
as TradingView does (na == naincluded). Two-state (v6) scripts are
unchanged.
Broker order sync
- A bracket for an entry that was never dispatched to the exchange is now
deferred together with its entry while the position view is unconfirmed,
instead of reaching the plugin as an exit for a position that does not
exist.