Skip to content

PyneCore v6.8.9

Choose a tag to compare

@wallneradam wallneradam released this 21 Aug 11:53
· 24 commits to main since this release

This release closes the remaining gaps between PyneCore's numbers and TradingView's, tightens the "no lookahead, ever" boundary, and hardens the broker plugin's live reversal and spot-inventory paths.

TradingView numerical exactness

  • Constant folding, transcendentals and cross state now match TradingView. Constant expressions are evaluated once at parse time with an fdlibm port (sin, cos, exp, asin, acos) and embedded capped at 16 decimals, while series-fed math.* calls run an Intel-LIBM port at runtime — reproducing the two different math paths TradingView uses. ta.crossover/ta.crossunder follow the measured rule: an exact-equality plateau no longer arms a cross.
  • Conditionally called ta.highest/ta.lowest now reproduce TradingView's window buffer. A builtin called from one arm of a branch runs only on the bars that enter it, and TradingView's native buffer then serves values the data never had at that bar. Both halves of the behaviour — the stale slot served across a skipped bar and the extreme ageing in bars rather than in calls — are reproduced. On the wild-corpus script "Leledc levels (IS)" (28302 bars) this turns a 0.9536 correlation into a bit-exact match on every column.

No lookahead, ever

  • Historical barmerge.lookahead_on no longer leaks the containing HTF bar. A same-symbol higher-timeframe request in historical mode was reading the period's already-complete bar from the child's own data file, so a bare close returned the period's final close — a value hours in the future. The developing-bar transport now runs in historical mode too, so an open period reports only what its bars could have had. The daily-pivot idiom security(sym, "D", close[1], lookahead_on) is unaffected and stays TradingView-exact.
  • New PYNE_ALLOW_LOOKAHEAD measurement switch. Because PyneCore closes every one of TradingView's future-leaks, a repainting script becomes indistinguishable from a sound one under static inspection. With PYNE_ALLOW_LOOKAHEAD=1 those channels are restored so a script can be run both ways to measure whether it depends on data its bars could not have had. It is a measurement switch, never a trading one. Several security and series-replay defects surfaced while measuring the wild corpus with it are fixed.
  • calc_on_every_history_tick added; intra-bar passes no longer read the whole bar. A mid-bar body execution now sees the bar truncated to its own point (running high/low, that point's close, accrued volume, and hl2/hlc3/ohlc4/hlcc4 recomputed from them). This closes the calc_on_order_fills leak and enables the new calc_on_every_history_tick, which runs the body at every point of a historical bar the broker emulator walks. Also fixes a varip rollback bug this exposed, where a varip with a non-literal initializer lost values across discarded re-executions of the first bar.

Strategy semantics

  • strategy.direction.all is now honoured. The direction filter compared the allowed direction with the intended side and rejected every entry of a strategy passing strategy.direction.all — the default of every direction-filter input. It now tests against the opposite direction.
  • strategy.position_entry_name added. Reports the id of the oldest still-open entry (measured on TradingView: with two pyramided entries it keeps naming the first), na when flat.

Broker plugin robustness

  • Reverse via close-then-open on every venue mode. A filled market entry in the opposite direction now always dispatches a symbol-wide reversal close first and parks the raw entry until the book settles flat, instead of folding the position into one oversized order. Same-bar replacement is handled: a larger re-placed entry re-parks only the remainder, a smaller one supersedes the parked open.
  • Reversal protocol hardened against venue glitches. Fixes three defects measured live on a single stop-and-reverse: a glitched flat read arriving before the close leg's own fill walked an empty FIFO into a phantom opposite position; a late close fill labelled with the entry's own Pine id slipped past the cleared-entry drop guard; and a declined reversal close left no marker, so sync passes re-ran the protocol into the same decline many times per second. A persistent decline now retries at most once per bar.
  • Spot-inventory hardening. Unsellable spot fee dust is compacted into the epoch baseline (never re-anchored to the venue balance, so real drift cannot be absorbed); a quarantined epoch recovers automatically at the next startup; a closing fill leaving a sub-step residual books the remainder as non-tradable dust instead of overselling; and one-way-emulator port dispatches run on the classifying write bridge so a timeout ends in a controlled halt rather than a raw crash. Adds min_sellable_base() to the spot-inventory protocol and a spot_executions.retired column (migration 6).
  • Bracket qty amend sized from the fee-netted entry fill. On spot venues that charge the buy-side fee in the base coin, the partial-fill bracket amend compared against the gross filled quantity, so the TP/SL legs oversold the inventory by the fee and drove the ledger into quarantine. The amend now sizes from the fee-netted fill.