Skip to main content

QuantRail logo

QuantRail

Every backtest lies a little. QuantRail tells you where.
Data governance · ledger-accurate simulation · research discipline

CI Python 3.11 | 3.12 | 3.13 Apache-2.0 Status: pre-alpha Ruff

繁體中文 · Architecture · Decisions · Contributing

A QuantRail result opens with a trust report listing everything it could not verify

Status: early development (v0.x); APIs will change. Nothing here is investment advice.

Why QuantRail?

Most backtests are easy to make look good and hard to trust:

  • positions are multiplied by adjusted returns, so dividends, splits and settlement are approximated or double-counted;
  • nobody records which data version, licence or availability time a result depended on;
  • the many variants tried before the "winner" are forgotten, so overfitting goes unmeasured.

QuantRail is built around three pillars:

Pillar What you get
Data governance Versioned, hashed datasets with manifests: source, licence, price basis, point-in-time availability, quality checks. "Unknown" is allowed and reported, never hidden.
Ledger-accurate simulation Raw prices plus explicit events (fees, taxes, dividends, splits, settlement). Every day's change in wealth must reconcile.
Research discipline Append-only trial registry, frozen experiment contracts, sealed holdout data, and built-in paired block bootstrap, Holm correction, deflated Sharpe ratio and probability of backtest overfitting.

Quickstart

import tempfile

import numpy as np
import pandas as pd

import quantrail as qr
from quantrail.markets.generic import ProportionalCosts

# Any price table you have: only a date and a close are required.
days = pd.bdate_range("2024-01-01", periods=250)
returns = np.random.default_rng(0).normal(0.0004, 0.01, 250)
prices = pd.DataFrame({"date": days, "close": 100 * np.exp(np.cumsum(returns))})

store = tempfile.mkdtemp()
data = qr.ingest(prices, root=store, dataset_id="my-prices", version="v1", instrument="X:ABC")

asset = qr.Instrument("X:ABC", "X", "equity", "USD")
result = qr.backtest(data, instrument=asset, capital=10_000,
                     costs=ProportionalCosts(commission_rate="0.001"))
print(result.report())

The report starts with what QuantRail could not verify, because nothing was declared:

Trust report:
  [!] SOURCE_UNKNOWN: Data source is not recorded.
  [!] LICENCE_UNKNOWN: Licence is unknown: private research only; ...
  [!] PRICE_BASIS_UNKNOWN: Prices may be raw or adjusted; ...
  [!] ACCOUNTING_APPROXIMATE: Ledger-accurate accounting needs raw prices plus dividend and split events.
  [!] AVAILABILITY_UNVERIFIED: Availability time is not declared; ...
  [!] NO_OPEN_PRICES: No open prices: next-open execution cannot be modelled.
  [!] EXECUTION_NEXT_CLOSE_PROXY: No open prices: orders fill at the next session's close.
  [i] CALENDAR_FROM_PRICES: Sessions are inferred from price dates; ...

Declare provenance (qr.Provenance), price basis and availability (qr.Declaration), add open prices and corporate actions, and the caveats disappear one by one.

Verified to the cent

The engine and the Taiwan equity module were ported from a private research implementation and must reproduce it exactly. On eight years of a Taiwan ETF (1,953 sessions, 16 cash dividends, one 4-for-1 split and a trading suspension), QuantRail matches the daily net asset value of five reference runs with zero difference: buy-and-hold, and three rules that sell (87 sells with securities transaction tax, including runs with a no-trade band and with doubled slippage). Units, cash, receivables, payables, commission, tax and slippage all match.

That reference was itself checked independently: its buy-and-hold ledger was reconciled against a total-return index, with every difference explained by cash drag, costs and timing, and against a second data source. The data is not distributed; tests/test_reference_parity.py reruns the comparison when you point it at your own copy.

Markets

Module Status Covered Not yet
markets.tw_equity: Taiwan equities and ETFs Beta T+2 settlement, commission with minimum fee, securities transaction tax as a sourced, effective-dated rule, cash dividends, splits, odd lots and board lots Daily price limits, stock dividends (#15)
markets.generic: any market Available Proportional commission with minimum, sell tax Market-specific rules
Crypto Planned (#5) Spot, then perpetuals

QuantRail ships no market data. You bring your own, or fetch it with your own credentials from sources whose terms allow it. There is no broker connectivity or live trading in this repository.

Architecture

Animated flow: your data passes through data governance and the engine into a result with a trust report; accounting and market modules light up as they support the engine, research and stats light up as they judge the result; core types underlie everything

Read the architecture and the decision records for the reasoning.

Install

Not yet on PyPI. For development:

git clone https://github.com/ting-hong-shieh/quantrail.git
cd quantrail
uv sync
uv run pytest

Contributing

Correctness comes before features: accounting and statistics changes need tests with independently computed expectations. Every commit is signed off (DCO). See CONTRIBUTING.md.

Licence

Apache-2.0. See LICENSE and NOTICE. Data you use with QuantRail remains subject to its own source's terms.

Metadata

Release files for quantrail 0.1.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 quantrail 0.1.0
File Size Uploaded
quantrail-0.1.0.tar.gz 467.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for quantrail 0.1.0
File Interpreter ABI Platform
quantrail-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 502.5 kB

Release files / quantrail-0.1.0.tar.gz

Download URL quantrail-0.1.0.tar.gz
Size 467.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e5ebdee7ce1c9fc4586ed76d71b71778a7d8f2d541547fc606577ba0714e7fc7
BLAKE2b-256 checksum
How to use checksums
10573ec7b9868b3f0b3fcb238602478ba5fab7f4c41474234fc1f4560d3b65ae
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 Oct 5, 2026.

Transparency log

Release files / quantrail-0.1.0-py3-none-any.whl

Download URL quantrail-0.1.0-py3-none-any.whl
Size 34.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
915a8ed2ded8ba7f83594dfb19d6020f887b83b942771b5eb6b622a77eaab88a
BLAKE2b-256 checksum
How to use checksums
3991a6f85fe7cf545619019fb269e89efea45de69369ac0d2b06beccdb07c491
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 Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

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