Skip to content

v6.8.13

Latest

Choose a tag to compare

@wallneradam wallneradam released this 26 Aug 13:26
· 1 commit to main since this release

This release closes the remaining measured TradingView divergences in the strategy simulator — margin calls, exit brackets and ta.sar — and hardens live broker reconciliation against the state a restart or a cross-script rotation leaves behind.

Features

TradingView's second intrabar margin-call stage

After a margin-call liquidation TradingView does not credit the proceeds at the bar's next checkpoint. It walks the pre-liquidation trades FIFO, crediting each trade's entry cost immediately but its realized gain (net of the exit commission only) one trade late, and stops while the running credit still fits inside the deficit. The remaining shortfall is covered 4x like the first stage, sized at the FIRST stage's checkpoint price, capped by the remaining position, and filled at the next checkpoint with slippage. When the first trade's cost alone exceeds the deficit — the common single-trade case — no second stage fires.

Measured on BINANCE:BTCUSDT 30m: 848/848 margin-call bars exact (94 Rocket Grid corpus and input-sweep bars, 754 synthetic single-stage probe bars). Rocket Grid Algorithm goes bit-exact (plot 1.0, 411/411 trades, exact net profit), and all 16 margin-call corpus strategies stay at 1.0.

request.security() warns instead of going silent

A request.security() call with ignore_invalid_symbol=true whose data was never provisioned was downgraded to an all-na series without a word, so the run completed successfully while every value derived from that context was wrong. The downgrade is now logged at WARNING with the fully resolved symbol and timeframe.

Fixes

strategy.exit() absolute and relative levels

A tick offset and its absolute counterpart — profit/limit, loss/stop, trail_points/trail_price — are both live in Pine v6, and the one the price path reaches first fills. The runtime resolved a tick offset only while its absolute level was unset, which is the v4/v5 rule, so a nearer offset never fired.

Measured on BINANCE:BTCUSDT 30m over 28915 bars: with the absolute level farther out the trades are bit-identical to the same script written without it at all, while a nearer one takes 30 of 140 take-profit and 36 of 141 stop exits. A v4/v5 source keeps its own meaning through PyneComp, which writes the absolute level's priority into the converted text.

Margin checks under pyramiding

Two margin divergences measured against TradingView on the pyramiding Rocket Grid Algorithm strategy:

  • The unaffordable-entry sweep required margin for the position an order would leave behind instead of the order's own size, so every stacked stop entry beyond the affordable one was cancelled. The two figures coincide from flat, but not under pyramiding.
  • A long's favorable extreme is a margin checkpoint a second time after the leg's fills: an entry filling on the way up raises the position's requirement above what the pre-leg checkpoint could see.

ta.sar()

TradingView validates none of ta.sar's three arguments: a start above max is its own series, max values of 0.9 / 0.7 / 0.5 stay distinct once inc reaches them, and zero, negative or zero-increment factors compute instead of erroring. The three asserts rejected all of those, killing scripts that ship such inputs.

A large acceleration factor also exposes the reversal tie: the test is strict on both sides, so a bar whose high equals the short stop (or whose low equals the long stop) does not reverse, and the level is carried forward by the two-bar clip instead.

ta.highest() / ta.lowest() behind a gate

Both now keep their own per-call-site window buffer of length + 1 slots addressed by the chart bar, written only on the bars the call runs, instead of rescanning the source series' bar history. A gated call then serves the stale slot TradingView serves: measured on a ta.lowest(low, 10) behind a position-state if, 28827 of 28827 bars match where reading the source missed 872. This supersedes the series-level stale-on-gap flag, which is removed along with its transformer mapping.

Trailing exits issued after the entry filled

A trailing exit first issued after its entry already filled anchors its water mark to the issue bar's close rather than folding that bar's extreme in. With the extreme the stop sits above the next bar's open and gaps through it, costing 106 of 222 exit prices in a probe.

Default-sized entries on a foreign-quote symbol

A resting default-sized entry freezes the quote-to-account rate together with its money budget, so only the fill price comes from execution. With the fill bar's rate, 12 of 580 entries of a USD-account strategy on a USDT-quoted symbol sized one lot off, ten of them on the daily rate step.

Bool-valued and / or

Pine's and/or yield a bool and cast every operand, while Python's yield the operand itself. The truthiness rewrite handed a non-float operand back raw, so a na or int operand leaked out as the whole expression's value and a marker plot exported na where TradingView exports 0.

math.round_to_mintick() ties

The tie was decided on the double product; TradingView decides it on the exact value of number * pricescale / minmove, ties away from zero, with the same 1e-10 tolerance round() carries. 19999.585 rounds up and 16384.245 rounds down although both products are the same exactly representable .5 as a double. A double fast path keeps the common case at two flops and drops to int arithmetic only inside a near-tie window.

Live broker reconciliation

Orphan exit legs on a flat book

Exit tracking keyed to stale parent IDs is now cleaned up after flat closes, while exit brackets belonging to pending or opening entries are preserved.

Cross-script rotation adopts the prior run's protective TP/SL leg rows store-side, but the new script never declares those pine ids, so no in-memory exit tracking exists for them. The orphan-exit sweep walked only the in-memory tracking and retired nothing: the adopted venue legs stayed armed after the flat close and later filled into empty inventory — measured live, three prior-cycle TP legs filled 11 minutes after the flat close, quarantining the spot ledger on negative inventory. Sweep parents are now collected from the durable journal's live exit-leg rows as well.

A cancel arriving after a full fill

A CANCELLED for an order whose cumulative fill already consumed its whole quantity is not an external cancel: nothing working was left to cancel, and the exposure is fully owned by the fill events already booked. Venues still surface such a cancel late — measured on Capital.com, an in-flight entry was netted into an opposite deal's close and the consumed order was reported CANCELLED 28 minutes after its complete fill — and both paths that see it ran the unexpected-cancel policy, quarantining a healthy run over bookkeeping. Both paths now treat it as a benign echo.

A replayed parent's fail-safe state

Cancelling the legs a restart replay rebuilt under a prior run's parent evicted the only handle the retire walk uses to reach that parent's dispatch ref, so its DEGRADING fail-safe state was left behind, later degraded, and blocked every new entry on the symbol on a flat book. The foreign refs are now retired explicitly before the cancel.

The adopted partial-qty classification restore is also logged once per intent instead of every sync; the restore itself still runs each cycle.