PyneTS parity
How to compare @hoox-sh/pynets Runtime.run plots against Python pynescript.runtime. Python wins ties.
This page
Manuals
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
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
| Field | Rule |
|---|---|
plots / series | Equal length; null ↔ Python None; finite numbers match |
events | Kind, direction, bar, id — same contract as strategy events |
error_kind | Same class of failure (parse vs runtime) |
| TradingView screenshots | Out 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
| Path | Role |
|---|---|
test/interpret_*.test.ts | Focused interpret cases |
test/compile_*.test.ts | JS emit vs interpret |
test/helpers/first_party.ts | First-party fixtures (live in PYNE) |
PYNE src/pynescript/ast/evaluator/builtins/ | Handler SoT |
PYNE tests/test_first_party_ta_goldens.py | Python 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
- Python wins ties. If TS and Python disagree, fix TS (unless Python is proven wrong — then fix both + tests).
- Do not "improve" semantics. Port
na, lookback, and call-site keys as Python implements them. - Same-symbol
request.securitymay passthrough; foreign without data isnaon both sides. - Compile-vs-interpret inside PyneTS can pass while TS-vs-Python still fails — check both.
- 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
- Read
src/pynescript/ast/evaluator/builtins/…(Python). - Port into
src/runtime/ta.ts/math.ts/ … andevalCallininterpret.ts. - Add
test/interpret_<area>.test.ts. - If PYNE is present, compare
Runtime.runplots on the same bars. bun testandbun run typecheck.
Failure modes
| Symptom | Cause | Fix |
|---|---|---|
| Off-by-one vs Python | Lookback / bar_index | Match PineSeries to Python |
null vs 0 | na collapsed | Keep null; do not coerce |
| Foreign security equals chart | Invented bars | Return na |
| Compile matches interpret, both wrong | Shared host bug | Fix interpret first (Python SoT) |
| Copied sources into PYNE | Submodule rule | PYNE consumes pynets/ only |