Backtests
Use the Test button (Running code) in the QuantCraft IDE to open Run backtest. There you set symbols, price data, optional fundamentals, the simulation window, account defaults, and (if your script uses them) input parameters for a single run. The engine invokes your strategy lifecycle callbacks. Results appear in Test results; OHLCV explains bar shapes.
The dialog explains which price source applies at the top (a short banner). At the top of the modal body you can Load settings… or Save settings… to reuse a run preset (.qcs). Everything else is grouped so you can work top‑to‑bottom before you click Continue to start the backtest.
Price source (Alpaca vs. B2)
You do not pick the price vendor manually — the app chooses it from your active trading account:
- Alpaca is used when the active account has API key + secret, or an OAuth-linked Alpaca connection with a valid link id. Intraday and daily-style Alpaca timeframes are available.
- QuantCraft B2 is used when the active account has no Alpaca credentials that qualify. In that case only daily (
d), weekly (w), and monthly (m) OHLCV timeframes are available.
If B2 is selected, you must be signed in to QuantCraft so a session token can be sent for B2 OHLCV (and for fundamentals when enabled).
Bar timeframe and asset class (Alpaca only)
When the price source is Alpaca, you can set:
| Field | Purpose |
|---|---|
| Bar timeframe | Candle resolution for the run — e.g. 1 Day, 1 Hour, 4 Hour, 1 Week, and several minute bars (1 / 5 / 15 / 30 min). |
| Asset class | US equity or Crypto — drives which symbol list you search and how Alpaca fetches data. |
| Min bars (optional) | If set, after the date range is applied the engine keeps only the N most recent bars. Leave empty to use the full range implied by your start and end dates. |
When the price source is B2, you only choose B2 timeframe: Daily, Weekly, or Monthly (no intraday on B2).
Symbols
Use Symbols to choose one or more tickers for the run:
- With Alpaca, the list comes from your Alpaca asset universe (equity vs. crypto follows Asset class). You can search and multi-select.
- With B2, the list comes from the same catalog as fundamentals paths on the server.
Rules:
- At least one symbol is required.
- Symbols are normalized to uppercase for the run.
- Valid characters: letters, digits,
.and-(typical for exchange suffixes likeBRK.BorRHM.XETRA).
The first symbol in your selection order is the default clock symbol (primary execution bar) unless your strategy overrides it with a top-level SYMBOL = "..." that matches a loaded ticker.
Fundamentals (optional)
Tick Uses fundamentals when your strategy reads the fundamentals argument in on_bar / on_tick (backtest), or in on_timer on a forward run, or uses fundamentals-aware logic.
When fundamentals are on:
- You must be signed in (QuantCraft token is sent to load B2 fundamentals files).
- Pick one or more fundamentals bundles from the Fundamentals multi-select (paths like
fundamentals/AAPL.json.gz). The dialog shows the normalized path under each selection.
Important: OHLCV symbols and fundamentals symbols are independent. You can backtest RNMBY on Alpaca while loading RHM.XETRA fundamentals — the UI reminds you that in that case you must pass the correct ticker into fundamentals.current(..., symbol="RHM.XETRA") (or equivalent) in code.
When multiple fundamentals bundles are selected, the engine builds a per-path map. The primary fundamentals bundle used for bar-aligned snapshots defaults to the first OHLCV symbol in your symbol list unless the engine applies another rule; use explicit symbol= on fundamentals.current / get_data_with_offset when you need a specific bundle.
Fama-French factors (optional)
Tick Include Fama-French factors (global) when your strategy reads global monthly factor returns via fama_french.qc. See Fama-French factors for the full API.
When factors are on:
- You must have a Premium subscription and be signed in (QuantCraft token is sent with the run).
- The checkbox is on by default for Premium users in the Run backtest modal. Uncheck to skip factor data for that run.
- OHLCV symbols, fundamentals bundles, and Fama-French factors are independent — enable any combination you need.
- There is no
factors=callback argument — importquantcraft.fama_frenchand readfama_french.qcinside callbacks (on_init,on_bar,on_tick, …).
Simulation window (dates and warmup)
| Field | Purpose |
|---|---|
| Start date | Required. First UTC calendar day included in the execution window (YYYY-MM-DD). |
| End date | Required. Last UTC calendar day included. Must be on or after the start date. |
| Warmup bars (indicators) | Extra bars loaded before the start date (same timeframe as your bars) so moving averages and similar indicators have history. Callbacks still run only between start and end dates. Default is 45; enter 0 to disable extra warmup. |
The Test dialog does not configure timer intervals, so
on_timeris not invoked during historical backtests from the IDE — even if you defineon_timerin your strategy file. Useon_baroron_tickfor bar-aligned or intrabar logic.on_timeris available on forward runs (chart forward test, bulk forward / Quant Cloud) whentimerIntervalMsis set. See Strategy lifecycle.
Account — starting balance and advanced defaults
| Field | Purpose |
|---|---|
| Starting balance | Required. Initial cash for the simulated PaperAccount. |
Under Advanced — stops, targets, risk (optional) you can set defaults passed into the paper account (your strategy must still enforce exits; these configure default distances for open_trade):
- Stop-loss % or Stop-loss $ — not both. Percent can be entered as
2or0.02for 2%. - Take-profit % or Take-profit $ — not both.
- Risk % per trade or Risk fixed $ per trade — not both; used with
position_size_for_riskwhen you size from risk.
Script parameters (single run)
If your strategy imports from quantcraft.inputs import params (legacy from ide.inputs_module import params or from quantcraft.inputs_module import params still works) and references params.NAME, the dialog shows a Script Parameters section with one row per discovered name: Parameter, Type (int / float / str / bool), and Value.
Fill every row before Continue — values are required for each declared parameter. They are sent on the wire as strings and coerced by the engine before your file loads, so params.PERIOD (for example) is already the correct Python type when your module executes.
This doc does not cover parameter optimization (grid or genetic search). Leave the “Optimize script parameters” option unchecked for a normal single backtest.
What happens when you click Continue
The app validates the form (dates, symbols, balance, mutual exclusivity of SL/TP/risk fields, fundamentals if enabled, and script parameter types). On success it starts one backtest with the assembled configuration; progress and logs appear in the Output panel, and structured results open in Test Results.
Quick reference
| Topic | Where it’s set |
|---|---|
| Alpaca vs. B2 prices | Automatic from active account (banner at top of dialog). |
| Timeframe | Bar timeframe (Alpaca) or B2 timeframe (d / w / m only). |
| Asset class | US equity / Crypto (Alpaca only). |
| Truncate to last N bars | Min bars (Alpaca only, optional). |
| What to trade | Symbols (multi-select). |
| Financial statements | Uses fundamentals + Fundamentals multi-select; requires sign-in. |
| Global factor returns | Include Fama-French factors (global); Premium + sign-in — see Fama-French factors. |
| Calendar window | Start date / End date (required). |
| Indicator history before start | Warmup bars. |
on_timer | Not invoked in IDE backtest (no timer setting in dialog) — forward runs only (Strategy lifecycle). |
on_tick | Backtest: four synthetic OHLC ticks per bar (no real tick history). Forward runs: every broker price update — see Strategy lifecycle. |
| Cash and default risk | Starting balance + Advanced SL / TP / risk fields. |
| Tunables in code | Script parameters (params.*), single values per run. |
Tips
- If Alpaca symbols never load, open Trade once or confirm Alpaca connectivity; for B2, confirm you’re signed in and the symbol catalog loaded.
- Warmup only extends loaded history — it does not add trading days outside your date range.
- Do not rely on
on_timerin the IDE backtest dialog — useon_bar/on_tickinstead; timers apply on forward runs whentimerIntervalMsis configured. on_tickin backtest uses synthetic OHLC from each bar (four calls per bar) — not real tick data. Test live tick logic on forward runs (Strategy lifecycle).- Match fundamentals bundles to the tickers you actually read in code when OHLCV and fundamentals tickers differ.
- Use Min bars sparingly — it is easy to accidentally shorten a run more than you intended.
