Live
A self-hosted warehouse for market data.
FX, metals, indices, commodities, crypto, OHLC bars and tick data, stored in DuckDB and served over a FastAPI layer with cursor-paginated queries, Parquet backups, and a WebSocket endpoint for historical replay.
Current coverage
updated —
Architecture
Receive. Store. Serve.
Three components, clean boundaries, one VPS.
- 01
FastAPI
ingest · query · WebSocket
Handles ingestion, auto-derivation from M1 to D1, cursor-paginated queries, and historical replay.
- 02
DuckDB + Postgres
market data · auth
DuckDB holds OHLC bars and ticks in an embedded columnar file. Postgres holds users and API keys.
- 03
Caddy
TLS · reverse proxy
Terminates TLS, proxies /api/* to FastAPI and / to this static site.
Stack
What it's built with.
- FastAPIREST + WebSocket API
- DuckDBOHLC + tick storage
- PostgreSQLusers + API keys
- CaddyTLS reverse proxy
- Docker Composecontainer orchestration
- HetznerVPS
API
Sample query.
Queries are cursor-paginated; timestamps are UTC; each row is tagged
raw or
derived.
{
"instrument": "XAUUSD",
"timeframe": "D1",
"count": 3,
"next_cursor": "eyJ0cyI6IjIwMjUtMTEtMDMifQ==",
"rows": [
{
"timestamp": "2025-11-03T00:00:00Z",
"open": 3987.12,
"high": 4021.88,
"low": 3971.05,
"close": 4014.60,
"volume": 128334,
"source": "raw"
},
{
"timestamp": "2025-11-04T00:00:00Z",
"open": 4014.60,
"high": 4055.20,
"low": 4002.15,
"close": 4048.73,
"volume": 142019,
"source": "raw"
},
{
"timestamp": "2025-11-05T00:00:00Z",
"open": 4048.73,
"high": 4071.40,
"low": 4031.90,
"close": 4060.25,
"volume": 117445,
"source": "raw"
}
]
} Row-level queries require an API key. The stats above come from an aggregate-only public endpoint — no row content is exposed without auth.