Write Workflow
This workflow runs the full backtest loop: create a strategy, push your Docker image as a version, then configure, run, and read a backtest against it.
Overview
The write workflow follows these steps:
- Create a strategy - Set up a named container for your trading logic
- Prepare your Dockerfile - Ensure your strategy builds for the target platform
- Upload a version - Build and push your Docker image to the platform
- Write a scenario configuration - Describe the market data and window to test
- Run the backtest - Kick off the run with
scenario create - Read the results - Pull the headline metrics (return, Sharpe, drawdown)
Prerequisites
Before starting, ensure you have:
- The Tektii CLI installed (Installation)
- Your API key configured (Authentication)
- Docker installed and running
- A Dockerfile for your strategy
Step 1: Create a Strategy
If you don't have a strategy yet, create one:
tektii strategy create --name "my-strategy"
This displays the newly created strategy as a field/value table:
✓ Strategy created successfully! ┌──────────────┬──────────────────────────────┐ │ Field │ Value │ ├──────────────┼──────────────────────────────┤ │ Strategy ID │ strat_abc123... │ │ Name │ my-strategy │ │ Owner ID │ user_... │ │ Created By │ user_... │ │ Created At │ 2024-01-15T10:30:00Z │ │ Updated At │ 2024-01-15T10:30:00Z │ └──────────────┴──────────────────────────────┘
Note the strategy ID (strat_abc123...) - you'll need it for the next step.
If You Already Have a Strategy
List your existing strategies to find the ID:
tektii strategy list
Step 2: Prepare Your Dockerfile
If you just want to see the platform running, skip Steps 2–3 and create a version from a built-in template instead:
tektii version upload strat_abc123 --template ma-crossover
Available templates: ma-crossover, rsi-momentum. You can upload your own Docker-built version later.
Your strategy needs a Dockerfile that builds for the linux/amd64 platform. This is required by the Tektii engine.
Example Dockerfile
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "main.py"]
Platform Requirements
Your Docker image must target linux/amd64. Images built for other platforms (like darwin/arm64 on Apple Silicon) will not work.
Step 3: Upload a Version
Navigate to your strategy repository and run:
cd /path/to/my-strategy tektii version upload strat_abc123
The CLI will:
- Validate inputs (including that your Dockerfile exists)
- Auto-detect your Git SHA (or generate a timestamp fallback)
- Create a version entry in the API
- Build the Docker image
- Verify the built image targets
linux/amd64 - Push the image to the registry
Custom Paths
If your Dockerfile isn't in the default location, specify custom paths:
tektii version upload strat_abc123 \ --dockerfile ./docker/Dockerfile.prod \ --context ./src
Flags
| Flag | Default | Description |
|---|---|---|
--dockerfile <PATH> | ./Dockerfile | Path to your Dockerfile |
--context <PATH> | . | Docker build context directory |
--git-sha <SHA> | Auto-detected | Git commit SHA for this version |
--parent <VERSION_ID> | - | Parent version ID when branching from an existing version |
--template <TEMPLATE> | - | Create the version from a platform template (ma-crossover, rsi-momentum) and skip the Docker build |
Git SHA Detection
The CLI automatically detects your current Git commit SHA. If you're not in a Git repository, it generates a timestamp-based identifier like ts-1234567890.
To specify a SHA manually:
tektii version upload strat_abc123 --git-sha abc1234def
Version provenance & branching
Each version records two things that tie it back to your work:
- Git SHA — the traceability link back to your source. Tektii stores the built image and the commit SHA, not your source code. To see what changed between two versions, run
git diff <shaA> <shaB>in your own repository. - Parent version — lineage.
--parentrecords which version this one descends from, organising your experiments as a branching tree. You can branch a new experiment from any version, not just the latest — point--parentat the version you want to fork from.
Apple Silicon (M1/M2/M3) Users
If you're on an Apple Silicon Mac, Docker builds natively target darwin/arm64, which the Tektii engine cannot run. You have two options:
Option 1: Enable Rosetta in Docker Desktop (Recommended)
- Open Docker Desktop
- Go to Settings > General
- Enable "Use Rosetta for x86/amd64 emulation"
- Restart Docker Desktop
Option 2: Use Docker Buildx
Create a buildx builder that can cross-compile:
# Create and use a buildx builder docker buildx create --use # Build with explicit platform docker buildx build --platform linux/amd64 -t my-image .
Complete Example
Here's the full workflow from start to finish:
# Step 1: Create a strategy (if you don't have one) tektii strategy create --name "momentum-v1" # Note: Save the strategy ID from the output # Step 2: Navigate to your strategy code cd /path/to/momentum-strategy # Step 3: Verify Dockerfile exists ls Dockerfile # Step 4: Upload the version tektii version upload strat_abc123 # The CLI will build and push your Docker image # On success, you'll see the new version ID
Example Output
Validating inputs... → Detected version: abc1234 Creating version in API... ✓ Created version: ver_xyz789 Connecting to Docker... Building image ... Verifying image platform... Pushing image to ... ✓ Version uploaded successfully! Version ID: ver_xyz789 Git SHA: abc1234 Image: ... Use this version ID when creating scenarios
Verify Your Upload
List versions for your strategy to confirm the upload:
tektii version list strat_abc123
Get details for a specific version:
tektii version get strat_abc123 ver_xyz789
Configure & run a backtest
Uploading a version doesn't run anything on its own — it just makes your strategy available. To actually test it, you run a backtest scenario: you describe what market data to feed the strategy and over what window, the platform replays that data through your image, and you read the results.
Step 4: Write a scenario configuration
A scenario is defined by a JSON configuration file. tektii scenario create reads this file with --config:
{
"strategyVersionId": "ver_xyz789",
"subscriptions": [
{ "instrument": "C:BTCUSD", "events": ["candle_1m"] }
],
"startTime": "2024-01-01T00:00:00Z",
"endTime": "2024-04-01T00:00:00Z",
"initialCapital": 100000,
"positionMode": "netting"
}
| Field | Required | Description |
|---|---|---|
strategyVersionId | Yes | The version to run — the ver_... ID from your upload. |
subscriptions | Yes | 1–50 market-data subscriptions (see below). |
startTime | Yes | Window start, as an RFC 3339 / ISO 8601 timestamp (e.g. 2024-01-01T00:00:00Z). |
endTime | Yes | Window end, RFC 3339. Must be after startTime; the end is exclusive. |
initialCapital | No | Starting capital. Defaults to 100,000; valid range 1–100,000,000. |
positionMode | No | netting (default) aggregates all trades on a symbol into one net position; hedging tracks each trade as its own position. |
The instrument field takes a platform symbol like C:BTCUSD (crypto) or F:EURUSD (forex). Browse Available Instruments for the full list and each symbol's available date range — and note it's the symbol value, not the hyphenated dataSymbol, that goes in a config.
Subscriptions
Each subscription pairs one instrument with the events you want delivered to your strategy:
{ "instrument": "C:BTCUSD", "events": ["candle_1m", "candle_1h"] }
Valid events are candle bars — candle_<timeframe>, where <timeframe> is one of 1m, 2m, 5m, 10m, 15m, 30m, 1h, 2h, 4h, 12h, 1d, 1w — plus the lifecycle events order_update, position_update, account_update, and trade_update.
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.
Two independent caps apply to every run: how far back your startTime can reach, and how long a single window can span (on Sandbox the max backtest length is 180 days — longer windows are rejected before the run starts). Size the window against Plan Limits before you launch.
Step 5: Run the backtest
Pass the config to scenario create. Creating the scenario starts the run:
tektii scenario create strat_abc123 --config ./backtest-config.json
The command returns a scenario ID with an initial state of PENDING. The run then moves through RUNNING to COMPLETE (or FAILED / CANCELLED).
To run the same window again later, save it once with tektii config create --name "<name>" --file ./backtest-config.json and reuse it. See the commands reference.
Step 6: Read the results
Poll the scenario until it completes, then read its headline metrics with scenario get:
tektii scenario get strat_abc123 scen_def456
That prints a summary table in your terminal. For a machine-readable object, add the global --output json flag:
tektii --output json scenario get strat_abc123 scen_def456
For a completed scenario, the response carries the top-line performance fields:
{
"data": {
"scenarioId": "scen_def456",
"state": "COMPLETE",
"totalReturn": 12.45,
"sharpeRatio": 1.32,
"maxDrawdownPct": 8.10,
"totalTrades": 142,
"winRatePct": 54.2
}
}
totalReturn, maxDrawdownPct, and winRatePct are percentages (e.g. 12.45 = 12.45%). sharpeRatio and the other risk metrics appear only once a completed run has enough data to compute them.
For the full equity curve, the per-trade log, and the other downloadable result types, continue to the Read Workflow.
A scenario configuration controls the market data and window — not your strategy's parameters. Today, strategy parameters (symbol, indicator windows, stop-loss / take-profit, and so on) are read only from environment variables baked into your Docker image with ENV. To change a parameter, set it via ENV in your Dockerfile and upload a new version — each version is immutable, so a new parameter set means a new version. Per-run parameters (varying parameters per scenario without rebuilding the image) are planned but not yet available.
Common Issues
Docker Not Running
Error: Docker not running
Solution: Start Docker Desktop or the Docker daemon.
Platform Mismatch
Error: Image platform mismatch (expected linux/amd64, got darwin/arm64)
Solution: See the Apple Silicon section above.
Git SHA Not Detected
Warning: Failed to detect git SHA, using timestamp fallback
This is not an error. If you're not in a Git repository, the CLI uses a timestamp-based identifier. To specify a SHA manually, use --git-sha.
Dockerfile Not Found
Error: Dockerfile not found at ./Dockerfile
Solution: Use --dockerfile to specify the correct path:
tektii version upload strat_abc123 --dockerfile ./docker/Dockerfile
Next Steps
- Read Workflow - Download backtest results
- Troubleshooting - More common errors and fixes