v6.9.3
Features
Dependent request.security() expressions are synchronized bar by bar
A security expression that reads the result of another security call now sees the peer's value for the
correct bar instead of whatever happened to be in the peer's slot. Scripts that feed one context's
result into another — for example request.security(sym, "M", ta.sma(monthlyRsi, n)) — no longer
diverge.
One pairing rule is applied everywhere: a consumer sees the peer's last bar whose scheduled close is at
or before the consumer's as-of time. Scheduled closes come from the trading schedule (intraday:
min(open + span, next open, session end); D/W/M: the end of the last scheduled session in the period),
never from nominal timeframe arithmetic. The chart itself now uses the same rule in its confirmation
logic, replacing the grid branch, the next-chart-time early confirmation and the sparse-series clamp.
Producers publish into a per-symbol append ring of (open, scheduled close, value) plus a frontier
close, so a consumer can wait for exactly the bar it needs and never waits for a bar the producer will
not publish. A round now advertises exactly what it published — a developing round up to its own tick
(or to the end of the scheduled break containing it for a D/W/M context keeping the chart's calendar),
a closed round clamped to the same as-of — so a consumer running on a later tick of the same bar no
longer pairs with the previous tick's value.
Static dependencies are computed by the transformer with forward taint analysis, alias and control-flow
tracking; the bindings a dependency needs are hoisted, and call sites inside loops are marked. A
loop-sited security expression publishes on its first write per bar and raises if a later iteration
produces a different value. Dependencies are restricted to earlier-sited producers; a later-sited peer
read returns the default value.
Behaviour changes:
- An early close the schedule does not know about (a holiday or a half-day) now makes the D/W/M bar
visible one chart bar later, matching what live mode already did. - A lower-timeframe bar that straddles the chart bar boundary is delivered on the next chart bar
instead of leaking a close from after the chart bar.
Also fixed: shared memory block names could collide between concurrent runs of the same script; they are
now derived from the OS-assigned sync block name and the slot index.
ticker.heikinashi() contexts warm up from a mapped context feed
A chart-type context splits in two. Its series is the ordinary same-symbol context — at an intraday
notation the chart's bars are aggregated, so the context opens at bar_index 0 on the chart's first
bar. Its transform is not: the Heikin Ashi recurrence carries over from that resolution's own feed, so
the context's first open is the carried value, not (open + close) / 2.
A --security mapping for such a context is therefore a seed source, not a data source. It is now routed
to the child, which advances the recurrence over the mapped file's bars strictly before its own first
bar and leaves the chart aggregation as the series. A context at the chart's own resolution keeps
reading a mapping as plain data; without a mapping the context logs the cold start it falls back to.
Fixes
Strategy
strategy.opentrades.profit_percent()and the other per-trade open-trade returns are now refreshed in
backtests and before every live broker script tick, instead of staying at 0. The backtest exit fee is
estimated at the current mark, and the remaining entry-fee share is preserved after a partial broker
close. (#83, duplicate #82)- Past the retained closed-trade limit,
strategy.closedtradeskeeps counting globally and the
accessors address the intended trade: global closed-trade numbering is preserved when the retained
list evicts old rows, and finalized trade report metrics are accumulated independently of the bounded
history. (#84)
request.*
request.earnings(),request.dividends()andrequest.splits()returnnawhen the requested
ticker is the current crypto chart, instead of raising. Explicit errors are preserved for genuinely
unsupported feeds.
Broker and live mode
- A
close_lega plugin declines (the leg already settled, or the position is busy with another venue
operation) is routed through the one-way fan instead of propagating as a raw reject: the pending leg
row is discharged, the skip propagates for script and engine-triggered partial closes when nothing
went on the wire, the fan ends as a partial success once earlier legs were dispatched (their fills
stay owned, and the dispatched quantity covers only the sent legs), and it is re-raised as a
definitive rejection for reversal and residual-replay fans. - Restart recovery: a consumed entry anchor is now detected and a fresh order ID is minted, orphaned exit
legs are retired on a flat-book restart, and reopened order lifecycles are reset. - Duplicate reversal closes are prevented — a stale reversal marker is deferred while another fresh close
already covers the remaining exposure. - Live mode drops out-of-order closed candles that arrive behind a forming bar, so a late close can no
longer move the strategy clock backwards.
Library
timestamp()treatsnacomponents as zero instead of raising.