Skip to content

v6.5.0 — state-engine rewrite, strategy & request.security() TradingView parity

Latest

Choose a tag to compare

@wallneradam wallneradam released this 11 Jun 14:01
· 1 commit to main since this release

The largest release since the 6.4 line. The state engine has been rewritten end-to-end, the strategy simulator and request.security() reach trade-for-trade parity with TradingView on the previously diverging corpus strategies, and several Pine v6 surfaces are completed. 148 files changed.

State engine rewrite (slot-based per-instance state)

The module-global state scheme — mangled global names plus the FunctionType-keyed isolation cache — is replaced with compile-time slot layouts and runtime root state vectors:

  • Series / Persistent / varip variables now live in compile-assigned slots of their scope's state vector; reads resolve through the scope chain.
  • Call sites are classified at transform time into fast / direct / uniform routes; carrier status is a fixpoint over the module call graph.
  • Overload dispatch, Pine method dispatch and inline_series are anchored per call site, so a site whose argument types vary across bars keeps separate state per implementation.
  • Both runners (chart and request.security() children) drive every entry point — script main and registered library mains — through its own root vector, keyed per qualified function so library registrations can't collide.

Correctness fixes that fell out of the rewrite:

  • A str / bool persistent with a non-literal += no longer emits float arithmetic and crashes.
  • varip Kahan compensation is carried with its companion across var rollback, so the pair can't desynchronize.
  • Deterministic call routing, independent of sys.modules import order.
  • Stateful lib functions (fixnan, math.random, math.sum, timeframe.change) ported to @pyne submodules.

Module property routing

CallableModule and the hasattr-based runtime fallback are gone; module-property routing is now pure AST rewriting backed by an auto-generated, exhaustively tested registry (224 -> 1012 entries). Unknown names of known lib modules raise at transform time instead of failing at runtime, and a freshness test keeps the registry from going stale.

Performance

Per-bar hot-loop overhead cut in the runner and strategy engine: -18..-32% wall-clock on the benchmark strategies, -21% on the demo indicator. Behavior unchanged (suites pass, TV trades match bar-for-bar). Includes an idle fast path in process_orders, per-bar memoized time_tradingday, and a single-call timezone conversion in _set_lib_properties.

Strategy simulator — TradingView parity

Both previously diverging pyne-in-the-wild corpus strategies now match TV trade-for-trade.

  • Trailing stops rewritten as an intrabar O-H-L-C / O-L-H-C path walk: same-bar activation, ride and rebound fill at the extreme -/+ offset; hard-stop and limit legs reached earlier on the path win.
  • strategy.exit(from_entry=) covers every same-ID entry, recomputing the leg reservation on each (re-)issue instead of freezing the first size.
  • Margin calls on fractional-lot symbols size the liquidation in lot units (was always whole contracts), so crypto backtests no longer force-close the whole position and halve the trade count vs TV. The bar-open margin call keeps TV's whole-contract sizing.
  • Margin overshoot now depends on lot granularity: fractional-lot symbols fill-then-trim, whole-lot symbols reject the entry so the signal re-fires later.
  • Offset-0 trailing leg: trailing arguments alongside stop/limit are legal and arm at 0 ticks; trail_price-only exits are no longer dropped; trailing arguments without trail_offset are ignored per Pine docs.
  • Position-flat close: the flattening trade size is snapped to 0.0 so it is removed, fixing an NA-propagation TypeError in percent-of-equity sizing.

request.security()

  • Deferred and mixed contexts unblocked: a deferred context resolving to the chart's own symbol+timeframe now gets result blocks (no deadlock); static subprocesses in scripts mixing static and deferred contexts are now spawned; double-spawn is guarded.
  • Intraday HTF bars anchored to the session open (e.g. equities at 09:30 / 10:30 ...) instead of a pure UTC clock-floor, matching TV; zero overhead for 24/7, on-hour and session-aligned markets.
  • Library mains run before main() in security children, so scripts calling imported library functions no longer crash with "Exported proxy has not been initialized".
  • Config safety: security children no longer rewrite the script's .toml on import — multiple contexts could race and truncate the user's config (now disabled via PYNE_SAVE_SCRIPT_TOML=0).
  • request.security contexts from imported libraries are merged; deferred / same-context timeframe handling is more reliable.

Pine v6 built-ins

  • syminfo.mincontract plus the full Pine v6 syminfo namespace (main_tickerid, expiration_date, current_contract, isin, the recommendations_* family, and more). Order sizes are floored to the symbol's real lot grid (BINANCE:BTCUSDT -> 1e-5). The CCXT provider derives the step from precision, and pyne data download refines it from analyzed volume precision.
  • chart.point namespace (new, now, from_index, from_time, copy) and Pine keyword params for drawings: line.new first_point/second_point, box.new top_left/bottom_right, label.new point. Drawing coordinates widened to int | NA / float | NA.
  • Month-first date strings in timestamp(): "03-04-2023" resolves to March 4 with -, / or . separators and an optional HH:MM[:SS] part; day-first dates are still rejected, as on TV.
  • time / time_close overload handling extended for bars_back and chart-timeframe defaults; math.round precision guard fixed.

Transformer fixes

  • Parameter default values are rewritten in the enclosing scope, fixing a NameError when a parameter shadows a same-named lib module used in its own default.
  • PersistentTransformer rewrites persistent references in attribute and subscript assignment targets (persistent_udt.field = ...).
  • Overload dispatch treats Any (unannotated params, threaded closure vars) as a wildcard instead of crashing on isinstance(..., typing.Any).

CI

  • release.yml checkout / setup-python upgraded to Node 24 actions.