Skip to main content

ashare-data-immunity

Data immunity for A-share daily bars: cleaning (NaN / OHLCV validation), board-aware price-limit and suspension detection, quality audit (listing / coverage / continuity) and snapshot versioning (sha256 manifests). Python 3.11+, zero dependencies, Windows / Linux / macOS.

Status: v0.1 鈥?alpha. The audit structure is distilled from a production A-share pipeline; board rules follow the current exchange conventions and should be re-checked against the exchanges' rule documents before you rely on them.

Why this exists

A-share daily data is not born clean. Vendors ship NaN closes, negative opens, volume in lots or shares depending on the board, silent suspensions that look like flat prices, and limit-up days that look like "huge moves" unless you know the board's 10/20/30% rule. Every one of these corrupts a factor pipeline differently, and most corrupt it quietly.

ashare-data-immunity is the immune system: it does not fetch data and it does not trade 鈥?it makes the data you already have honest:

  • clean 鈥?flag or sanitize non-finite values, non-positive prices, OHLC inconsistencies (high below max(open, close), low above min(open, close)), negative volume;
  • limits 鈥?board-aware price-limit detection (main 卤10%, STAR and ChiNext 卤20%, BSE 卤30%, ST 卤5% on the main board) against the previous close with tick rounding tolerance, plus a documented suspension heuristic (zero volume, or no prices on a dated row);
  • audit 鈥?daily quality audit: are watched codes still listed, does history coverage meet the threshold, are there calendar gaps? All data sources injectable, results append-only;
  • snapshot 鈥?sha256 manifests with cutoffs, so "which data did this backtest actually see" is a file you can compare and prove.

Philosophy

Data is an asset; immunity is a discipline.

Most data tooling optimizes for getting data. This tool optimizes for trusting the data you have 鈥?and it refuses to guess: board rules are explicit tables, the suspension detector is documented as a heuristic (vendor conventions differ), and the audit reports "universe unavailable" instead of pretending the listing check ran. Read-only by design; every function either returns a report or writes an append-only record. Nothing here trades, prices, or decides.

Quick start

# install from PyPI (once published)
pip install ashare-data-immunity

# or run without installing anything:
#   PYTHONPATH=src python -m ashare_data_immunity --help

python examples/demo.py   # clean + limits + audit + snapshot on synthetic data

Your own data:

# 1. validate / clean a bars file
imm clean --bars bars.json                     # exit 1 when problems found
imm clean --bars bars.json --drop-non-positive --out clean.json

# 2. board-aware limits + suspensions
imm limits --bars bars.json --code 600000
imm limits --bars bars.json --code 688001 --st

# 3. daily quality audit (watchlist + history dir + append-only audit dir)
imm audit --watchlist watchlist.json \
  --history-root data/daily --audit-root data/audits

# 4. snapshot versioning
imm snapshot --name v2026-08-01 --cutoff 2026-08-01 \
  --files data/daily/*.json --root data --out manifests/v1.json
imm snapshot-compare --before manifests/v1.json --after manifests/v2.json

Commands

Command What it does
clean Validate bars (missing/non-finite/non-positive fields, OHLC consistency, negative volume); optionally sanitize (non-finite and non-positive prices 鈫?None, volume kept 鈮?0) and optionally drop non-positive rows
limits Board classification, price-limit events (up/down with ratio and limit price) and suspension days for one code
audit Listing (codes not in the injected universe), history coverage, calendar continuity; appends a JSONL record per day
snapshot sha256 manifest of a file list with name + cutoff
snapshot-compare added / removed / changed files between two manifests
version Print version

Board rules (v0.1)

Board Prefixes Limit
main 60xxxx / 00xxxx 卤10% (ST: 卤5%)
STAR 688 / 689 卤20%
ChiNext 300 / 301 卤20%
Beijing SE 43x / 83x / 87x / 920 卤30%
unknown 鈥? 卤10% (assumed main)

Limit detection compares close against round(prev_close 脳 (1 卤 ratio), 2) with a default tolerance of 0.001 for vendor rounding conventions. The first bar has no reference and is never flagged. Verify the tables against the current exchange rule documents before production use 鈥?the tool's job is to make the rules explicit, not to invent them.

Suspension heuristic: a dated row with zero volume, or with no prices at all, is a suspension day. Documented, not hidden 鈥?and toggleable (zero_volume_means_suspended).

Development

python -m pip install -e . pytest
python -m pytest

CI runs the full test suite on Ubuntu, Windows and macOS with Python 3.11 and 3.12. Issues are handled on weekends; pull requests are welcome.

Related work

This tool makes no claims to novelty of its own: it is the engineering layer under the data-quality principles that the industry is converging on 鈥?point-in-time discipline (Kelly et al., NBER w35247), look-ahead awareness (Fonseca 2026, arXiv:2607.04958) and reproducible snapshots. The pieces that are worth citing live in the sibling repos of this project family; this one just keeps the data honest.

Project family

Part of Foolproof Labs — a toolchain against self-deception in quantitative research:

License

MIT

Metadata

Release files for ashare-data-immunity 0.1.1

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

Source distribution (sdist)

Source distribution for ashare-data-immunity 0.1.1
File Size Uploaded
ashare_data_immunity-0.1.1.tar.gz 18.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ashare-data-immunity 0.1.1
File Interpreter ABI Platform
ashare_data_immunity-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 34.1 kB

Release files / ashare_data_immunity-0.1.1.tar.gz

Download URL ashare_data_immunity-0.1.1.tar.gz
Size 18.5 kB
Tags Source
SHA-256 checksum
How to use checksums
cac7f0e0b034e2b777fd1735fe69e3cada808c8d7bf406a765dbcf7e4af43c75
BLAKE2b-256 checksum
How to use checksums
8bf8069f7d7535177ce22cb74999a543ea511ce6a0bdb553bbd31a822759a425
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release files / ashare_data_immunity-0.1.1-py3-none-any.whl

Download URL ashare_data_immunity-0.1.1-py3-none-any.whl
Size 15.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
39a8044624cbfae3fbba4431df2fd4640fea78c4ca904f55fe7284cd4453d171
BLAKE2b-256 checksum
How to use checksums
96da64d9a2ed9639026e6e74eebbf5b054dc38d9a789ce1edb68dfb17c88b368
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release history Release notifications | RSS feed

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

This release

0.1.1 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