Quant Buffet API
Sandbox rules
Allowed imports, the exact builtins you get, blocked calls, and hard runtime limits.
Lab runs execute your code in `backtest/sandbox_runner.py`. The source is parsed with `ast`, stripped of bootstrap boilerplate by lab_sanitize, then exec'd in a restricted namespace. Understanding these limits explains most confusing failures.
Allowed import roots
| Category | Roots |
|---|---|
| Quant Buffet | backtest (data, engine, metrics, templates, universes, lab_sanitize) |
| Numerics | numpy, np, pandas, pd |
| Standard library | math, json, typing, collections, dataclasses, functools, itertools, datetime, re, statistics, decimal |
| Language | __future__ |
The check is on the root module, so from backtest.templates import make_sma_trend and import collections.abc both pass. Anything else fails at validation time with *Import blocked: …*.
Blocked
- Standard-library modules outside the allow-list:
os,sys,pathlib,subprocess,socket,pickle,random,time, … - All third-party packages:
requests,sklearn,scipy,matplotlib,yfinance,statsmodels, … - Direct calls to
eval,exec,compile,open,__import__,input,breakpoint— rejected by the AST walk. async/await/async for/async with— *Async code is not supported in the sandbox.*- Source files larger than 80 KB — *Code too long (max 80KB).*
Builtins you get
| Group | Available |
|---|---|
| Numeric | abs, min, max, sum, round, float, int, bool |
| Sequence | len, range, enumerate, zip, map, filter, sorted |
| Containers | list, dict, set, tuple, str |
| Introspection | isinstance, issubclass, hasattr, type, print |
| Exceptions | Exception, ValueError, TypeError, KeyError, RuntimeError, StopIteration |
Builtins you do NOT get
| Missing | Use instead |
|---|---|
any(...), all(...) | series.any(), series.all(), or sum(1 for … ) > 0 |
reversed(...) | sorted(x, reverse=True) or x[::-1] |
getattr, setattr, vars, globals, locals | Restructure — attribute plumbing is not needed here |
next, iter, frozenset, divmod, pow | Comprehensions, set, // and %, ** |
IndexError, AttributeError, ZeroDivisionError | Catch Exception, or guard the condition instead |
Runtime limits
| Limit | Value | Error when exceeded |
|---|---|---|
| Source size | 80 KB | *Code too long (max 80KB).* |
Symbols in ASSETS | 15 | *Too many symbols (max 15).* |
| Minimum price rows | 30 after load | *Not enough price history for the selected assets/start date.* |
| Minimum equity points | 20 after the run | *Equity curve too short — strategy may never trade.* |
| Equity chart points | 90 (downsampled) | n/a — the full curve still drives the metrics |
| Default start date | 2000-01-01 | n/a |
Source sanitisation
backtest/lab_sanitize.py runs before validation and removes the scaffolding that catalog-generated files carry, so the same file works both as a CLI script and as lab input. It strips:
- everything from
def main(onwards, including the__main__guard; import sys,from pathlib …,ROOT = …, and any line touchingsys.path;- the leading module docstring and
from __future__line; - generator metadata assignments such as
SLUG,LOCALE,TITLE,TEMPLATE,FIDELITY,DATA_SOURCE.