Skip to main content

English | Русский

quant-harness

An honest backtest framework. Its job is not to "find a profitable strategy" — it is to make sure you cannot fool yourself into believing you found one. It issues a mechanical PASS | KILL verdict that cannot be spun as a success after the fact.

Most backtests lie by default: train and evaluate on the same data, look-ahead on the bar's close, costs "added later", and — the big one — a silent search across hundreds of configurations, with only the best one shown. quant-harness closes every one of those holes structurally.

import numpy as np, pandas as pd
from harness import run_cpcv_returns, Thresholds, CPCVConfig

# 6 configs x 900 bars of pure noise -> the judge MUST return KILL
R = np.random.default_rng(0).normal(0.0, 0.01, (6, 900))
T = np.zeros_like(R); T[:, ::3] = 1                       # turnover every 3 bars
idx = pd.date_range("2024-01-01", periods=900, freq="1D", tz="UTC")
rep = run_cpcv_returns(R, T, idx, [{"c": i} for i in range(6)],
                       CPCVConfig(n_groups=10, k_test=2), Thresholds())
print(rep["verdict"])   # -> "KILL"

Who this is for

Allocators, prop desks, bot marketplaces, and AI-agent builders who need an independent, mechanical verdict before capital is committed to a strategy — whether the strategy comes from a human researcher or is generated by an LLM agent. Point it at a returns series (yours, a vendor's, or a counterparty's) and get a pre-registered PASS/KILL you did not tune after seeing the answer, either as a CLI/library call or as a hosted API an agent can call directly.

What this is not

Not a signal generator, not a source of alpha, not investment advice, and not a promise of returns. It answers one narrow question: is this edge visible on this data, after realistic costs and a correction for how many configurations were tried, at the pre-registered thresholds? A KILL means "not visible here" — not "no profit exists anywhere." A PASS is not a recommendation to deploy capital.

What it guarantees (the guardrails)

Guardrail How it's implemented File
No look-ahead bar t position = signal t−1 (held = target_pos.shift(1)) harness/backtest.py
Honest OOS rolling/anchored walk-forward and Combinatorial Purged CV with purge+embargo; you only trust the concatenation of untouched test windows harness/walk_forward.py
Realistic costs taker fee + slippage on every turnover, funding as a periodic cash flow harness/backtest.py
Multiplicity correction Deflated Sharpe deflates the best Sharpe by the number of configurations tried N; PBO catches overfitting of the search itself harness/deflated_sharpe.py, harness/pbo.py
Mechanical verdict four pre-registered Thresholds -> PASS/KILL (run.py exits 2 on KILL; qh-audit exits 1 on KILL and 2 on invalid input) harness/runner.py, run.py

The judge is measured, not "seems to work"

A verdict is only worth as much as the calibration behind the judge issuing it. So the judge was run across the whole PASS/KILL response surface on synthetic data with known ground truth (harness/calibration.py, report reports/CALIBRATION.md, 200 seeds/cell):

  • False positives on noise (N≥6): 0.0% — the judge does not pass noise.
  • Detection threshold: PASS≥50% at true annualised Sharpe ~2.2, ≥90% at ~3.0 — the honest bar a real strategy has to clear.
  • Costs cut the passing gross edge exactly like real runs (net-kills-gross).
  • DSR deflation: the same true edge, as N grows 1→100 → PASS 82%→16%.
  • Fat tails (Student-t, df=3) and autocorrelation (φ up to 0.6) at zero edge do not break the FPR — the non-normality correction holds.
  • Regime shift: an edge alive for only part of the sample is not extrapolated.

Full write-up: reports/FINDINGS-CALIBRATION.md. Regression guards: tests/test_calibration.py, tests/test_detection_power.py. Complete methodology (the seven ways a backtest lies, and the defence against each): docs/METHODOLOGY.md.

Install

