When we last published corpus numbers in May, the parity corpus held 167 reference strategies, 165 of them at strict trade-for-trade parity against TradingView. It's grown since. The corpus now holds 252 strategies — 251 at "excellent" parity (99.6%), one documented anomaly, zero failures.
The headline number is the boring part. The interesting part is what showed up while we were getting there: three TradingView broker behaviors we weren't modeling, each one found because a real or synthetic strategy exercised a code path the existing 167 didn't. This is a walk-through of three of them.
Where the corpus stands
corpus/validation_report.md (2026-06-29)
Total probes: 252
Excellent: 251 (99.6%)
Anomaly: 1
Strong/Moderate/Weak/Minimal/Fail: 0
TV trades: 389,590
Engine trades: 389,688
Matched: 389,468The engine emits 98 more trades than TradingView across the full corpus — a 0.025% delta on 389,590 reference trades. That's the aggregate; per-strategy, almost all of it is the one anomaly below, not noise spread across the other 251.
The newest six probes are a drawing category, added when we shipped a runtime for
reading Pine drawing objects (line.get_price, label/box geometry) as backtest-time data,
not just chart annotations. Strategies that use a drawn line as computational state — a
manually-anchored trendline used as a dynamic support level, say — need the engine to keep
serving geometry for objects the script has already deleted, the same way TradingView does.
All six passed clean.
The one anomaly, named honestly
We don't filter the one strategy that doesn't match. anomaly-equity-mirror-strategy-equity-01
sits at the exact 1× equity boundary for margin admission. TradingView's broker emulator is
non-monotonic right at that boundary — it admits some over-equity entries and rejects some
under-equity ones, inconsistently, bar to bar. Our engine is deterministic: same equity, same
admission decision, every time. That's correct per Pine's documented margin semantics. It is
also, provably, not what TradingView's broker actually does at that one boundary. We'd have to
introduce our own non-determinism to match it, so we don't. The gap is documented, not hidden,
and it's the only one of 252.
Bug one: the position TV would have force-closed
TradingView's broker doesn't wait for your strategy logic to decide when to exit a position
that's blown through its margin requirement — it liquidates. If a leveraged or short position's
equity drops far enough that required margin exceeds account equity, TradingView force-closes
the position at the next bar, no matter what strategy.exit() conditions are or aren't met.
The engine didn't model this. It would hold the position and let the strategy's own logic eventually close it — which on a strategy that doesn't have a tight stop could mean dozens of bars of a position TradingView had already liquidated. On corpus strategies with significant leverage, that produced wildly different equity curves under stress, even when entry and exit logic matched perfectly everywhere else.
The fix adds forced liquidation when account equity breaches the margin requirement, computing the liquidation price the same way TradingView's broker does, then quantizing the liquidated quantity to the symbol's lot step — TradingView doesn't liquidate fractional lots smaller than the exchange allows, and neither do we now.
This matters most for anyone backtesting leveraged or short strategies on perpetuals. If your equity curve looked too smooth during a drawdown, this was plausibly why.
Bug two: the affordability check that didn't know about FX
Pine strategies can declare an account currency that differs from the symbol's quote currency —
currency.INR trading a USDT pair, for example. Before checking whether you can afford an
order, TradingView's broker converts the order's notional value into your account currency
using the prevailing FX rate, then compares against equity in that same currency.
The engine's affordability gate skipped the conversion. It compared USDT notional directly
against INR-denominated equity as if the FX rate were 1:1 — meaning a strategy declaring
currency.INR looked roughly 83× more affordable than it should have (since 1 USDT is worth
roughly that many rupees). On affected scripts, that roughly doubled the number of trades the
engine admitted that TradingView's broker would have rejected as unaffordable.
The fix applies the account-currency FX rate to required margin before the affordability check runs, the same point in the order pipeline TradingView applies it. If you're backtesting with a non-USD-denominated account currency against a USD- or USDT-quoted symbol, this is the bug that was quietly inflating your trade count.
Bug three: the trailing stop that never armed
This is the one we'd most want a user to have caught before us, because it fails silently.
strategy.exit() supports two ways to specify a trailing stop: trail_points, an entry-relative
distance, and trail_price, an absolute activation price.
// armed correctly today; trail_price-only calls used to never arm at all
strategy.exit("TS", from_entry = "Long", trail_price = close * 1.05, trail_offset = 10)The engine's arming condition only checked trail_points. A trailing exit specified purely
via trail_price compiled without error, ran without error, and never armed — the position
just sat there with no trailing stop active, silently, for the entire backtest. No exception,
no log line, no trade. The strategy looked protected. It wasn't.
We found this because a corpus probe specifically isolates trail_price-only activation —
exactly the kind of narrow, synthetic strategy the validation category exists for, per the
corpus breakdown post: not profitable, not realistic,
built to exercise one Pine feature in isolation so a regression like this can't hide behind
"the overall numbers looked fine."
The fix arms the trailing stop if either trail_points or trail_price is present. If you've
ever written a Pine strategy using trail_price and the equity curve looked suspiciously like
there was no trailing stop at all — there wasn't, on any engine version before this one.
Why this is the actual point of a corpus
None of these three bugs were found by code review. They were found because a strategy with the right shape ran through the engine and produced a number that didn't match TradingView's. That's the whole thesis behind keeping 167 strategies, then 252, and counting as a held-out, versioned corpus instead of a handful of smoke tests: bugs that don't change the trade count or the entry price can still change the number that matters most — what the strategy made or lost — and the only way to catch those is to keep running more shapes of strategy through the same diff against the same ground truth.
We'll keep adding probes as we find gaps, and keep publishing the numbers — good and the one anomaly — as they stand.
Where to go from here
- Browse the gallery — all 252 strategies, parity tier and trade count on every card.
- Read how we found a similar margin bug — a different bug, a different boundary, same method: isolate, diff, fix.
- Try the codegen API — transpile a Pine strategy and backtest it on your own OHLCV from Claude, Cursor, or any MCP client.
- Get early access — free tier, 100 transpiles a month.
