Skip to content

Troubleshooting

Symptom → cause → fix. Use this page when something's wrong and you need to figure out which doc to read next.

First, run the health check

qkt status --deep

Single-screen summary of daemon, control plane, every deployed strategy. Exits 0 when everything is healthy; 1 with a list of issues when anything is wrong. The output below is the fastest way to know which section of this page to read.

qkt: HEALTHY

qkt 0.28.9 (424d5d9) built 2026-05-25T21:08:37Z

DAEMON       running (uptime 12h5m)
CONTROL      reachable
STRATEGIES
  alpha                running, 14 trades, up 12h5m
  beta                 running, 3 trades, up 12h5m

When unhealthy, the issues land on stderr — pipe to tee or your alert channel:

qkt status --deep || echo "qkt is unhealthy — check logs"

The flowchart

┌────────────────────────────────────────────────────────────────────┐
│ Is the daemon running?                                             │
│   qkt list  → should print a table                                 │
│   No?  →  see "Daemon won't start"                                 │
└────────────────────────────────────────────────────────────────────┘
                              ↓ yes
┌────────────────────────────────────────────────────────────────────┐
│ Is the strategy in the table?                                      │
│   No?  →  see "qkt deploy fails"                                   │
└────────────────────────────────────────────────────────────────────┘
                              ↓ yes
┌────────────────────────────────────────────────────────────────────┐
│ Is the state column "running" / "active"?                          │
│   No?  →  see "Strategy stuck in a non-running state"              │
└────────────────────────────────────────────────────────────────────┘
                              ↓ yes
┌────────────────────────────────────────────────────────────────────┐
│ Are trades happening?                                              │
│   No?  →  see "No trades firing"                                   │
└────────────────────────────────────────────────────────────────────┘
                              ↓ yes
┌────────────────────────────────────────────────────────────────────┐
│ Trades happening, results unexpected?                              │
│   →  see "Trades not as expected"                                  │
└────────────────────────────────────────────────────────────────────┘

Daemon won't start

Symptom Likely cause Fix
qkt: command not found PATH not set export PATH="$PWD/build/install/qkt/bin:$PATH"
Address already in use on startup Previous daemon didn't shut down cleanly qkt daemon stop then restart, or check for orphaned qkt processes
Could not find qkt.config.yaml Working directory wrong cd to the directory containing the config or pass --config /path/to/file
MT5 gateway connection refused (live) Gateway container not healthy docker compose ps; if gateway is unhealthy, VNC at :3000 and log in
observability bind failed The selected ephemeral loopback port became unavailable Restart the affected deployment and use qkt list to discover its new port

qkt deploy fails

Symptom Likely cause Fix
Parse error at line N:M DSL syntax bug Run qkt parse <file> for the full diagnostic; check DSL reference
unknown broker prefix: FOO The prefix isn't a built-in and isn't in your qkt.config.yaml Add a brokers: entry or use a built-in (BACKTEST, EXNESS, etc.); BYBIT_LINEAR and BYBIT_SPOT are type: gateway entries named bybit_linear / bybit_spot
Unknown indicator: ADX The indicator isn't registered with the DSL Check the indicator catalog; ADX is on the backlog
Daemon not running You forgot to start the daemon qkt daemon & or docker compose up -d
Strategy with name X already exists Already deployed under that name For edits, use qkt resync <file> --as X; for a separate copy, pass --as <newname>

qkt resync fails

Symptom Likely cause Fix
unknown strategy: X No deployed strategy or portfolio has that name Use qkt deploy <file> --as X for the first start, then resync future edits
parse failed The replacement file is invalid Run qkt parse <file> and fix the DSL before retrying
production resync blocked Promotion gates do not approve the replacement hash Promote the replacement through the normal pipeline, or use --waive ... --reason ... only for an operator-approved emergency
reconcile-mismatch Live broker/account state does not match the replacement assumptions Investigate positions and pending orders before using --reconcile=ignore-mismatches

Strategy stuck in a non-running state

