Never babysit a 3-hour backtest again. This skill runs a background daemon that monitors your QuantConnect backtests, auto-stops on excessive drawdown, downloads results when done, runs forensic diagnosis, and sends you a system notification.
The poller runs as a nohup background process that survives terminal disconnection. All state is persisted to state.json with file-locking to prevent CLI/poller race conditions.
text
User submits backtest
|
v
[Poller Daemon] (nohup, runs independently)
|
|-- Every 30-180s: check QC API
|-- Track equity & peak equity
|-- Calculate live drawdown
|
|-- If DD > threshold at 20%+ progress:
| |-- Delete backtest (early stop)
| |-- Record result
| \-- Send notification
|
|-- If completed:
| |-- Download orders.csv + result.json
| |-- Run OrderForensics diagnosis
| |-- Generate diagnosis.txt
| |-- Update state.json
| \-- Send macOS notification
|
\-- If no active backtests: exit gracefully
Instead of a fixed 30s interval (360 API calls for a 3-hour backtest), the poller adapts based on progress:
PhaseProgressIntervalRationaleStartup0%, < 2min elapsed30sConfirm backtest actually startedNormal0-30%120sSteady trackingMidgame30-80%180sLow frequency, save API quotaEndgame> 80%60sNearly done, check frequently
Result: ~50 API calls instead of ~360 for a 3-hour backtest.
bash
python3 cli.py submit \
--main-file strategy.py \
--name "MyStrategy_v1" \
--max-dd 40
bash
python3 cli.py status
Shows a table with: name, status, progress %, current equity, live drawdown, elapsed time.
bash
python3 cli.py logs --lines 30
bash
python3 cli.py results --name "MyStrategy_v1" --full
bash
python3 cli.py start-poller
python3 cli.py stop-poller
bash
python3 cli.py clear
All state is stored in state.json:
json
{
"poller_pid": 12345,
"poller_running": true,
"poller_started": "2026-03-17T10:00:00",
"backtests": [
{
"backtest_id": "abc123",
"name": "MyStrategy_v1",
"status": "running",
"progress": 0.45,
"peak_equity": 12500,
"current_equity": 11200,
"live_drawdown": 0.104,
"max_dd_threshold": 0.40,
"auto_download": true,
"auto_diagnose": true
}
]
}
File-locking ( fcntl.flock) prevents race conditions between the CLI and the poller daemon writing to the same file.
When a backtest completes, the poller automatically:
orders.csv and result.json to results/<name>/OrderForensics.full_diagnosis() to generate diagnosis.txtOn macOS, the poller sends a system notification via osascript when a backtest finishes.
The daemon handles SIGTERM and SIGINT for clean exit. It clears its PID from state.json only if the PID still matches (prevents stale cleanup from a different process).
state.json while the poller is running. Use the CLI commands ( submit, clear) to modify state. The file uses fcntl.flock locking — manual edits bypass the lock and can corrupt state.results/ while the poller is actively downloading. Wait for the "completed" status.QC_USER_ID, QC_API_TOKEN, and QC_PROJECT_ID must be set before running any command. The skill will fail with a clear error if they are missing.