Skip to content

Latest commit

 

History

64 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

OpenPineScript

An open-source engine that runs Pine Script locally. It compiles .pine source to JavaScript and executes it against your own OHLCV data — no cloud account, no execution quotas, no 500 ms loop timeout.

Requires Node.js 20+.

Status

Pine Script v1 and v2 are implemented and passing 393 tests. That covers the full v2 language, roughly 130 standard-library functions, the strategy broker emulator, multi-timeframe security(), and the real-time tick model.

The //@version annotation selects the language version; a script without one is v1. A script declaring a version that is not implemented is refused rather than run under the wrong rules.

Version State
v1 Implemented — TradingView states v1 and v2 are the same language, and the test suite asserts that over the whole corpus
v2 Implemented
v3 Planned — a five-item delta from v2
v4 Planned — var, while, switch, arrays, drawings, namespace migration
v5 Planned — ta.*/math.* namespaces, matrices, maps, user-defined types, libraries

The plan for v1–v5 lives in dev-docs/: an architecture assessment, a version delta spec sourced from TradingView's migration guides, and a 16-iteration roadmap.

Install

git clone https://github.com/be-thomas/OpenPineScript.git
cd OpenPineScript
npm install

npm install runs generate:parser, which builds the ANTLR parser from grammar/.

Run a script

npm run opsv2 -- <script.pine> --data <data.csv> [flags]
npm run opsv2 -- examples/sma_crossover.pine --data mock_data/AAPL_mock.csv
Compiling: sma_crossover.pine...
Pine Script: v1
Running backtest: 506 bars...
✔ Done.

=== sma_crossover.pine — Summary ===
Bars processed : 506
Plots recorded : 1

REPL

npm run replv2

OpenPineScript REPL

Inspect the generated JavaScript

npm run opsv2 -- examples/sma_crossover.pine --data mock_data/AAPL_mock.csv --show-transpiled
let opsv2_len = ctx.new_var("opsv2_len", 14);
let opsv2_src = ctx.new_var("opsv2_src", opsv2_close);
let opsv2_mySma = ctx.new_var("opsv2_mySma", ctx.call("sma@L4:C8", opsv2_sma, opsv2_src, opsv2_len));
ctx.call("plot@L6:C0", opsv2_plot, opsv2_mySma, { opsv2_color: opsv2_color.opsv2_red });

Every identifier is prefixed to avoid collisions with the sandbox, and every stateful call carries its source location so per-call-site state (indicator lookback buffers, for example) stays independent.

Export results

npm run opsv2 -- strategy.pine --data data.csv --out-dir ./results
results/
├── chart.csv       OHLCV plus one column per plot()
├── trades.csv      entry and exit rows per trade
└── summary.json    performance metrics

Compare against a TradingView export

Point --compare-dir at a folder holding chart_data.csv, trades.csv, and summary.json exported from TradingView:

npm run opsv2 -- strategy.pine --data data.csv \
  --out-dir ./results \
  --compare-dir ./tv_exports
=== Comparison Report ===
Overall: PARTIAL    Tolerance: 0.0001

Chart Data: PASS  (506 rows compared, 0 mismatches)
Trades:     FAIL  (38 tv / 37 opsv2 — 1 discrepancy)
  Trade #42: exit_price_mismatch  tv=45000.5000  opsv2=45001.0000  Δ=0.5
Summary:    PASS  (net profit Δ 0.05%)

Report written: ./results/comparison_report.json

Every flag — --out-chart, --out-trades, --compare-chart, --tolerance, --input, --dry-run — is documented in the CLI Usage Guide.

Tests

npm test

393 tests across 23 files. The suite covers lexer token streams, parser trees, transpiler output, and runtime behaviour.

Two patterns carry most of the weight:

  • Differential testing. tests/v1/ta/naive_ta.ts is an independent naive reimplementation of the TA library. The engine is asserted to match it bar-for-bar over 5000 seeded bars under four different lookback regimes, rather than against hand-picked expected values.
  • The version matrix. conformance/ asserts every language rule at every version, including the versions where it is illegal — so adding a version cannot silently relax an older one.

Repository layout

Path Contents
grammar/ ANTLR lexer and parser grammars (.g4)
lexer/ Token source that turns indentation into block tokens
parser/ Generated ANTLR parser and the parse entry point
transpiler/ Parse tree to JavaScript
runtime/ Execution context, series storage, standard library, broker emulator
repl/ Interactive REPL
mock_run/ CLI runner
utils/ Shared helpers and the TradingView comparison engine
tests/ Test suites
validation/ Real-world Pine scripts used for parity checking
spec/ Language specification and per-version progress checklists
dev-docs/ Development plan for v1–v5
mock_data/ Sample OHLCV data

Deliberate deviations from TradingView

TradingView enforces limits that protect a shared cloud tier. Running locally, those limits are not parity — they are rationing. The engine skips them:

  • No 500 ms loop timeout and no cumulative execution cap. A genuine infinite loop will hang the process.
  • No plot limit. TradingView allows 64.
  • No max_bars_back window. Lookback depth is bounded by available memory.
  • No script size limits.

Semantic rules — the ones that would silently change your numbers — are enforced, not skipped. Every skipped item is recorded with its blast radius in dev-docs/04-skipped-restrictions.md.

Contributing

The core is developed by a single author and pull requests are not being accepted, but bug reports and feature requests drive the roadmap. See CONTRIBUTING.md, the Code of Conduct, and the Security Policy.

License

GNU GPL-3.0. See LICENSE.

About

OpenPineScript is an open-source runtime for Pine Script code, providing a free and extensible platform to execute and experiment with Pine Script in diverse environments. Built with Typescript, it enables developers to work with Pine Script code without proprietary restrictions.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

55 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages