Run your Pine Script anywhere.
Paste a v4, v5 or v6 indicator or strategy and get readable Python on the forge API — same values bar-for-bar, a per-line report, and a regression test against your original output. Or hand the whole folder to the agent and let it convert, prove and report on its own. The browser demo below converts the sample scripts; nothing is uploaded.
Run the regression test to compare the Python output with the Pine reference over 500 bars.
Simulated data · illustration only
Hypothetical results on sample data. Trades can be exported for your own analysis.
Or hand the whole folder to it.
One script at a time is the demo above. A library is a job. State one standing instruction and the agent works the queue on its own — converting, then proving each result against the Pine reference — and finishes by telling you, by name, what it could not do.
Every cycle is written to a visible log with what it did, why, and the number it produced. Pause, resume, undo its last change and stop are one click each. Agent docs →
| Script | Clean | Noted | Unsupported | Bars differ |
|---|---|---|---|---|
rsi_divergence.pine | 13 | 1 | 2 | 0 of 306 |
vwap_bands.pine | 8 | 2 | 0 | 0 of 320 |
htf_trend_filter.pine | 9 | 1 | 0 | 0 of 270 |
ema_cross.pine | 14 | 0 | 0 | 0 of 320 |
| Queue finished | 44 | 4 | 2 | 0 in total |
Every line maps to a line, on both sides.
This is the conversion report for rsi_divergence.pine — the sample with a real problem in it, because a converter is only worth anything on the files that do not convert cleanly. 25 source lines read, 27 Python lines written: 13 clean, 1 with a note, 2 unsupported.
- Pine v5 detected. Runtime imports added. Pine 1 → Python 2
- Three
input.intcalls became typed arguments. Pine 3, 4, 5 → Python 5 ta.rsiuses Wilder smoothing seeded on the SMA of the first 14 changes — the Pine convention, not the EMA shortcut. Pine 6 → Python 6ta.pivotlow/ta.pivothigh/ta.valuewhenvectorised; every[lbR]offset became an explicitshift(). Pine 7, 8, 10, 11, 14, 15 → Python 7, 8, 9, 11, 12, 15, 16color.new(color.blue, 0)approximated as#5aa0ffff. Transparency 0 means fully opaque, so this is only a shade difference. Pine 17 → Python 18- label.new() has no equivalent yet. The signal still plots as a triangle; the "Bull" caption is dropped. Values are unaffected. Pine 22, 23 → Python 23
- Both
alertconditionrules becamealert(). Pine 24, 25 → Python 25, 26
306 of 306 bars agree.
Converting is the easy half. The proof is running both implementations over the same bars and counting the differences above floating-point tolerance — with a typical hand port of the same script in the third row, so you can see what "looks right" costs.
| Implementation | Bars | Differ | Max Δ | Signals | Off |
|---|---|---|---|---|---|
| Pine reference | 306 | — | — | 6 | — |
| IndicatorSmith conversion | 306 | 0 | 0 | 6 | 0 |
| Hand port using an EMA instead of Wilder smoothing | 306 | 306 | 21.93 | 9 | 3 |
ta.rsi smooths with ta.rma (Wilder, alpha = 1/N). Porting it with a plain EMA (alpha = 2/(N+1)) looks right and reads wrong — the level is systematically off, so overbought and oversold cross on different bars. It also produces 13 bars with no value at all, where Pine has one.Bars, signals and Δ as printed by the Equivalence tab in the demo, on BTCUSD 1D. Costs and fills are not part of this comparison — that is the backtest.
A compiler, not a find-and-replace.
Parse
The script is parsed into an AST using the grammar of the declared //@version. Types are inferred: series vs simple, int vs float, and — in v6 — strict booleans.
Resolve series semantics
History references (close[1]) become shifts, var blocks become vectorised accumulations or explicit stateful loops, na follows the version's rules, and request.security gets an explicit lookahead argument.
Emit & verify
Readable Python on the forge API, a per-line report (translated / approximated / unsupported), and a regression test against your exported reference values.
What converts, what doesn't.
About 1,900 functions across ta, math, str, array, matrix, map, strategy and request are mapped one-to-one. Libraries are resolved through import.
A short list is reported per line as unsupported instead of being silently dropped; unsupported lines become commented # TODO(pine) markers so the rest of the script still runs.
| Category | Coverage |
|---|---|
ta.* | 100 % — indicators, pivots, crosses, valuewhen |
strategy.* | 98 % — entry, exit, close, risk |
request.security / security_lower_tf | 100 % (explicit lookahead) |
plot · plotshape · fill · hline · bgcolor | 100 % |
line · box | 96 % |
label.new | unsupported — signal still plots, caption dropped |
table.* | partial (styling) |
polyline · request.seed | unsupported |
Convert your own scripts, offline.
The installed engine converts any Pine file on your disk and runs the result on your own data. €249 once, 12 months of updates included.