Keel Docs
SDK & CLI

Getting Started with the CLI

Install the Keel CLI, inspect components, compose a strategy, and run a backtest.

Updated October 15, 2026

Install the Keel CLI and run the current compose -> backtest workflow.

See it working: Funding carry in the strategy library shows a full backtest on Hyperliquid perps, net of fees, slippage and funding, with the rules you can fork.

Install

pipx install keel-trade
keel --version
# keel, version <latest>

Requires Python 3.11+. pipx installs the keel CLI in an isolated environment. uv tool install keel-trade also works.

Local discovery

Most component discovery and reference commands work without authentication.

keel components search momentum
keel components search --query "mean reversion oscillator"
keel components describe-batch PriceDataLoader EWMA Crossover ForecastWeightNormalizer
keel components compose-help Crossover
keel help dsl_syntax

Compose a strategy

Create my_strategy.py:

Globals(target_timeframe="1d")

Universe(mode="top_volume", top_n=30, market="perp", resolved=[], resolved_at="")

Execution(rebalance="every_bar")

Pipeline([
    PriceDataLoader(),
    Store("ohlcv_1d"),
    {
        "fast": [EWMA(window=8, min_periods=8)],
        "slow": [EWMA(window=32, min_periods=32)],
    },
    Crossover(),
    VolatilityStandardizer(signal_type="price_points", ohlcv_slot="ohlcv_1d", window="36d", returns="pct"),
    ForecastScaler(avg_abs_target=10.0),
    ForecastCapper(limit=20.0),
    ForecastWeightNormalizer(target_leverage=1.0),
], name="my_momentum")

Globals declares the strategy's clock — daily bars, closing at 00:00 UTC (a bar_offset would move the close) — and it is the only place the timeframe and offset live. PriceDataLoader() follows it: the loader serves 1d bars on that grid itself, so there is no resampler step. Pass an explicit timeframe= only for a branch that needs its own clock (see keel help composition_mechanics).

Validate without saving:

keel strategy compose --source-file my_strategy.py --dry-run --format json

Save it to the platform:

STRATEGY_ID=$(keel strategy compose \
  --source-file my_strategy.py \
  --name my_momentum \
  --format json | jq -r '.strategy_id')

keel strategy compose is the current create/update/validate entry point. Use --dry-run first, then rerun without --dry-run when the source is ready.

Authenticate

Remote tools such as strategy save, backtest, accounts, sharing, and live deployment require authentication.

keel auth login
keel --format json auth whoami
keel status --format json

For CI, SSH, Codespaces, or WSL without browser forwarding:

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

For live-trading scope, use keel auth login --scope live. Controlling a running deployment (keel live control) also requires local arming with keel arm live set --account <account_id>; deploying does not — it is a handoff into the web app.

Run a backtest

BT_ID=$(keel backtest run "$STRATEGY_ID" \
  --start-date 2025-06-01 \
  --format json | jq -r '.run_id')

keel backtest watch "$BT_ID" --format json
keel backtest summarize "$BT_ID" --format json

keel backtest run waits by default for up to about 90 seconds and uses today's UTC date when --end-date is omitted. If the run is still active, pass run_id to keel backtest watch.

Paper trade

A paper run trades a saved strategy forward with simulated fills at live Hyperliquid prices; no real orders are placed and no exchange account is needed. Unlike going live, it completes in band, in one call:

keel paper deploy str_abc123
keel paper control dep_123 --action stop --yes
keel deployments list --capital-class practice

Read it with keel live monitor, like a live run. See Paper trading.

Deploy live

Going live is a handoff into the Keel web app. The command sends no orders and enumerates no accounts — it returns code=handoff_required with an action_url you open to pick or connect the account, review the server-computed sizing, accept the risk, and go live:

keel live deploy str_abc123

The handoff is pollable, so you can watch the human finish without a browser return:

keel live deploy str_abc123 --intent-token <resume-token>
# handoff_state: pending | completed (carries deployment_id) | expired

Monitor and control a deployment:

keel live monitor dep_123 --view overview
keel live monitor dep_123 --view positions
keel live control dep_123 --action pause
keel live control dep_123 --action stop --yes

keel live monitor includes freshness metadata. Use it to distinguish on-demand Hyperliquid position snapshots from backend-recorded portfolio, trade, order, execution, funding, stats, equity, and P&L views.

Output formats

Every outcome command supports --format:

keel components search ROC --format json
keel strategy search --query carry --format table
keel components search ROC --format tsv
keel help dsl_syntax --format human

The CLI auto-detects common agent contexts and prefers structured output. Use KEEL_AGENT_MODE=true to force agent mode or KEEL_AGENT_MODE=false to force human mode.

Exit codes

CodeMeaningWhat to do
0SuccessProceed
1General failureCheck the structured error
2Usage errorFix arguments
3Not foundCheck the id or search first
4Auth failedRun keel auth login
5ConflictInspect strategy status or retry with intent
6Entitlement exceededCheck keel status
7Validation failedFix source, retry dry-run compose

Next steps