A smart binary container for financial time-series data.
Project description
๐ QuantCrate (.qcr)
The SQLite of Quant Finance โ A zero-config, portable, high-performance binary container for financial time-series data.
What is QuantCrate?
QuantCrate is a specialized file format (.qcr) for financial OHLCV data that bundles:
- Smart metadata (ticker, exchange, timezone, timescale)
- Automatic data quality audits (5 built-in checks)
- Corporate action tracking (splits, dividends)
- SQL querying (DuckDB-powered, no database required)
All in a single, compressed, memory-mapped binary file.
The Problem
Traditional workflows with CSV/Parquet:
- โ No standardized metadata โ every vendor uses different column names
- โ No data quality guarantees โ backtests fail on "ghost" spikes or gaps
- โ No audit trail โ you don't know if data has been validated
- โ No SQL access โ must load into a database or DataFrame first
The QuantCrate Solution
from qcr import save_sealed_qcr, load_qcr, run_audit
from qcr.schema import QcrMetadata
# Pack data with metadata and automatic audit
metadata = QcrMetadata(ticker="AAPL", asset_class="Equity", ...)
audit = run_audit(df, timescale="1d")
save_sealed_qcr(df, metadata, audit, "AAPL.qcr")
# Load instantly (memory-mapped)
df, meta = load_qcr("AAPL.qcr")
# Query with SQL (no database needed!)
from qcr.vtable import query_qcr
result = query_qcr("SELECT * FROM 'AAPL.qcr' WHERE volume > 1000000")
Features
| Feature | Traditional (CSV/Parquet) | QuantCrate (.qcr) |
|---|---|---|
| Embedded metadata | โ None | โ Ticker, exchange, timezone, etc. |
| Data quality audit | โ Manual | โ Automatic (5 checks) |
| Audit trail | โ No | โ Sealed with timestamp |
| Corporate actions | โ Manual scripts | โ Stored in metadata |
| Split/dividend adjustments | โ Destructive | โ Non-destructive, on-the-fly |
| Instant metadata peek | โ Must load full file | โ Footer-only read |
| SQL queries | โ Load into DB first | โ Direct SQL via DuckDB |
| CLI tooling | โ Write your own | โ
qcr pack/info/ingest/sql |
| File size | ~Same | ~Same (ZSTD compressed) |
| Read speed | ~Same | ~Same (memory-mapped) |
Installation
# Core library
pip install quantcrate
# With CLI tools
pip install quantcrate[cli]
# With data adapters (Yahoo Finance, etc.)
pip install quantcrate[adapters]
# With SQL querying (DuckDB)
pip install quantcrate[sql]
# Everything
pip install quantcrate[cli,adapters,sql]
Quick Start
1. Pack a CSV into a .qcr file
# From the command line
qcr pack aapl.csv --ticker AAPL --timescale 1d --output AAPL.qcr
# The auditor runs automatically and blocks sealing if errors are found
2. Inspect metadata
qcr info AAPL.qcr
Output:
โโโโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโโโโโโโ
โ Field โ Value โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ ticker โ AAPL โ
โ asset_class โ Equity โ
โ currency โ USD โ
โ exchange โ XNAS โ
โ timezone โ America/New_York โ
โ timescale โ 1d โ
โ audit_passed โ โ True โ
โ data_gaps โ 0 โ
โ outliers_found โ 0 โ
โโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโ
3. Load and analyze
from qcr import load_qcr
# Load the full file (instant, memory-mapped)
df, metadata = load_qcr("AAPL.qcr")
print(df.head())
print(metadata.identity.ticker) # "AAPL"
print(metadata.audit.audit_passed) # True
4. Query with SQL
# From the command line
qcr sql "SELECT * FROM 'AAPL.qcr' WHERE close > 150" --format table
# CSV output
qcr sql "SELECT timestamp, close, volume FROM 'AAPL.qcr'" --format csv --limit 100
# Cross-file JOIN
qcr sql "SELECT a.close, b.close FROM aapl JOIN msft ON a.timestamp = b.timestamp" \
-r AAPL.qcr=aapl -r MSFT.qcr=msft
Or in Python:
from qcr.vtable import query_qcr, query_qcr_df
# Get results as a structured object
result = query_qcr("SELECT avg(close) FROM 'AAPL.qcr'")
print(result.rows) # [(150.23,)]
# Get results as a Polars DataFrame (zero-copy from DuckDB)
df = query_qcr_df("SELECT * FROM 'AAPL.qcr' WHERE volume > 1000000")
5. Fetch live data
# Fetch from Yahoo Finance, audit, and seal in one command
qcr ingest AAPL --start 2024-01-01 --end 2024-12-31 --timescale 1d
Or in Python:
from qcr.ingest import ingest_to_qcr
from qcr.adapters import YahooFinanceAdapter
import asyncio
adapter = YahooFinanceAdapter()
result = await ingest_to_qcr(
adapter=adapter,
ticker="AAPL",
start_date="2024-01-01",
end_date="2024-12-31",
asset_class="Equity",
timescale="1d",
)
if result.success:
print(f"Sealed {result.rows} rows to {result.path}")
6. Apply corporate actions
from qcr import load_qcr
from qcr.adjust import adjust_ohlcv
from qcr.schema import CorporateAction, ActionType
from datetime import datetime, timezone
# Load raw data
df, metadata = load_qcr("AAPL.qcr")
# Define a 4-for-1 split on 2022-08-31
actions = [
CorporateAction(
action_type=ActionType.SPLIT,
effective_date=datetime(2022, 8, 31, tzinfo=timezone.utc),
value=4.0,
)
]
# Apply adjustments (non-destructive, returns new DataFrame)
adjusted_df = adjust_ohlcv(df, actions)
# Pre-split prices are divided by 4, volume is multiplied by 4
# Post-split rows are unchanged
The Auditor โ 5 Automatic Checks
Every .qcr file is sealed only after passing these checks:
| Check | Description | Severity |
|---|---|---|
| Logical Consistency | High >= Open, High >= Close, High >= Low, Low <= Open, Low <= Close, Volume >= 0 |
ERROR |
| Non-Zero Price | All OHLC prices must be > 0 | ERROR |
| Chronological Integrity | Timestamps must be strictly increasing with no duplicates | ERROR |
| Outlier Detection | Flags price moves exceeding 5 standard deviations | WARNING |
| Gap Detection | Identifies missing candles based on the expected timescale | WARNING |
Errors block sealing. Warnings are recorded but don't block (use --force to override).
Architecture
File Anatomy
A .qcr file is a ZSTD-compressed Parquet file built on Apache Arrow:
- The Header (Metadata): JSON stored under the
qcr_metadatakey in the Arrow schema metadata. - The Audit Trail: Quality-check results written by the
Auditorbefore sealing. - The Corporate Action Table: Stores splits/dividends for dynamic adjustments.
- The Payload: Columnar OHLCV data โ
float32prices,uint64volume,timestamp[ns, UTC].
Tech Stack
| Dependency | Purpose |
|---|---|
pyarrow |
Arrow/Parquet I/O, schema metadata, ZSTD compression, memory-mapping |
polars |
DataFrame manipulation and validation |
pydantic |
Metadata validation (enforce required fields, types, enums) |
typer + rich |
CLI framework with beautiful terminal output |
yfinance (optional) |
Yahoo Finance data adapter for live OHLCV fetching |
duckdb (optional) |
SQL query engine with native Parquet support |
pytest |
Testing framework (146 tests passing) |
CLI Commands
| Command | Description | Example |
|---|---|---|
qcr pack |
Ingest CSV, audit, seal to .qcr | qcr pack aapl.csv --ticker AAPL --timescale 1d |
qcr info |
Print metadata from .qcr file | qcr info AAPL.qcr |
qcr ingest |
Fetch live data, audit, seal | qcr ingest AAPL --start 2024-01-01 --end 2024-12-31 |
qcr sql |
Query .qcr files with SQL | qcr sql "SELECT * FROM 'AAPL.qcr' WHERE close > 150" |
Demo
Run the comprehensive demo to see all features in action:
python demo.py
This interactive script compares QuantCrate with traditional workflows step-by-step, including:
- CSV ingestion
- Data quality auditing
- Metadata inspection
- Corporate action adjustments
- SQL querying
- CLI usage
- File size and load-time comparisons
Project Structure
qcr/
โโโ qcr/ # Core package
โ โโโ __init__.py # Package root, __version__
โ โโโ schema.py # Pydantic models, enums, Arrow PAYLOAD_SCHEMA
โ โโโ storage.py # save_qcr / load_qcr / read_qcr_metadata
โ โโโ auditor.py # Financial linter / validation rules
โ โโโ adjust.py # Split & dividend adjustments
โ โโโ adapters.py # BaseAdapter ABC + YahooFinanceAdapter
โ โโโ ingest.py # Async fetch โ audit โ seal pipeline
โ โโโ vtable.py # DuckDB-powered SQL engine for .qcr files
โ โโโ cli.py # CLI entry point (typer)
โโโ tests/
โ โโโ test_storage.py # 14 tests โ
โ โโโ test_auditor.py # 26 tests โ
โ โโโ test_cli.py # 14 tests โ
โ โโโ test_adjust.py # 26 tests โ
โ โโโ test_adapters.py # 26 tests โ
โ โโโ test_vtable.py # 40 tests โ
โโโ pyproject.toml # hatchling build, deps, pytest config
โโโ demo.py # Interactive demo script
โโโ PLAN.md # Project vision & specification
โโโ ROADMAP.md # Development phases & tasks
โโโ SCHEMA_SPEC.md # Metadata & payload schema spec
โโโ README.md # This file
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Run tests (
pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT License โ see LICENSE file for details.
Why "QuantCrate"?
Because financial data deserves better than a CSV in a ZIP file. QuantCrate is:
- Portable โ One file, no setup, works anywhere
- Smart โ Knows what a stock split is, validates data quality
- Fast โ Memory-mapped, compressed, columnar storage
- Professional โ Audit trails, metadata, corporate actions built-in
Think of it as SQLite for quant finance โ a single-file, zero-config database optimized for time-series data.
Built with โค๏ธ for quantitative researchers, data scientists, and financial engineers.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quantcrate-0.1.1.tar.gz.
File metadata
- Download URL: quantcrate-0.1.1.tar.gz
- Upload date:
- Size: 58.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad77bcf61abc900d0b49b456a9bc94928680c53064f7e55d32878ed6c1a648a1
|
|
| MD5 |
8f80d5eb1b6d1deccf1902700f32d477
|
|
| BLAKE2b-256 |
6d40893fc2272397a4e645a81fcce8900563c96c761fd2cd36c34f17e325966b
|
File details
Details for the file quantcrate-0.1.1-py3-none-any.whl.
File metadata
- Download URL: quantcrate-0.1.1-py3-none-any.whl
- Upload date:
- Size: 36.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c9865ad497c7d47b68afff09ea3fdaaebaeaa5b163bd5a8c671d1636d12203e
|
|
| MD5 |
e2ba1511a54970adcd7f7527b8752dbd
|
|
| BLAKE2b-256 |
c0c40fc429e319f87a770280c2e0c0653ca775d9860ea2046556a169a387aace
|