Skip to main content

OHLCVault

OHLCV = Open/High/Low/Close/Volume, the universal bar format. Vault = immutable, checksummed snapshots.

Reproducible daily OHLCV data for A-share, Hong Kong and US markets — served as static files from a CDN. No API keys, no rate limits, no per-request billing.

import ohlcvault as ov

ov.connect()
df = ov.daily("600519.SH").to_pandas()      # 跨月自动拼接
ov.cross_section("cn", 20260918, limit=50)  # 当日全市场截面,按成交额排序

Why this exists

Most free market-data endpoints are APIs: stateful, rate-limited, silently revised, and impossible to reproduce. A backtest that ran last month can't be rerun today with the same inputs.

OHLCVault publishes immutable monthly shards with checksums instead. Each read is anchored to a snapshot id you can write down and reproduce later, on any machine.

Install

pip install ohlcvault            # core, zero runtime dependencies
pip install "ohlcvault[pandas]"  # + DataFrame helpers

The core has no third-party dependencies — only the standard library. That's deliberate: a data client shouldn't drag a dependency tree into your project, and it matters even more for agent/tooling contexts.

Usage

Everything (the five things you actually need)

import ohlcvault as ov
ov.connect()

# 1. Trading calendar
ov.calendar("cn", start=20260101)

# 2. Stock daily bars (cross-month stitching is handled for you)
ov.daily("600519.SH", start=20260101, end=20260918)

# 3. Index daily bars — a separate namespace, never mixed with stocks
ov.index_daily("000300.SH")

# 4. Symbol list — includes delisted stocks
ov.symbols("cn", type="stock")
ov.symbols("cn", type="stock", status="delisted")

# 5. Daily cross-section — sorted by turnover, no extra data files
ov.cross_section("cn", 20260918, sort_by="amount", limit=50)

Batch backtests

Month shards hold every symbol in the market for that month. Loading 200 symbols one-by-one would decompress the same file 200 times:

bars = ov.daily_many(["600519.SH", "000001.SZ", "300750.SZ"], start=20260101)
bars["600519.SH"].to_pandas()

Adjustment is a view, not a stored field

The dataset stores unadjusted prices only, plus the official cumulative back-adjustment factor. Forward/backward adjusted prices are computed client-side:

b = ov.daily("600519.SH")
ov.adjust(b, to="hfq")   # 后复权
ov.adjust(b, to="qfq")   # 前复权

This is not a limitation — it's the reason historical files never change. If forward-adjusted prices were stored, every dividend would rewrite all of history, and immutable caching would be impossible.

Reproducibility

st = ov.connect()
sid = st.snapshot                       # e.g. "6b197df3723871c5"
ov.connect(snapshot=sid)                # later, anywhere: exact same inputs

Offline / self-hosted mirrors

A mirror can be an HTTP(S) URL or a local directory:

ov.connect(mirrors=["/path/to/data"])

Mirrors are tried in order; whichever one succeeds is promoted to first place. Every file is checked against the sha256 in the snapshot manifest, and anything that fails is discarded and the next mirror is tried — bad bytes are never handed to the caller.

Data integrity

Guarantee How
No silently-corrupted data Every file verified against the snapshot's sha256
No silently-changed history Sealed months are never rewritten
No unverifiable numbers Missing adjustment factors raise, instead of returning raw prices
No hidden survivorship bias Delisted stocks are kept in the universe and in the data
Byte-for-byte reproduction Fixed-point integers, gzip with MTIME=0, no wall-clock timestamps

Delisted stocks matter. If your backtest universe only contains companies that are still listed today, your historical returns are systematically overstated. ov.symbols("cn", status="delisted") returns them, and their daily bars are complete over ipo … out.

Coverage and known gaps

Coverage is declared explicitly in meta/symbols/{market}.json under coverage, and ov.connect() prints it on startup. Current state:

Market Status Gaps
cn Daily bars + indices, 2000→present No Beijing Stock Exchange (upstream source doesn't provide it)
hk Symbol list only No daily bars yet; list is current listings only
us Symbol list only No daily bars yet; list is current listings only

hk / us symbol lists carry survivorship bias (the upstream source only returns currently-listed securities) and have no IPO dates. Their daily bars are pending.

An honest data project states its gaps. A dataset that quietly omits them is worse than one that is merely incomplete.

API

Function Purpose
connect(mirrors=, cache_dir=, snapshot=) Build the default client
symbols(market, type=, status=, board=) Symbol list
symbol(code) Single symbol entry
calendar(market, start=, end=) Trading calendar
daily(code, start=, end=) Stock daily bars, cross-month stitching
index_daily(code, start=, end=) Index daily bars
daily_many(codes, start=, end=) Batch read (preferred for backtests)
cross_section(market, date, sort_by=, limit=) Daily cross-section
adjust(bars_or_df, to="qfq"|"hfq"|"none") Adjustment view
snapshot() Current snapshot id

Date parameters (start / end / date) accept an int YYYYMMDD (preferred) or common string forms — "2026-09-18", "20260918", "2026/09/18". Anything unparseable raises DateError instead of failing deep inside the library.

The frozen data contract lives in SPEC.md — the client and the pipeline share nothing but this document and the files it describes. schema/example-*.json are machine-generated from real data, so the examples cannot drift from the contract.

License

MIT. See LICENSE.

Data is gathered from public sources. Verify before relying on it for anything consequential.

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

Built distribution (wheel)

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

Total release size: 76.1 kB

Release files / ohlcvault-0.1.0.tar.gz

Download URL ohlcvault-0.1.0.tar.gz
Size 47.2 kB
Tags Source
SHA-256 checksum
How to use checksums
10f5800457bc092e59b7a68ed58d99973ee45c1f35f8fd702a288f86da89d3ce
BLAKE2b-256 checksum
How to use checksums
b80c396ba5562df9951bb5c121f7f91912fe526b19f6e877f915992ebab4f8f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

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

Download URL ohlcvault-0.1.0-py3-none-any.whl
Size 28.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5c6248577a80e49a87c80624651a6cbad370c5bb2672ec1e829d007d4ae4c7fd
BLAKE2b-256 checksum
How to use checksums
a431112f571cba43ca84777f3a64250194727820b7391f454f17a842fc963445
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

Release history Release notifications | RSS feed

0.2.1

2 release files

0.2.0

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