Tektii just went live. We're shipping fixes daily — spot a bug? Let us know

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).

Fields

FieldRequiredTypeNotes
strategyVersionIdYesstringThe version to run (a UUID).
subscriptionsYesarray1–50 instrument subscriptions. Each has its own events. See Subscriptions.
startTimeYesstringInclusive start of the window, as a full ISO-8601 timestamp (e.g. 2024-03-04T13:30:00Z). Any time of day.
endTimeYesstringExclusive end of the window, ISO-8601. Must be after startTime.
positionModeNostringnetting (default) or hedging.
initialCapitalNonumberStarting capital. Default 100000; range 1100000000.
envNoobjectPer-run environment overrides (string→string), layered over the strategy's defaults. Stored in plain text — never put secrets here.
costsNoobjectOptional transaction costs — commission, slippage, funding. Each defaults to zero; omit for a spread-only backtest. See Transaction costs.

Subscriptions

Each entry in subscriptions is one instrument and the events that instrument should receive:

FieldRequiredTypeNotes
instrumentYesstringA platform symbol — F:EURUSD, C:BTCUSD — or a wildcard like *USD or C:BTC*. Use the platform symbol, not the hyphenated data symbol.
eventsYesarray1–100 event patterns this instrument subscribes to.

Valid events:

  • candle_<timeframe> — one of 1m, 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.

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.

FieldRequiredTypeNotes
costs.commissionNoobject{ "model": "zero" } (default) or { "model": "bps_of_notional", "fee_rate_bps": "10" } — basis points of notional charged per side (entry and exit).
costs.slippageNoobjectAdverse price movement on top of the spread, in basis points: base_slippage_bps, a size-impact term, and a cap. Defaults to zero.
costs.fundingNoobjectOvernight 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