Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Trading Data Daemon - A modular Python daemon system for downloading and storing trading data from German stock exchanges (EIX, Lang & Schwarz, Deutsche Börse, Gettex, Stuttgart, Börsenag regional exchanges) into QuestDB.
Language: Python 3.12+ | Database: QuestDB (time-series via Influx Line Protocol)
Commands
# Docker Compose (primary deployment method)
docker-compose up -d # Start all 5 services
docker-compose logs -f fetcher # Watch fetcher logs
docker-compose down # Stop all services
# Manual Python execution
python3 daemon.py # Run main fetcher
python -m src.analytics.worker # Run analytics worker
python src/metadata/fetcher.py # Run metadata fetcher
python dashboard/server.py # Run dashboard API (port 8000)
# Dependencies
pip install -r requirements.txt
Architecture
Five microservices orchestrated via Docker Compose:
┌─────────────────────────────────────────────────────────────────┐
│ QuestDB │
│ (9000=HTTP, 8812=PostgreSQL, 9009=ILP) │
└──────────┬──────────────┬──────────────┬──────────────┬─────────┘
│ │ │ │
┌──────┴──────┐ ┌─────┴─────┐ ┌──────┴──────┐ ┌─────┴─────┐
│ fetcher │ │ analytics │ │ metadata │ │ dashboard │
│ daemon.py │ │ worker │ │ fetcher │ │ :8080 │
└─────────────┘ └───────────┘ └─────────────┘ └───────────┘
Fetcher (daemon.py): Main orchestrator. Fetches trades from all exchanges daily at 23:00. Uses streaming for EIX (large files), batch processing for others. Handles deduplication via MD5 hash caching.
Analytics Worker (src/analytics/worker.py): Calculates aggregated tables (analytics_exchange_daily) for time periods: 7, 30, 42, 69, 180, 365 days.
Metadata Fetcher (src/metadata/fetcher.py): Enriches ISINs with company/sector data via OpenFIGI API and yfinance.
Dashboard (dashboard/server.py): FastAPI server serving REST endpoints and static UI from dashboard/public/.
Exchange Extensibility Pattern
All exchanges extend src/exchanges/base.py:BaseExchange. To add a new exchange:
- Create subclass in
src/exchanges/ - Implement
fetch_latest_trades()returning list ofTradeobjects - Implement
nameproperty - Register in
daemon.pyinSTREAMING_EXCHANGES(large data) orSTANDARD_EXCHANGES(batch)
Currently registered:
- Streaming: EIX (European Investor Exchange)
- Standard: LS, Xetra, Frankfurt, Quotrix, Gettex, Stuttgart, Börsenag (DUSA/DUSB/DUSC/DUSD/HAMA/HAMB/HANA/HANB)
Database Schema
trades: exchange, symbol, isin, price, quantity, timestampanalytics_exchange_daily: timestamp, exchange, trade_count, volumemetadata: isin, name, country, continent, sector
Environment Variables
DB_USER=admin # QuestDB user (default: admin)
DB_PASSWORD=quest # QuestDB password (default: quest)
DB_HOST=questdb # QuestDB hostname (default: questdb for Docker)
Code Conventions
- German-language comments and commit messages
- Memory-efficient patterns: streaming/generators for large files, explicit
delafter processing - Rate limiting: User-Agent rotation, 0.3-0.5s delays between requests, retry with backoff for 429s