Skip to main content

Checks whether your backtest data is lying to you: survivorship, dead-name coverage, integrity gates for financial price panels.

Project description

backtest-bias

Checks whether your backtest data is lying to you.

Most backtests don't fail loudly. They flatter you quietly, because the data underneath them is missing the stocks that died. This library tests your price panel for that — in one line — and tells you roughly what it costs when it finds it.

The measured numbers this library is built on

These are not estimates. I measured them on real Indian market data and published the write-ups:

  • 23% of the top-500 Indian stocks (as of 2015) are invisible to yfinance today — delisted, merged, suspended. Any backtest built on it runs on survivors only.
  • Survivor-only universes inflated equal-weight returns by +0.8 to +2.5 pp/yr depending on universe vintage — same market, same method, 3x difference. Anyone quoting one number is guessing.
  • On the most widely used Kaggle NSE dataset, index-membership look-ahead added +10% terminal wealth cap-weighted and +43% equal-weighted over 2010-2021. The bias depends on construction.
  • Comparable mid/large-cap universes lose 10-30% of their names over multi-year windows. If your panel lost zero, your panel is the problem.

Install

pip install backtest-bias

30 seconds to a verdict

import pandas as pd
from backtest_bias import check_survivorship

prices = pd.read_csv("my_panel.csv")   # wide (date x symbols) or long (date/symbol/close)
report = check_survivorship(prices)
print(report.summary())
survivorship check: 412 symbols over 9.2y, 0 died in-window (0%)
verdict: SEVERE - 412 names over 9.2y with zero deaths is the survivor-only signature;
comparable universes lose 10%-30% of names over such windows
expect EW returns inflated roughly +0.8-2.5 pp/yr vs an honest universe (measured,
vintage-dependent; see backtest_bias.REFERENCES)

What v0.1 ships

function what it answers
check_survivorship(prices) does my universe contain the stocks that died, or only the winners? Full report with severity and a measured bias estimate
dead_name_ratio(prices) one number: what fraction of my names end before the panel does. 0.0 = pure survivor panel
assert_integrity(prices) CI gate: raise if the panel smells survivor-only, so a silent re-download of bad data fails your pipeline instead of flattering your backtest

Input handling is forgiving: wide panels, long frames, sniffed column names, NaN-padded histories. Anything the library cannot judge honestly, it raises instead of guessing.

Roadmap

  • v0.2 — look-ahead / point-in-time violations: fundamentals dated by period instead of announcement, index membership applied backwards, same-bar signal fills
  • v0.3 — rename-continuity and corporate-action gap detection

Who

I'm Ayan Jain. I build point-in-time Indian equity data and audit backtests and datasets for bias — the measured numbers above come from those audits. If you want this class of check run on your own backtest by a person instead of a library, that's my Bias Check: fixed price, 48h, written verdict.

MIT licensed. Issues and war stories welcome — especially datasets that fooled you.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

backtest_bias-0.1.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

backtest_bias-0.1.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file backtest_bias-0.1.0.tar.gz.

File metadata

  • Download URL: backtest_bias-0.1.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for backtest_bias-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e1863f0a745f4e35673521495e6eea00d2bf5039207090e04ed41ffc8659544e
MD5 f8d6a059e3436966b56840d480a66660
BLAKE2b-256 aaff0e180087d66642cd464358bba88f4383f42842de46fe655df471f9d06b20

See more details on using hashes here.

File details

Details for the file backtest_bias-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: backtest_bias-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for backtest_bias-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 52e0a10dd1f22ed10eaa9c1a25c45b9282d32d3003b6d289573e73ac3ac10707
MD5 8e7eaeb09ddd182d7b9360fed64499f9
BLAKE2b-256 5a809fb2ac74c670e6f46524f8ab620b8c39aa11f9f8643fe0df2f6349888cd2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page