Research & records
Notebooks
Not every research question deserves a full strategy. Notebooks let you run free-form Python — parameter sweeps, feature studies, quick hypothesis checks — right inside your workspace, with a research backtest call and the full scientific stack available.
How notebook runs work
Create a .ipynb or .py file in your workspace, open it,
and press Run Notebook. Three things to know about the execution
model:
- Runs are top-to-bottom. The saved file executes from the first cell to the last in one pass — there is no long-lived interactive kernel or per-cell execute. This keeps every notebook result reproducible: what ran is exactly what was saved, in order.
- It runs in the same isolated environment as strategies — no network, the same import rules, with time and memory limits.
- Results land in the panels. Printed output appears in the Outputs panel as plain text, cell by cell, with a summary line like “12 of 12 cell(s) ran · 3 output file(s)”. Files your notebook writes are listed under Artifacts. The run itself appears in the run library like any other.
The research backtest call
The headline tool inside notebooks is platform_sdk.research.backtest —
a fast, idealized backtest you can call in a loop:
from platform_sdk import research
result = research.backtest(
"workspace", # this workspace's own strategy
{"start": "2026-01-05", "end": "2026-02-27"},
params={"stop_ticks": 10, "target_r": 2.5}, # optional overrides
symbol="ES", # optional; defaults sensibly
)
print(result["sharpe"], result["expectancy_R"], result["n_trades"])
-
What you can run: the workspace's own strategy
(
"workspace"), a strategy class defined right in the notebook, or a registered template with parameters. - What you get back: a plain dictionary of summary statistics (Sharpe, expectancy, trade counts and friends) plus warnings — data, not live objects, so it's easy to collect into a DataFrame and plot.
- Parameters are validated against the strategy's declared parameter schema; anything you don't override keeps its default.
Research calls are idealized — on purpose
Every result is labeled with its fill model: idealized. Notebook backtests are for exploring — mapping a parameter landscape, checking whether an idea is worth engineering. The graded, conservative verdict still only comes from a real Backtest run. Treat notebook numbers as a compass, not a scorecard. Two guardrails are built in: windows must lie inside the data access your run declared, and reserved holdout windows are refused outright — held-out data stays untouched until a real evaluation spends it.
The limits, and what hitting them looks like
| Limit | Behavior when you hit it |
|---|---|
| Wall-clock time (generous — tens of minutes) | The run ends with status timed out — never a silent hang. Split long sweeps into smaller runs. |
| Memory (several GB) | The run is stopped and the run page shows the reason. |
| Output files (200 files / 100 MB per run) | Extra files are skipped, with a visible count in the Outputs summary — e.g. “· 4 skipped by the size cap”. |
| Research invocations (very high, but bounded) | A hard ceiling on research.backtest calls per run keeps
runaway loops from consuming your compute allowance. |
| Network | None, ever. Network-touching imports are flagged in the editor and refused at run time. |
If a cell fails, the Outputs panel names the failing cell and its error type, and the run page carries the full error detail.
Patterns that work well
-
Parameter sweeps: loop
research.backtestover a grid, collect the stat dicts, and print (or write to a CSV artifact) a ranked table. Look for plateaus of good parameters, not single sharp peaks — peaks are usually overfitting. - Feature studies: pull features through the same SDK your strategy uses and test whether a relationship exists at all before building entry logic around it.
- Pre-flight checks: before an expensive graded backtest, sanity- check trade counts and expectancy over the window so the credit spend is informed.