PyneTS parity

How to compare @hoox-sh/pynets Runtime.run plots against Python pynescript.runtime. Python wins ties.

This page

Manuals

Full PDFComplete

PyneTS parity

Abstract

Parity here means TypeScript Runtime.run vs Python Runtime.run on the same source and the same bars — not vs TradingView. Interpret↔compile alignment inside PyneTS is a second, narrower check (test/compile_*.test.ts).

Workflow when adding or fixing a builtin: read the Python handler, port na / lookback / call-site semantics, wire the name, add a focused test/interpret_*.test.ts, compare plots if PYNE is present.

Conceptual model

Diagram

Rendering…

Interface surface

Commands

# PyneTS
cd /path/to/pynets
bun test
bun test test/interpret_ta.test.ts
bun run typecheck

# Python oracle (sister checkout)
cd /path/to/pynescript
python -c "from pynescript.runtime import Runtime; ..."

Use /pynets-parity when adding or fixing builtins. Use /pynets-generate when touching grammar output.

What to compare

FieldRule
plots / seriesEqual length; null ↔ Python None; finite numbers match
eventsKind, direction, bar, id — same contract as strategy events
error_kindSame class of failure (parse vs runtime)
TradingView screenshotsOut of scope as an oracle

na encoding: Python interpret uses None; JSON / TS uses null; Python Numba uses nan. Compare after normalizing non-finite → na.

Internals

PathRole
test/interpret_*.test.tsFocused interpret cases
test/compile_*.test.tsJS emit vs interpret
test/helpers/first_party.tsFirst-party fixtures (live in PYNE)
PYNE src/pynescript/ast/evaluator/builtins/Handler SoT
PYNE tests/test_first_party_ta_goldens.pyPython goldens

Do not treat historical pine-worker/test/parity/ JSON as the PyneTS harness. That tree lives in the leftover TypeScript Worker sister (hoox-sh/pine-worker), not here.

This PYNE pynets/ pin (v0.2.0) includes interpret tests and compile-vs-interpret cases (test/compile_*.test.ts). Python Runtime remains the oracle.

Invariants & edge cases

  1. Python wins ties. If TS and Python disagree, fix TS (unless Python is proven wrong — then fix both + tests).
  2. Do not "improve" semantics. Port na, lookback, and call-site keys as Python implements them.
  3. Same-symbol request.security may passthrough; foreign without data is na on both sides.
  4. Compile-vs-interpret inside PyneTS can pass while TS-vs-Python still fails — check both.
  5. First-party fixtures live in PYNE; do not copy corpora into hoox-sh/pyne.

Worked examples

Minimal Python vs TS

Python:

from pynescript.runtime import Runtime

src = 'indicator("t")\nplot(close[1])'
bars = [{"close": 10}, {"close": 20}]
print(Runtime(symbol="TEST").run(src, bars))

TypeScript:

import { Runtime } from "@hoox-sh/pynets";

const src = 'indicator("t")\nplot(close[1])';
const bars = [{ close: 10 }, { close: 20 }];
console.log(new Runtime("TEST").run(src, bars));

Last-bar plot should be 10 on both.

Adding a builtin

  1. Read src/pynescript/ast/evaluator/builtins/… (Python).
  2. Port into src/runtime/ta.ts / math.ts / … and evalCall in interpret.ts.
  3. Add test/interpret_<area>.test.ts.
  4. If PYNE is present, compare Runtime.run plots on the same bars.
  5. bun test and bun run typecheck.

Failure modes

SymptomCauseFix
Off-by-one vs PythonLookback / bar_indexMatch PineSeries to Python
null vs 0na collapsedKeep null; do not coerce
Foreign security equals chartInvented barsReturn na
Compile matches interpret, both wrongShared host bugFix interpret first (Python SoT)
Copied sources into PYNESubmodule rulePYNE consumes pynets/ only

See also