← Back to Skills Marketplace
tltby12341

Backtest Poller

by tltby12341 · GitHub ↗ · v1.0.0 · MIT-0
macoslinux ⚠ suspicious
208
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install backtest-poller
Description
Background daemon that monitors QuantConnect backtests with adaptive polling, real-time equity tracking, drawdown early-stop, auto-download, and auto-diagnos...
README (SKILL.md)

Backtest Poller

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.

When to use

  • After submitting a backtest: "Monitor this backtest in the background"
  • "Start the poller daemon"
  • "Check backtest status"
  • "Show me the poller logs"

Architecture

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.

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

Adaptive Polling Intervals

Instead of a fixed 30s interval (360 API calls for a 3-hour backtest), the poller adapts based on progress:

Phase Progress Interval Rationale
Startup 0%, \x3C 2min elapsed 30s Confirm backtest actually started
Normal 0-30% 120s Steady tracking
Midgame 30-80% 180s Low frequency, save API quota
Endgame > 80% 60s Nearly done, check frequently

Result: ~50 API calls instead of ~360 for a 3-hour backtest.

CLI Commands

Submit a backtest (auto-starts poller)

python3 cli.py submit \
  --main-file strategy.py \
  --name "MyStrategy_v1" \
  --max-dd 40

Check status of all backtests

python3 cli.py status

Shows a table with: name, status, progress %, current equity, live drawdown, elapsed time.

View poller logs

python3 cli.py logs --lines 30

View completed results

python3 cli.py results --name "MyStrategy_v1" --full

Manually start/stop the poller

python3 cli.py start-poller
python3 cli.py stop-poller

Clean up completed records

python3 cli.py clear

State Management

All state is stored in state.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.

Auto-Diagnosis

When a backtest completes, the poller automatically:

  1. Downloads orders.csv and result.json to results/\x3Cname>/
  2. Runs OrderForensics.full_diagnosis() to generate diagnosis.txt
  3. Extracts a summary: order count, option ROI, zero rate, windfall count

Notifications

On macOS, the poller sends a system notification via osascript when a backtest finishes.

Graceful Shutdown

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).

Rules

  • Never submit more than one backtest at a time. QuantConnect free tier only allows one concurrent backtest per project. Submitting a second will silently queue or fail.
  • Never manually edit 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.
  • Never run multiple poller instances simultaneously. The CLI checks for an existing PID before starting. If you force-start a second poller, both will race on state.json writes.
  • Do not delete files in results/ while the poller is actively downloading. Wait for the "completed" status.
  • Early-stop deletes the backtest permanently from QuantConnect. There is no "pause" API — early-stopped backtests cannot be resumed or recovered.
  • Environment variables 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.
Usage Guidance
This skill appears to do what it says: it will run a local Python daemon that polls QuantConnect, may permanently delete backtests (early-stop), and will store state and downloaded results under state.json, poller.log, and results/. Before installing: 1) Only provide QC_USER_ID, QC_API_TOKEN, and QC_PROJECT_ID if you trust the code—these are live API credentials and the token can be used to delete backtests. 2) Consider creating or using a token with the minimum needed privileges, or test in a throwaway project first. 3) Install dependencies in a virtual environment (pip install -r requirements.txt) to avoid contaminating system Python. 4) Note the default data paths live in the skill directory but can be overridden with STATE_FILE/LOG_FILE/RESULTS_DIR env vars — set them to locations you control. 5) To stop the daemon, use the provided CLI stop-poller command or kill the PID recorded in state.json. If you want additional assurance, review the included code files yourself or run in an isolated environment (container/VM).
Capability Analysis
Type: OpenClaw Skill Name: backtest-poller Version: 1.0.0 The skill implements a background daemon for QuantConnect backtest monitoring but contains a shell injection vulnerability in 'poller.py' via 'os.system' when sending macOS notifications using unsanitized backtest names. It also employs dynamic module loading ('__import__') to load optional forensics logic, which could be exploited for arbitrary code execution if a malicious file is placed in the search path. While these features align with the stated purpose of the skill, the high-risk execution patterns and lack of input sanitization pose a security risk to the host environment.
Capability Assessment
Purpose & Capability
Name/description (monitor QuantConnect backtests) matches required env vars (QC_USER_ID, QC_API_TOKEN, QC_PROJECT_ID), required binary (python3), and the code which calls QuantConnect endpoints (read, delete, read orders). The ability to delete backtests and download results is coherent with the stated early-stop and auto-download features.
Instruction Scope
SKILL.md and the CLI/poller code stay within the declared scope: they read/write state.json, poll QC API, optionally delete backtests, download results into results/, run a local diagnosis call, and emit macOS notifications. There are no instructions to read unrelated system files or to send data to third-party endpoints beyond quantconnect.com.
Install Mechanism
No automated install spec is provided (skill is instruction/file-based). Source includes Python scripts and requirements.txt (requests, python-dotenv) which the user must install manually. This is not inherently risky, but users should note dependencies must be installed in their environment before use.
Credentials
Only QuantConnect credentials and optional path env vars (STATE_FILE, LOG_FILE, RESULTS_DIR) are required. The primary credential is QC_API_TOKEN which is appropriate for an API client. The requested env vars are proportional to the functionality; no unrelated secrets are requested.
Persistence & Privilege
The skill does not request always:true or other elevated platform privileges. It runs as a local background process (nohup) and persists state to state.json and results/ under the working directory or locations set via env vars. This behaviour matches the described daemon nature.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install backtest-poller
  3. After installation, invoke the skill by name or use /backtest-poller
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release of backtest-poller. - Monitors QuantConnect backtests in the background with adaptive polling. - Tracks real-time equity, draws down early-stop, auto-downloads results, and runs automated diagnosis. - Persists state to a file with locking for reliability and survives terminal disconnection. - Provides CLI commands for submission, status, logs, poller control, and results. - Sends system notifications on macOS when backtests complete.
Metadata
Slug backtest-poller
Version 1.0.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is Backtest Poller?

Background daemon that monitors QuantConnect backtests with adaptive polling, real-time equity tracking, drawdown early-stop, auto-download, and auto-diagnos... It is an AI Agent Skill for Claude Code / OpenClaw, with 208 downloads so far.

How do I install Backtest Poller?

Run "/install backtest-poller" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Backtest Poller free?

Yes, Backtest Poller is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Backtest Poller support?

Backtest Poller is cross-platform and runs anywhere OpenClaw / Claude Code is available (macos, linux).

Who created Backtest Poller?

It is built and maintained by tltby12341 (@tltby12341); the current version is v1.0.0.

💬 Comments