QuantRail
Every backtest lies a little. QuantRail tells you where.
Data governance · ledger-accurate simulation · research discipline
繁體中文 · Architecture · Decisions · Contributing
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
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)
| File | Size | Uploaded | |
|---|---|---|---|
| quantrail-0.1.0.tar.gz | 467.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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