Skip to main content

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.

Tests Python License


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:

  1. The Header (Metadata): JSON stored under the qcr_metadata key in the Arrow schema metadata.
  2. The Audit Trail: Quality-check results written by the Auditor before sealing.
  3. The Corporate Action Table: Stores splits/dividends for dynamic adjustments.
  4. The Payload: Columnar OHLCV data โ€” float32 prices, uint64 volume, 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:

  1. CSV ingestion
  2. Data quality auditing
  3. Metadata inspection
  4. Corporate action adjustments
  5. SQL querying
  6. CLI usage
  7. 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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Run tests (pytest)
  4. Commit your changes (git commit -m 'Add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quantcrate-0.1.1.tar.gz (58.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

quantcrate-0.1.1-py3-none-any.whl (36.0 kB view details)

Uploaded Python 3

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

Hashes for quantcrate-0.1.1.tar.gz
Algorithm Hash digest
SHA256 ad77bcf61abc900d0b49b456a9bc94928680c53064f7e55d32878ed6c1a648a1
MD5 8f80d5eb1b6d1deccf1902700f32d477
BLAKE2b-256 6d40893fc2272397a4e645a81fcce8900563c96c761fd2cd36c34f17e325966b

See more details on using hashes here.

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

Hashes for quantcrate-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3c9865ad497c7d47b68afff09ea3fdaaebaeaa5b163bd5a8c671d1636d12203e
MD5 e2ba1511a54970adcd7f7527b8752dbd
BLAKE2b-256 c0c40fc429e319f87a770280c2e0c0653ca775d9860ea2046556a169a387aace

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page