Scenario Configuration
The tektii scenario create command and the POST /v1/strategies/{id}/scenarios API both take a config file: a JSON document describing the subscriptions, the date window, and the run settings for a backtest. This page is the reference for that file.
The config file unlocks two shapes the web wizard deliberately does not author: per-instrument events (each instrument subscribing to its own set of events) and a precise start time (any time of day, not just 00:00 UTC).
The CLI parses this file directly into the API request body, which uses camelCase keys: strategyVersionId, subscriptions, startTime, endTime, positionMode, initialCapital. The MCP tools and the raw public REST surface use snake_case (start_time, position_mode) — but the file you pass to --config is camelCase. Unknown keys are rejected.
Fields
| Field | Required | Type | Notes |
|---|---|---|---|
strategyVersionId | Yes | string | The version to run (a UUID). |
subscriptions | Yes | array | 1–50 instrument subscriptions. Each has its own events. See Subscriptions. |
startTime | Yes | string | Inclusive start of the window, as a full ISO-8601 timestamp (e.g. 2024-03-04T13:30:00Z). Any time of day. |
endTime | Yes | string | Exclusive end of the window, ISO-8601. Must be after startTime. |
positionMode | No | string | netting (default) or hedging. |
initialCapital | No | number | Starting capital. Default 100000; range 1–100000000. |
env | No | object | Per-run environment overrides (string→string), layered over the strategy's defaults. Stored in plain text — never put secrets here. |
costs | No | object | Optional transaction costs — commission, slippage, funding. Each defaults to zero; omit for a spread-only backtest. See Transaction costs. |
startTime/endTime must fall within every subscribed instrument's available data, and within your plan's lookback and duration limits. Check Available Instruments for each symbol's dataStartDate → dataEndDate, and Plan Limits before sizing a long window.
Subscriptions
Each entry in subscriptions is one instrument and the events that instrument should receive:
| Field | Required | Type | Notes |
|---|---|---|---|
instrument | Yes | string | A platform symbol — F:EURUSD, C:BTCUSD — or a wildcard like *USD or C:BTC*. Use the platform symbol, not the hyphenated data symbol. |
events | Yes | array | 1–100 event patterns this instrument subscribes to. |
Valid events:
candle_<timeframe>— one of1m,2m,5m,10m,15m,30m,1h,2h,4h,12h,1d,1w(e.g.candle_1m,candle_1h). Brace/wildcard patterns are accepted:candle_{1,5,15}m,candle_*.order_update,position_update,account_update,trade_update— trading lifecycle events.
quote exists as an event type elsewhere on the platform, but it is not a valid subscription event for a backtest — it loads no market data and selects no broadcast stream. For price data, subscribe to a candle_* timeframe instead. A config that subscribes to quote is rejected.
Per-instrument events
Because events lives inside each subscription, different instruments can subscribe to different event sets in the same run. Here EUR/USD drives the strategy on 1-minute candles while BTC/USD only supplies hourly candles:
{
"strategyVersionId": "b2c3d4e5-f6a7-4b2c-8d3e-4f5a6b7c8d9e",
"subscriptions": [
{
"instrument": "F:EURUSD",
"events": ["candle_1m", "order_update", "position_update"]
},
{
"instrument": "C:BTCUSD",
"events": ["candle_1h"]
}
],
"startTime": "2024-03-04T13:30:00Z",
"endTime": "2024-03-08T21:00:00Z",
"positionMode": "netting",
"initialCapital": 100000
}
Save it and launch a run:
tektii scenario create a1b2c3d4-e5f6-4a1b-9c2d-3e4f5a6b7c8d --config ./scenario-config.json
The same file works as a reusable preset via tektii config create --name "<name>" --file ./scenario-config.json.
Custom start time
startTime is a full timestamp, so a run can begin at any moment — for example at a market open rather than midnight. The window above starts at 13:30 UTC, not 00:00:
"startTime": "2024-03-04T13:30:00Z", "endTime": "2024-03-08T21:00:00Z"
endTime is exclusive: the run includes data up to, but not including, that instant.
Transaction costs
By default a backtest pays only the bid/ask spread. The optional costs object layers on commission, slippage, and funding — each defaults to zero, so omitting costs (or leaving a field at its default) keeps the run spread-only and identical to a run without it.
Unlike the top-level camelCase keys, costs and its nested fields use snake_case on every surface.
| Field | Required | Type | Notes |
|---|---|---|---|
costs.commission | No | object | { "model": "zero" } (default) or { "model": "bps_of_notional", "fee_rate_bps": "10" } — basis points of notional charged per side (entry and exit). |
costs.slippage | No | object | Adverse price movement on top of the spread, in basis points: base_slippage_bps, a size-impact term, and a cap. Defaults to zero. |
costs.funding | No | object | Overnight financing on positions held across the rollover: { "model": "disabled" } (default) or { "model": "daily", "long_rate": "-0.03", "short_rate": "-0.01" }. |
{
"strategyVersionId": "b2c3d4e5-f6a7-4b2c-8d3e-4f5a6b7c8d9e",
"subscriptions": [{ "instrument": "F:EURUSD", "events": ["candle_1m"] }],
"startTime": "2024-03-04T13:30:00Z",
"endTime": "2024-03-08T21:00:00Z",
"costs": {
"commission": { "model": "bps_of_notional", "fee_rate_bps": "10" }
}
}
See Backtest Execution & Costs for how each cost is applied and how gross vs net P&L is reported in results.
What the web wizard leaves out
The Create Scenario wizard in the web app is deliberately the simple path. It applies the same events to every instrument and starts every run at 00:00 UTC on the chosen day. Its Review step points power users here for anything else.
To get per-instrument events or a non-midnight start time, author a config file as shown above and launch it with the CLI or API. The wizard restriction is a UI simplification only — the platform itself supports both shapes natively.
Next steps
- Command Reference — full
scenarioandconfigcommand options - Available Instruments — symbols and their data ranges
- Plan Limits — lookback and duration caps