Skip to content

When two Pine engines disagree: cross‑validating PineForge against PyneCore

9 min read

How we use PyneCore as a second-source engine next to TradingView, what the May 2026 sweep showed, and why a friendly second engine is the most useful debugging tool we own.

The figures in this post were measured on May 5, 2026 and are kept as they were. For current results, see how we measure parity.

In May 2026 we knew of two off-platform engines that backtest Pine strategies: ours, and PyneCore. PyneSys's PyneComp transpiles Pine to Python; PyneCore is the open-source Python runtime that executes the result. Different language, different runtime, same source material, same API definitions to honour.

We treat PyneCore as our second-source oracle. In May 2026 we ran the parity sweep against both TradingView's "List of Trades" exports and PyneCore's executed output. When all three agree on a strategy's trades, we believe the result. When two agree and one diverges, the divergent one is where we look first.

This post shows what the numbers from that sweep looked like. The current comparison, the engine repo's bake-off of 2026-09-29 (measured at engine 35db01c8, which v1.0.0 includes), is on the compare page.

The corpus

50 reference strategies were in the public sweep (the broader 162-strategy corpus was private at the time; this subset was what we published in the trade-comparison report, benchmarks/results/trade_comparison.md at engine commit 7e526c1a). Each strategy got:

  • Compiled to Python by PyneComp, executed by PyneCore on the canonical OHLCV
  • Compiled to C++ by PineForge codegen, run by pineforge-engine on the same OHLCV
  • Both diffed against TradingView's CSV export, window-clipped to [OHLCV span] ∩ [TV entry span] ∩ [engine entry span]
  • Match-degree assigned per the 5-tier scale (excellent / strong / moderate / weak / minimal)

The headline

Of the 50 strategies in the sweep, 47 hit the same tier in PineForge and PyneCore: both engines hit excellent on 45 and strong on 2. On those 2, 13-parabolic-asr and 17-bos-curv, the two engines produced the same trades, and both trade counts differed from TV's by 1.8–2.8 %. Under the rubric of the time, excellent meant a trade-count difference under 1 %, entry and exit p90 under 0.01 %, P&L p90 under 1 % (looser exit and P&L limits for trail_* exits) and at least 95 % of TV's in-window trades matched.

The 3 that disagree by tier are interesting cases. All 3 are PineForge-higher.

StrategyPineForgePyneCoreNotes
49-partial-exit-qty-percentexcellentweakPyneCore over-emits exit fills
06-liquidity-sweepexcellentmoderateExit timing drift on Pyne side
07-scalping-strategyexcellentmoderatePnL p90 high on Pyne; entries match

The interesting one

49-partial-exit-qty-percent is the largest gap. The strategy uses strategy.exit(qty_percent=...) to peel off partial position size on profit-take, and the cycle repeats: fully exited, re-entered, partially exited again. Across the test window:

TV trades (raw, in-window):  725
PineForge engine trades:     852  →  725 in-window  →  725 matched (100% of TV)
PyneCore  engine trades:    3297  →  2805 in-window →  582 matched (80.3% of TV)

PyneCore's count delta on this strategy is 74 %: the harness divides the difference by the larger count, 2,805 in-window trades against TV's 725. PineForge's is 0 %. Looking at the p90 metrics:

PineForge: count_delta 0.0000% · entry p90 0.0000% · exit p90 0.0004% · PnL p90 0.1321%
PyneCore : count_delta 74.1533% · entry p90 0.0000% · exit p90 1.0376% · PnL p90 (high)

Translation: on the trades that pair up with TV's, both engines enter at TV's prices (entry p90 is 0 % for both), though PyneCore pairs only 582 of TV's 725. The disagreement is on exits. PyneCore generates roughly 4× as many trades as TradingView does for the same strategy (2,805 against 725 in the window), most likely an over-firing of partial-exit cycles where the same qty_percent clause re-arms before TV's order processor considers it complete.

This is not a value judgement on PyneCore's quality. It's a corner case in Pine's strategy.exit() semantics. The comparison works in both directions: when PyneCore agrees with TV and PineForge doesn't, the bug is ours.

The other two

06-liquidity-sweep and 07-scalping-strategy are smaller-magnitude versions of the same shape. Both have entry alignment at 100 %; the exit-price p90 drift is 1.65 % (06) and 0.48 % (07) on PyneCore, against 0.0005 % and 0.029 % on PineForge. Trail-style exits and partial-fill semantics are where Pine's reference implementation is least documented; both engines have to reverse-engineer it from observable trade behavior.

Calling the PyneCore compile API

PyneSys exposes the compile step over HTTP at api.pynesys.io. You can hit it directly with curl:

curl -X POST https://api.pynesys.io/compiler/compile \
  -H "Authorization: Bearer $PYNESYS_API_KEY" \
  --data-urlencode 'script=//@version=6
strategy("ma cross", overlay=true)
if ta.crossover(close, ta.sma(close, 20))
    strategy.entry("L", strategy.long)'

The response is a Python file that targets the open-source pynecore runtime. This is what it looked like in May 2026; newer PyneComp releases write their own version in the header and mark the file @pyne edge:

"""
@pyne
 
This code was compiled by PyneComp v6.0.31 — the Pine Script to Python compiler.
Run with open-source PyneCore: https://pynecore.org
Compile Pine Scripts online at PyneSys: https://pynesys.io
"""
from pynecore.lib import close, script, strategy, ta
 
 
@script.strategy("ma cross", overlay=True)
def main():
    if ta.crossover(close, ta.sma(close, 20)):
        strategy.entry('L', strategy.long)
 
 
if __name__ == "__main__":
    from pynecore.standalone import run
    run(__file__)

Drop that into a Python file, pip install pynesys-pynecore, point it at your OHLCV, and you get the second-engine output to diff against PineForge.

Why this matters

A single backtest engine reporting "your strategy returns 12.4% over the test window" tells you exactly one thing: that engine claims that result. If you have nothing to compare against, you have to take the engine's word for it.

A pair of independent engines reporting the same result on the same script is much stronger evidence. When they disagree, the disagreement itself is a hypothesis: one of them has a bug, the corner case in Pine semantics is ambiguous, or the test data has an edge condition neither engine handles. All three are valuable to know.

We use PyneCore this way: the engine repo's benchmark now grades PineForge and PyneCore against TradingView on the same 200 strategies (PineForge also runs one more, whose source the PyneSys compiler rejects). If you're shipping a strategy you'd put real money behind, you should use a second engine too.

What's not in this post

  • Indicator-level drift. A separate report compares per-indicator values across PineForge, PyneCore and PineTS: engine against engine, not against TradingView. It lives in benchmarks/results/indicator_comparison.md in the engine repo.
  • The other ~110 strategies in the internal corpus of the time, which weren't in the public sweep. They exercised Pine corner cases (UDT methods, multi-timeframe lookups, OCA exit groups). The method has since been published on the methodology page.

Try the cross-validation pattern yourself

Two engines, one source, three outputs to compare. If they all agree, ship it. If they disagree, you've learned something useful before any real money was on the line.