From PyPI (the project's own PEP 503 index on GitHub Pages, https://imadeptus.github.io/quant-harness/simple/, mirrors the same wheels):

pip install quant-harness

From a clone (development):

pip install -e .                 # core: numpy, scipy, pandas, requests
pip install -e ".[fast]"         # + pyarrow (parquet cache for downloaded klines)
pip install -e ".[exchange]"     # + ccxt (extra venue loaders)
pip install -e ".[api]"          # + fastapi, uvicorn, pydantic (hosted verdict API)
pip install -e ".[dev]"          # + pytest, httpx
pip install -e ".[dev,api]"      # everything the full test suite needs (see Quick start)

Python >= 3.11. Current package version: 0.3.0.

Quick start

python examples/quickstart.py    # two demos, no data download
python -m pytest                 # 198 passed with the dev+api extras (154 passed, 44 API tests skipped with dev only)
qh-dsr returns.csv --trials 20   # DSR/PSR from a returns CSV (console utility)
qh-audit --returns returns.csv --trials 20   # PASS/KILL verdict + report (see below)

examples/quickstart.py shows both entry points: (A) the judge's verdict — KILL on noise / PASS on a real edge; (B) the leakage-safe engine on a single instrument (gross→net, turnover, drawdown).

Real data (free public Binance dumps):

python run.py --symbol BTCUSDT --interval 1h \
  --months 2024-01,2024-02,2024-03,2024-04,2024-05,2024-06
python run.py --synthetic --n-synth 5000            # offline sanity check -> KILL
python run_calibration.py --seeds 200                # rebuild the calibration report

Strategy audit (qh-audit)

A CLI (and Python API) that turns a CSV of per-period returns into a mechanical PASS/KILL verdict — the same judge as the hosted API, run locally, no network call:

qh-audit --returns examples/audit_sample_returns.csv --trials 20 \
  --out audit_report.md --json audit_report.json
qh-audit: VERDICT KILL  (audit_sample_returns)
  data       : 730 periods x 4 configs, 2.00 years, 365 periods/year
  trials     : 20 (effective)
  OOS Sharpe : +1.066 median path, +0.461 worst path
  max DD     : 0.114   trades: 730
  PSR 0.9335   DSR 0.5885 (N=20)   PBO 0.6865
  checks     : trades_ok=yes oos_sharpe_ok=yes drawdown_ok=yes dsr_ok=NO
  ASSUMPTION: trades not provided; turnover assumed at 1 trade(s) per bar for every config
  report     : audit_report.md      json       : audit_report.json
  statistical report, not investment advice

Four pre-registered gates (same calibrated thresholds as the judge above): minimum trades (200), minimum OOS Sharpe (0.7), maximum drawdown (0.20), minimum Deflated Sharpe (0.95). PBO is reported as an informational diagnostic and never changes the verdict. Costs (--costs-bps), a cost-sensitivity table at 0x/0.5x/1x/2x, custom CPCV geometry, and threshold overrides are all supported — run qh-audit --help for the full flag list. Exit codes: 0 PASS, 1 KILL, 2 invalid input or unwritable --out/--json, 3 internal error — a crash never exits 1, so it can never be read as a KILL.

Since 0.4.0 the report also carries an evidence budget: the smallest annualized Sharpe this sample could certify against the trials tried, the bars needed at the observed Sharpe, and whether a KILL means "below the noise benchmark" or "not enough data yet" (the same Deflated Sharpe test read backwards; thresholds unchanged).

python examples/audit_quickstart.py   # generates examples/audit_sample_returns.csv (~1s, no network)

Python API: from harness import audit_returns, render_markdown, AuditInputError.

Hosted verdict API

A thin FastAPI service around the exact same judge (harness.audit.audit_returns) — upload a returns matrix over HTTP, get a calibrated verdict back. Built so an AI agent (or a human) can request an independent PASS/KILL without installing anything.

pip install -e ".[api]"
uvicorn api.app:app --host 0.0.0.0 --port 8000 --no-access-log   # or: make api
# interactive docs at http://localhost:8000/docs
docker build -t qh-api:dev .          # or: make docker
docker run --rm -p 8000:8000 --env-file api/.env.example qh-api:dev

GET /healthz is always open. POST /v1/verdict takes a returns matrix (and optional trades, frequency, thresholds, CPCV geometry, and costs) and returns verdict, per-gate checks, metrics (OOS Sharpe, DSR, PBO, drawdown), a cost-sensitivity table, assumptions/warnings, a short Markdown report, and a disclaimer. Optional API-key auth (X-API-Key) and a payment gate (QH_PAYMENT_GATE: noop free / x402 / nowpayments — the paid gates are stubs that issue the payment challenge but do not verify payment; read api/README.md#payments-what-is-real-and-what-is-a-stub before relying on either in production). Full endpoint reference, error codes, and environment variables: api/README.md.

Public API

from harness import (
    run, run_cpcv, run_cpcv_returns, Thresholds,   # judge / verdict
    run_backtest, Costs, max_drawdown,             # engine
    WalkForwardConfig, CPCVConfig,                 # splitters
    deflated_sharpe_ratio, probabilistic_sharpe_ratio, pbo_cscv,  # statistics
    build_signal, grid_for, all_families,          # signal families
    audit_returns, render_markdown, AuditInputError,  # qh-audit
)
  • run(df, grid, wf, costs, thr) — walk-forward judge on a single instrument.
  • run_cpcv(df, grid, cpcv, costs, thr) — CPCV variant, verdict on the median path.
  • run_cpcv_returns(R, trades, index, grid, cpcv, thr) — judge on a ready-made returns matrix (for portfolio/cross-sectional strategies).
  • audit_returns(R, ...) — the same judge behind qh-audit and the hosted API.
  • build_signal(df, params) — momentum / mean_reversion / breakout / carry families.

Layout

quant-harness/
├── pyproject.toml            # package + dependencies + console scripts
├── api/                      # hosted verdict API (FastAPI; not part of the wheel)
├── run.py, run_*.py          # research runners (per-spec runs)
├── run_calibration.py        # judge calibration -> reports/CALIBRATION.{json,md}
├── examples/                 # quickstart.py, audit_quickstart.py — data-free demos
├── harness/
│   ├── __init__.py           # public API
│   ├── backtest.py           # engine: anti-look-ahead, costs, funding, max_drawdown
│   ├── walk_forward.py       # leakage-safe WFA + CPCV (purge/embargo)
│   ├── deflated_sharpe.py    # DSR / PSR (Bailey & López de Prado) + qh-dsr CLI
│   ├── pbo.py                # Probability of Backtest Overfitting (CSCV)
│   ├── runner.py              # assembly: WFA/CPCV -> OOS -> DSR -> verdict
│   ├── audit.py               # qh-audit: CSV in, PASS/KILL report out
│   ├── families.py           # parametric signal families (grid = N)
│   ├── calibration.py        # detection-power study
│   ├── data.py                # Binance loader + synthetic fallback (offline)
│   └── {bybit,hyperliquid,basis,listing,cascade,harvest,paper}.py  # venue/strategy modules
├── reports/                  # JSON+MD reports and FINDINGS-*
└── tests/                    # pytest (198 passed)

What has already been tested with this framework

Full registry: ../RESEARCH-CONCLUSION.md. In short: 10 pre-registered specs across 3 venues (Binance/Bybit/Hyperliquid) — all KILL on public data; no tested mechanism shows a tradeable edge net of realistic costs. The one positive cash flow found was funding-harvest on an inefficient venue — a research result, not a live product: a small live paper track (27 ticks over 42 calendar days) currently sits at −1.5% (about −13%/yr annualised), consistent with the strategy being a tail-risk carry trade with real basis risk, not free money. See ../docs/HARVEST-PATH-A.md for the position, ../CASE-STUDY-EN.md for the write-up of the project as a whole, and ../site/index.html for the public landing page. Calibration (above) shows this is a conclusion about the markets tested, not a judge artefact: the best observed net (0.88) sits well below the measured detection threshold (~2.2).

Boundaries of honesty (what this is and is NOT)

  • It is an edge detector and an anti-self-deception device. It says "not visible on this data with these costs" — not "no profit exists in the universe."
  • It is not an execution engine, a live trader, or a source of alpha.
  • Thresholds are pre-registered. Turning the dials after the fact to manufacture a PASS is exactly the overfitting the whole framework exists to prevent — don't do it.
  • The calibration study uses synthetic, independent configs (the adversarial, worst case for DSR). Real grids have correlated configs, so real deflation is milder.

Relationship to the skill

deflated_sharpe.py and walk_forward.py are the canonical implementations from the quant-backtest-guardrails skill, vendored here for standalone use. The skill holds the methodology; the harness is the working substrate under it.


MIT License.

Metadata

Release files for quant-harness 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for quant-harness 0.4.0
File Size Uploaded
quant_harness-0.4.0.tar.gz 129.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for quant-harness 0.4.0
File Interpreter ABI Platform
quant_harness-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 226.2 kB

Release files / quant_harness-0.4.0.tar.gz

Download URL quant_harness-0.4.0.tar.gz
Size 129.9 kB
Tags Source
SHA-256 checksum
How to use checksums
13e8afee50bee8a44b8cc57d1f7d799d99a5ba9b503bbc8743c80dbc26d1b6d1
BLAKE2b-256 checksum
How to use checksums
23a4e199c55e11a691128cb04007a7079f47f8b95460276ab2a96206e787d93d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / quant_harness-0.4.0-py3-none-any.whl

Download URL quant_harness-0.4.0-py3-none-any.whl
Size 96.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4466777ca134211328656b61ce82280e8cfef138426d5dda30b10f5f9f59a22d
BLAKE2b-256 checksum
How to use checksums
e5e1628e3881b4b0bc6b5350ca6b94d93d252d1e0b2196949e216a4a1771beb6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.1

2 release files

This release

0.4.0 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page