Keel Docs
Getting Started

Your First Backtest (CLI)

Run a backtest end-to-end from the terminal in under 10 minutes — install, authenticate, create, validate, upload, run, fetch results.

Your First Backtest (CLI)

End-to-end walkthrough using only the terminal. Every step shows the actual JSON output and pipes the relevant ID into the next command. By the end you'll have a strategy on the platform, a running backtest, and metrics back in your shell.

See the finished thing first: Verified Keel backtest of a funding-carry strategy — Sharpe 2.17, +79.6% return, -9.7% max drawdown.

Prerequisites

  • Python 3.11+
  • A free Keel account (sign up)
  • jq for piping JSON between commands (optional but recommended)

1. Install

pipx install keel-trade           # or: uv tool install keel-trade
keel --version
# keel, version 0.4.0

2. Authenticate

keel auth login

This opens your default browser, runs OAuth 2.1 + PKCE against app.usekeel.io, and captures the redirect on a temporary local listener. Tokens go to ~/.keel/config.yaml; refresh fires transparently every hour.

For CI / SSH / Codespaces / WSL where CLI and browser aren't on the same machine:

keel auth login --key <token>
# Get a token at https://app.usekeel.io/settings?tab=api-keys

Verify:

keel auth whoami
# {"principal_id": "...", "org_id": "...", "plan": "..."}

3. Create a Strategy from a Template

keel strategy new my_carry --template carry
# Wrote ~/.keel/strategies/my_carry/strategy.py

Open ~/.keel/strategies/my_carry/strategy.py — that's the Keel DSL. It's a funding-carry pipeline: load price + funding, negate the funding sign so the forecast points to the receiving side, vol-standardize, scale, cap, normalize to weights.

4. Validate Locally (No API Call)

keel strategy validate ~/.keel/strategies/my_carry/strategy.py

You'll see "valid": true plus the type flow at each step. Validation runs entirely in-process — no auth needed.

To assess whether the pipeline is ready to backtest:

keel strategy stage ~/.keel/strategies/my_carry/strategy.py
# {"stage": "sized", "backtest_ready": true, ...}

5. Resolve the Universe

The template ships with resolved=[] — the platform doesn't know which symbols to trade yet. Pick the top 30 by volume:

keel universe set ~/.keel/strategies/my_carry/strategy.py \
    --mode top_volume --top-n 30

(keel universe resolve --mode top_volume --top-n 30 shows you the symbol list without writing it back if you want to preview first.)

6. Upload to the Platform, Capture the ID

STRATEGY_ID=$(keel strategy create ~/.keel/strategies/my_carry/strategy.py \
    --format json | jq -r '.strategy_id')
echo "$STRATEGY_ID"
# str_01HX...

--format json is forced here so jq can parse it. In agent mode (Claude Code, Cursor, etc.) JSON is already the default.

7. Start a Backtest

BT_ID=$(keel backtest run "$STRATEGY_ID" \
    --start-date 2025-06-01 --end-date 2026-02-01 \
    --format json | jq -r '.backtest_id')
echo "$BT_ID"
# bt_01HX...

8. Poll Until It's Done

keel backtest status "$BT_ID"
# {"status": "RUNNING", ...}     # check again in a minute
# {"status": "SUCCEEDED", ...}   # ready

Or loop:

until [ "$(keel backtest status "$BT_ID" --format json | jq -r .status)" = "SUCCEEDED" ]; do
    sleep 15
done

9. Read the Results

keel backtest results "$BT_ID" --format json | jq '.metrics'
# {
#   "sharpe_ratio": 1.42,
#   "total_return_pct": 31.5,
#   "max_drawdown_pct": -8.1,
#   "win_rate_pct": 53.2,
#   "total_trades": 412
# }

That's the same shape you see on the app's backtest page. To open the rich view, head to app.usekeel.io and find my_carry in your strategies list.

What's Next?

  • Iterate: edit ~/.keel/strategies/my_carry/strategy.py, then re-run from step 4. To push edits back to the platform: keel strategy checkout "$STRATEGY_ID" then keel strategy push -m "Tweak vol target".
  • Deploy live: see the CLI reference for keel live deploy. Requires an authorized Hyperliquid account (keel accounts list).
  • Agent setup: wire the CLI + MCP server into Claude Code, Cursor, or your own agent via the agent setup guide.