Python scripts (Pyodide engine)

Choosing Python for a script runs it in an embedded engine under the same sandbox rules as JavaScript. The engine is downloaded once, on a click, and then runs entirely offline.

Senzoukria · Documentation · Updated September 2026


Where to find it

Where
Scripting page → Language → Python, then the "Python engine" strip
Download
Six files, about 16.4 MB in total, fetched once
Included
numpy, as the wheel matching the engine's ABI
Start budget
120 s for the boot; downloading has its own 600 s budget
Script budget
2 s per run, the same as JavaScript

What it does

The language is chosen per script and stored with it. Both languages receive the same data and return the same shapes, so a script ported from one to the other finds its bearings: the bar columns are exposed under their names, the calculation helpers keep the same names, and the output builders map one to one.

The engine's start-up is a first-class state, shown on its own strip, and is never confused with running a script. That distinction matters: the engine takes seconds to boot while a script run has a two-second budget, so folding one into the other would make every correct Python script look like an infinite loop.

Nothing downloads on its own. Installing is a click; automatic start happens only when the files are already present.

Engine states

The Python engine strip, state by state
StateDefaultWhat it changes
Not installedinitialOffers "Install the Python engine" and states the one-off download size.
DownloadingShows a percentage and offers "Cancel the download".
StartingThe engine is booting; scripts wait rather than fail.
Engine readyShows the version and the milliseconds it took to start, and offers "Remove the engine".
Engine unavailableStates that the engine did not start, with the raw message, and offers "Try again". JavaScript scripts are unaffected.
Offline notealwaysOnce installed, the engine runs entirely offline — no script and no data is sent anywhere.

Language mismatches

Pasting a Python script into a draft still set to JavaScript used to produce a syntax error pointing at an arbitrary line, plus advice about console.log to someone writing Python. The page now checks whether the code contradicts the declared language and says so, with a button that switches to the detected one.

The check is deliberately narrow: it only looks for marks that are outright syntax errors in the other language, and it stays silent when a file carries marks of both — a half-translated script has nothing useful to say. Missing a detection only returns you to the old obscure message; inventing one would send you to change a language that was correct.

Limits and pitfalls

  • Switching language does not translate your code: it stays exactly as written and will not run until you rewrite it.
  • The engine files are fetched from the product's own relay, the only remote origin the application's content policy allows.
  • The engine version is pinned and checked against the compiled binary; mixing versions is refused rather than producing unreadable crashes.
  • Backtesting a Python strategy runs the loop on the Python side rather than crossing the language boundary once per bar, and a parity test compares its trades with the JavaScript loop bar for bar. print() goes to the log, prefixed with the current bar.

This page in other languages

Frequently asked questions

Do I need Python installed on my computer?
No. The engine is embedded and downloaded once by the application. It does not use, and does not need, a system Python installation.
Which libraries are available?
The standard library plus numpy, which ships as the wheel matching the engine's ABI. There is no network access from inside the sandbox, so packages cannot be fetched at run time.
Why does my Python script fail with a syntax error on a line that does not exist?
That is the signature of a language mismatch: a wrapper in the other language was appended to your source. Switch the script's language and run again.

Keep reading