State Means Fix
inactive (portfolio child) Regime gate is false Either change market regime or qkt start <parent>/<child> to override
halted Risk engine triggered a halt Restart the daemon to clear stateful halts (qkt resume CLI lands in Phase 25); investigate why first
stopped Operator stopped it qkt deploy ... to redeploy or qkt start <name> for a portfolio child
crashed Unhandled exception Check qkt logs <name> for the stack trace; common causes: broker connectivity, data feed dropout

No trades firing

This is the most common complaint. Six things, in order of how often they happen — see the full debug recipe for the detail.

In order of frequency Quick check
1. Condition never transitioned false → true Add a LOG to the rule body to confirm the WHEN actually evaluates true
2. Risk engine rejected the order qkt logs <name> | grep -i reject
3. Broker rejected the order Same grep; look for venue rejection reasons (symbol not found, insufficient margin, stop too close)
4. Indicators not warm yet qkt status <name> and look for warmup completion
5. Wrong candle window Stream declared EVERY 1m but data is daily-only
6. Wrong broker prefix BACKTEST: in production routes to paper, not your real broker

Trades not as expected

Symptom Likely cause Fix
Trade fired but at the wrong price Slippage on live; ignore on backtest (no slippage model) Add a slippage buffer to your stops, or migrate to a venue with tighter spreads
Strategy double-enters Missing POSITION.<stream> = 0 entry guard Add the guard to your WHEN clause
Strategy never re-enters after exit The condition is now true continuously (not edge-triggered) Most often: CROSSES ABOVE already happened; wait for the next cross. Edge-triggers are correct.
Bracket stop fires immediately Stop too close to entry given current volatility Widen the stop or use ATR-scaled stops
Position sizes look wrong on MT5 Broker minimum lot / lot step violated Check qkt brokers list; MT5 brokers have volumeMin and volumeStep
P&L numbers seem off Confusion between realized and unrealized, or strategy-level vs symbol-level Use qkt status <name> for the breakdown

Live-broker-specific issues

Symptom Likely cause Fix
MT5 connection drops daily Some brokers force re-auth VNC back in and log in again; or build a watchdog
qkt refuses to start: gateway bybit_linear reports another adapter, account or trade mode expected_* settings do not match the gateway's /v1/health Set expected_account_login / expected_trade_mode to what the gateway reports (demo on testnet). Bybit API errors and rate limits are the gateway's: see the Bybit adapter page
Symbol rejected on MT5 (symbol not found) Broker uses a different symbol name Check symbolPolicy in your broker profile — Exness adds m suffix
ERROR ... booking at market ... realized PnL is PROVISIONAL Async-execution venue acknowledged a close with price 0.0 and the closing deal was not in history within ~3 s The trade was booked at the closing-side quote; compare it with the venue's closing deal and correct the realized PnL. See engine close pricing
Position drift between qkt and broker Manual trade on the venue, or magic-number collision qkt's MT5StateRecovery reconciles on next daemon start; or restart

Data / data store issues

Symptom Likely cause Fix
Symbol BTCUSDT not found in backtest Data store empty for that symbol Populate via ./scripts/fetch-dukascopy.sh BTCUSDT <from> <to> (or use data/sample/ with --data-root data/sample)
Backtest finishes instantly with 0 trades Date range outside what's in the store Check data coverage with ls ~/.qkt/data/symbols/<SYMBOL>/
Manifest corrupted error Partial write killed mid-fetch ./gradlew rebuildManifest or delete ~/.qkt/data/symbols/<SYMBOL>/manifest.json and refetch
Different P&L between two runs of the same backtest This shouldn't happen (parity contract). If it does, file an issue — that's a regression of the parity test

Performance issues

Symptom Likely cause Fix
Backtest is slow High-resolution data + long range Use EVERY 5m or EVERY 15m for sweeps; reduce date range
Daemon or MT5 gateway high CPU when idle Polling loops too aggressive Tune tick_poll_interval_ms separately from the position/order poll_interval_ms; both are milliseconds and default to 1000. Keep reconciliation fast enough for pending-fill and OCO detection.
Memory growth over time Position tracker accumulating closed positions Restart daemon nightly; long-running daemons aren't yet stress-tested
JVM startup ~3s This is normal Daemon process amortizes startup over its uptime

Where to get more help