Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Algorithmic Trading Platform

A production-ready, cloud-native algorithmic trading platform built with modern data engineering and ML technologies. Real-time crypto market data processing, strategy backtesting, and automated trading execution.

🎯 Project Overview

This platform demonstrates advanced technical skills in:

  • Stream Processing: Real-time market data ingestion and processing
  • Time-Series Analytics: High-performance OLAP queries on billions of ticks
  • Machine Learning: Price prediction and trading signal generation
  • Distributed Systems: Event-driven microservices architecture
  • Cloud-Native Development: LocalStack for AWS services, managed databases
  • DevOps: Infrastructure as Code, local β†’ cloud portability

Tech Stack:

  • Streaming & Messaging: Kafka (data streaming), RabbitMQ (task queues), Kinesis (AWS alternative)
  • Storage: S3 (LocalStack), ClickHouse (time-series), Redis (cache), PostgreSQL (metadata)
  • Application Layer: FastAPI, Python, AsyncIO, MLflow, Jupyter
  • Monitoring: Grafana, Prometheus
  • Cloud Services (LocalStack): Lambda, DynamoDB, EventBridge, SQS

πŸ“Š Architecture

Hybrid Messaging Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  DATA STREAMING (Kafka)                         β”‚
β”‚  Exchange WebSockets β†’ Kafka β†’ [S3, ClickHouse, Redis]        β”‚
β”‚  β€’ High throughput (60+ symbols)                               β”‚
β”‚  β€’ Message replay for backtesting                              β”‚
β”‚  β€’ Multiple consumers (analytics, ML)                          β”‚
β”‚  β€’ 24h retention                                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  TASK QUEUES (RabbitMQ)                         β”‚
β”‚  Trading API β†’ RabbitMQ β†’ Workers                              β”‚
β”‚  β€’ Order execution (priority queues)                           β”‚
β”‚  β€’ Backtest jobs (parallel workers)                            β”‚
β”‚  β€’ Notifications (email, telegram)                             β”‚
β”‚  β€’ Dead letter queues for failures                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Local Development Stack (Phase 2)

Exchange REST API (ccxt)          Exchange WebSocket (Binance/Coinbase/Kraken)
    ↓                                          ↓
Sync Service (every 60s)          Market Data Ingestion Service
  - Initial backfill: 100 candles   - 60+ symbols, real-time trades
  - Regular sync: 5 latest candles  - Samples ~4% of trades
    ↓                                          ↓
ClickHouse (candles_1m/5m/1h)     Redis (latest_price:{exchange}:{symbol})
  ReplacingMergeTree, TTL 90d       Real-time signals for Phase 3+
    ↓
Indicator Service (every 60s + 10s delay)
  - Catch-up mode: all historical candles on startup
  - Calculates: SMA 20/50, EMA 12/26, RSI 14, MACD
  - Stores: ClickHouse (indicators) + Redis (60s TTL)
    ↓
Grafana (technical-analysis.json)
  └── 4 panels: Price+Indicators, RSI, MACD, Volume

Future Stack (Phase 3+)

Trading API (FastAPI) β†’ RabbitMQ β†’ Workers
    ↓
β”œβ”€β”€ Strategy Engine
β”œβ”€β”€ ML Pipeline (Jupyter)
β”œβ”€β”€ Grafana (Docker) - Monitoring
└── Prometheus - Metrics collection

Cloud Production (Same code, different endpoints)

Replace LocalStack endpoints with real AWS services
- LocalStack S3 β†’ AWS S3
- LocalStack Kinesis β†’ AWS Kinesis
- LocalStack Lambda β†’ AWS Lambda
- Docker ClickHouse β†’ ClickHouse Cloud
- Docker Redis β†’ AWS ElastiCache

πŸ“ Project Structure

DataPlatform/
β”‚
β”œβ”€β”€ πŸ“ config/                           # Configuration Management
β”‚   β”œβ”€β”€ settings.py                      # Pydantic Settings (from .env + YAML)
β”‚   β”œβ”€β”€ loader.py                        # YAML config loaders
β”‚   └── providers/                       # Per-service YAML configs
β”‚       β”œβ”€β”€ databases.yaml               # ClickHouse, Redis, PostgreSQL
β”‚       β”œβ”€β”€ exchanges.yaml               # WebSocket + REST API per exchange
β”‚       β”œβ”€β”€ indicators.yaml              # Indicator definitions + service settings
β”‚       β”œβ”€β”€ streaming.yaml               # Kafka/Kinesis topics
β”‚       β”œβ”€β”€ storage.yaml                 # S3/GCS object storage
β”‚       └── sync.yaml                    # Sync Service timing + REST API config
β”‚
β”œβ”€β”€ πŸ“ core/                             # Core Abstractions (Cloud-agnostic)
β”‚   β”œβ”€β”€ interfaces/                      # Abstract Base Classes
β”‚   β”‚   β”œβ”€β”€ cache.py                     # BaseCacheClient (Redis, Memcached)
β”‚   β”‚   β”œβ”€β”€ database.py                  # BaseTimeSeriesDB (ClickHouse, TimescaleDB)
β”‚   β”‚   β”œβ”€β”€ market_data.py               # BaseExchangeWebSocket + BaseExchangeRestAPI
β”‚   β”‚   β”œβ”€β”€ indicators.py                # BaseIndicator
β”‚   β”‚   β”œβ”€β”€ storage.py                   # BaseStorageClient (S3, GCS)
β”‚   β”‚   β”œβ”€β”€ streaming_producer.py        # BaseStreamProducer (Kafka, Kinesis)
β”‚   β”‚   └── streaming_consumer.py        # BaseStreamConsumer
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── market_data.py               # Trade, Candle, OrderBook (Pydantic)
β”‚   β”œβ”€β”€ validators/
β”‚   β”‚   └── market_data.py               # Spike detection, crossed book checks
β”‚   └── utils/
β”‚       └── config.py                    # load_yaml_safe()
β”‚
β”œβ”€β”€ πŸ“ providers/                        # Cloud Provider Implementations
β”‚   β”œβ”€β”€ aws/
β”‚   β”‚   β”œβ”€β”€ kinesis.py                   # KinesisStreamProducer
β”‚   β”‚   └── s3.py                        # S3StorageClient
β”‚   β”œβ”€β”€ opensource/
β”‚   β”‚   β”œβ”€β”€ clickhouse.py                # ClickHouseClient (connection pool)
β”‚   β”‚   β”œβ”€β”€ redis_client.py              # RedisClient (queued writes)
β”‚   β”‚   └── kafka_stream_producer.py     # KafkaStreamProducer
β”‚   β”œβ”€β”€ binance/
β”‚   β”‚   β”œβ”€β”€ websocket.py                 # BinanceWebSocket
β”‚   β”‚   └── rest_api.py                  # BinanceRestAPI (ccxt)
β”‚   β”œβ”€β”€ coinbase/
β”‚   β”‚   β”œβ”€β”€ websocket.py                 # CoinbaseWebSocket
β”‚   β”‚   └── rest_api.py                  # CoinbaseRestAPI (ccxt)
β”‚   └── kraken/
β”‚       β”œβ”€β”€ websocket.py                 # KrakenWebSocket
β”‚       └── rest_api.py                  # KrakenRestAPI (ccxt)
β”‚
β”œβ”€β”€ πŸ“ factory/
β”‚   └── client_factory.py                # create_exchange_rest_api(), create_timeseries_db(), etc.
β”‚
β”œβ”€β”€ πŸ“ domain/                           # Business Logic
β”‚   └── indicators/
β”‚       β”œβ”€β”€ moving_averages.py           # SMA, EMA, WMA
β”‚       β”œβ”€β”€ momentum.py                  # RSI, MACD, Stochastic
β”‚       └── registry.py                  # Load indicators from config
β”‚
β”œβ”€β”€ πŸ“ services/                         # Microservices (Phase 2)
β”‚   β”œβ”€β”€ market_data_ingestion/           # WebSocket β†’ Redis (real-time signals)
β”‚   β”‚   β”œβ”€β”€ main.py
β”‚   β”‚   β”œβ”€β”€ stream_processor.py
β”‚   β”‚   └── websocket_client.py
β”‚   β”œβ”€β”€ sync_service/                    # REST API β†’ ClickHouse (authoritative candles)
β”‚   β”‚   └── main.py                      # Runs every 60s, backfills 100 candles on startup
β”‚   └── indicator_service/               # ClickHouse β†’ Calculate β†’ Redis + ClickHouse
β”‚       β”œβ”€β”€ main.py                      # Runs every 60s (+10s delay after sync)
β”‚       β”œβ”€β”€ calculator.py
β”‚       β”œβ”€β”€ persistence.py
β”‚       └── indicator_loader.py
β”‚
β”œβ”€β”€ πŸ“ infrastructure/
β”‚   β”œβ”€β”€ docker/
β”‚   β”‚   β”œβ”€β”€ docker-compose.yml           # ClickHouse, Redis, PostgreSQL, Grafana
β”‚   β”‚   └── clickhouse/
β”‚   β”‚       β”œβ”€β”€ init-and-migrate.sh      # Auto-applies migrations on startup
β”‚   β”‚       └── migrations/              # 000–006 SQL migrations
β”‚   └── terraform/                       # LocalStack (S3, Kinesis)
β”‚
β”œβ”€β”€ πŸ“ monitoring/
β”‚   └── grafana/
β”‚       β”œβ”€β”€ dashboards/
β”‚       β”‚   └── technical-analysis.json  # Price+Indicators, RSI, MACD, Volume
β”‚       └── provisioning/
β”‚           └── datasources.yml          # ClickHouse, Prometheus, PostgreSQL
β”‚
β”œβ”€β”€ πŸ“ tests/
β”‚   β”œβ”€β”€ unit/                            # 183 tests, no Docker required
β”‚   β”‚   β”œβ”€β”€ indicators/                  # SMA, EMA, RSI, MACD
β”‚   β”‚   β”œβ”€β”€ services/                    # stream_processor, websocket_client
β”‚   β”‚   β”œβ”€β”€ test_config/                 # Settings Phase 2
β”‚   β”‚   β”œβ”€β”€ test_providers/              # ClickHouse pool, queued cache/db/streaming, REST API
β”‚   β”‚   β”œβ”€β”€ test_services/               # indicator calculator + persistence
β”‚   β”‚   β”œβ”€β”€ test_factory.py
β”‚   β”‚   └── test_models.py
β”‚   └── integration/                     # Requires Docker + Terraform
β”‚       β”œβ”€β”€ pipelines/                   # End-to-end pipeline tests
β”‚       β”œβ”€β”€ infrastructure/              # ClickHouse, Redis, Docker readiness
β”‚       β”œβ”€β”€ idempotency/                 # Candle/indicator/cache quality
β”‚       └── factory/                     # Exchange factory + REST API network
β”‚
β”œβ”€β”€ πŸ“ docs/
β”‚   β”œβ”€β”€ DOCKER_SETUP.md
β”‚   β”œβ”€β”€ TERRAFORM_SETUP.md
β”‚   β”œβ”€β”€ KINESIS_VS_KAFKA.md              # Architecture decision record
β”‚   β”œβ”€β”€ COMPARISON.md
β”‚   └── WHEN_TO_USE_CLOUD_DB.md
β”‚
β”œβ”€β”€ .env.example                         # Environment template
β”œβ”€β”€ .gitignore
β”œβ”€β”€ pyproject.toml                       # uv dependencies
β”œβ”€β”€ Makefile                             # docker-up/down, terraform-apply, etc.
└── CLAUDE.md                            # AI assistant context + architecture guide

πŸ”‘ Key Design Principles

1. Separation of Concerns:

  • core/interfaces/ - Abstract contracts (cloud-agnostic)
  • providers/ - Concrete implementations (AWS, GCP, Azure, LocalStack)
  • factory/ - Auto-create clients based on config
  • domain/ - Business logic (trading strategies, NOT cloud code)
  • services/ - Microservices (API, ingestion, strategy engine)

2. Dependency Flow:

services/ β†’ domain/ β†’ factory/ β†’ providers/ β†’ core/interfaces/
                         ↓
                     config/

3. Cloud Portability:

  • Code in services/ and domain/ is 100% cloud-agnostic
  • Switch clouds by changing .env file only
  • No vendor lock-in

4. Testability:

  • Mock implementations of core/interfaces/ for testing
  • Fixtures in tests/fixtures/
  • Separate unit and integration tests

πŸ“Š Architecture Maturity (vs. Quant Fund Standard)

Mapping hiện trαΊ‘ng vΓ o 5 lα»›p workflow cα»§a quα»Ή Δ‘α»‹nh lượng:

Layer 1 β€” Data Infrastructure      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  βœ… Complete
          Multi-exchange WebSocket + REST API, ClickHouse OHLCV,
          Redis cache, PostgreSQL paper trading, MLflow artifacts

Layer 2 β€” Feature / Factor Eng.    β–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘  ~40%
          10 regime features + 16 sizing features (price-based only)
          Missing: funding rate, open interest, cross-asset, alternative data
          β†’ Phase 8C target

Layer 3 β€” Alpha Validation          β–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘  ~30%
          Backtest engine + walk-forward runner exist
          Missing: IC (information coefficient), decay analysis,
          factor correlation matrix, signal quality filter
          β†’ Phase 8B target

Layer 4 β€” Portfolio Construction    β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘  ~80%
          MVO optimizer, regime gates (Layer 1 + Layer 2),
          meta-labeling filter, vol overlay, 4-slot MSAPE engine

Layer 5 β€” Risk & Execution          β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘  ~50%
          RiskManager, PaperBroker, BacktestBroker
          Missing: slippage model, market impact, execution algos

πŸ“ˆ Backtest Results Summary (2022-01-01 β†’ 2026-02-27, Binance 1h)

Strategy Symbol Return Sharpe MaxDD Trades
volatility_breakout SOLUSDT +7.11% 0.580 3.50% 234
volatility_breakout ETHUSDT +3.92% 0.575 1.60% 232
volatility_breakout BTCUSDT +0.78% 0.142 2.50% 248
sma_crossover ETHUSDT +1.42% 0.099 9.04% 830
sma_crossover BTCUSDT -1.27% -0.070 7.00% 862
rsi_mean_reversion ETHUSDT -4.68% -0.224 10.90% 295
rsi_mean_reversion BTCUSDT -6.75% -0.465 8.67% 254
ma_trend BTCUSDT -7.89% -0.678 8.38% 1,561
volatility_breakout BNBUSDT -5.56% -0.884 6.16% 246
adaptive_trend BTCUSDT -12.92% -0.747 16.97% 2,187
lower_band_reversion BTCUSDT -15.46% -1.397 16.67% 1,558
fade_breakout BTCUSDT -13.93% -2.106 14.33% 1,594

Portfolio MSAPE β€” 4 slots, regime filter ON:

Period Return Ann. Sharpe MaxDD AvgLev
2022–2026 (4yr) +2.38% +0.58%/yr 0.295 -2.56% 1.47Γ—
2024 only +2.58% +2.90%/yr 1.20 -1.60% 1.36Γ—

Key insight: ma_trend (1,561 trades β†’ $1,512 commission) and adaptive_trend (2,187 trades β†’ $2,082 commission) lose 14–20% of capital to fees. Regime filter cuts them to ~200 trades and turns Sharpe positive.


πŸ—ΊοΈ Development Phases

πŸ“ PHASE 1: Foundation & Real-time Data βœ… COMPLETED

Goal: Stream live crypto market data into the system

Minimal Features (Required):

  • LocalStack setup (S3, Kinesis, Lambda)
  • Docker Compose for stateful services (ClickHouse, Redis, Grafana, Kafka)
  • WebSocket connection to Binance (BTC, ETH)
  • Stream to Kafka/Kinesis β†’ S3 (raw data backup)
  • ClickHouse table: trades (symbol, price, quantity, timestamp)
  • Grafana dashboard: Real-time price line chart
  • Environment config: .env + YAML configs (cloud-agnostic)

Advanced Features (Completed):

  • Multi-exchange support (Binance, Coinbase, Kraken)
  • 60+ crypto symbols streaming (20+ per exchange)
  • Order book depth data with quality validation
  • Data quality validation (spike detection, crossed book checks)
  • Kafka migration (KRaft mode, dual listeners)
  • Cloud-agnostic architecture (factory pattern, generic naming)
  • Comprehensive testing (62/62 tests passing: 46 unit, 16 integration)
  • Git pre-push hooks (secrets detection, lint, format, tests)
  • YAML-based configuration (public) + .env secrets (gitignored)

Services:

  • Docker: Kafka, ClickHouse, Redis, PostgreSQL, Grafana, Prometheus
  • LocalStack: S3, Kinesis (optional alternative to Kafka)
  • Python: Market data ingestion service with async WebSocket clients

Tech Showcase:

  • Cloud-Agnostic Design: Factory pattern, swappable providers (Kafka/Kinesis, S3/GCS, ClickHouse/TimescaleDB)
  • Multi-Exchange Integration: Binance, Coinbase, Kraken with unified interface
  • Kafka Streaming: KRaft mode, dual listeners (Docker + host), 24h retention
  • Data Quality: Spike detection, order book validation, data validators
  • Testing: 62/62 tests (unit + integration), pytest markers, timezone-aware
  • DevOps: Git hooks, ruff linting/formatting, uv dependency management
  • Monitoring: Grafana dashboards with multi-exchange metrics

πŸ“ PHASE 2: Data Processing & Analytics βœ… COMPLETED

Goal: Transform raw ticks into analytical datasets

Minimal Features (Required):

  • OHLCV candlesticks (1m, 5m, 1h) via REST API
  • ClickHouse candle tables (direct inserts, no MVs)
  • Technical indicators: SMA(20, 50), EMA(12, 26), RSI, MACD
  • Redis caching for latest indicators
  • Grafana technical analysis dashboard

Advanced Features (Completed):

  • Advanced indicators: RSI, MACD with custom implementations
  • Multiple timeframes (1m, 5m, 1h)
  • Initial backfill (100 candles on startup)
  • Catch-up mode (calculate indicators for all historical candles)
  • Sequential processing (avoid ClickHouse connection conflicts)

Services:

  • Redis (cache for indicators)
  • ClickHouse (candles + indicators storage)
  • NEW: Sync Service - Scheduled REST API klines fetching
  • NEW: Indicator Service - Scheduled indicator calculation

Architecture: Industry Standard - Scheduled Jobs

Exchange REST API (authoritative OHLCV data)
   ↓
Sync Service (every 60 seconds)
   β”œβ”€ Fetches latest klines via ccxt
   β”œβ”€ Initial backfill: 100 candles on startup
   β”œβ”€ Regular sync: 5 latest candles
   └─ Stores in ClickHouse (candles_1m, 5m, 1h)
   ↓
Indicator Service (every 60 seconds + 10s delay)
   β”œβ”€ Reads candles from ClickHouse
   β”œβ”€ Catch-up mode: Process all historical candles on startup
   β”œβ”€ Calculates: SMA 20/50, EMA 12/26, RSI, MACD
   β”œβ”€ Stores in ClickHouse (indicators table)
   └─ Caches in Redis (60s TTL)
   ↓
Grafana Dashboard
   └─ 4-panel layout: Price+Indicators, RSI, MACD, Volume

Key Design Decisions:

  • REST API over WebSocket: Exchange REST API provides authoritative, complete OHLCV data (WebSocket only captures ~4% of trades via sampling)
  • Scheduled jobs over event-driven: Simple, predictable, easier to debug than Kafka consumers
  • Sequential processing: Avoid ClickHouse single-connection conflicts (clickhouse_driver limitation)
  • Catch-up mode: Calculate indicators for all backfilled data on startup
  • No Materialized Views: Direct inserts from REST API, simpler schema

Tech Showcase:

  • ccxt Integration: Unified exchange REST API abstraction (Binance, Coinbase, Kraken)
  • BaseExchangeRestAPI Pattern: Cloud-agnostic REST API abstraction (mirrors WebSocket pattern)
  • Scheduled Job Architecture: 60-second intervals, 10-second offset between services
  • ClickHouse Optimization: Sequential queries to avoid connection conflicts
  • Custom Indicator Implementation: SMA, EMA, RSI, MACD without TA-Lib dependency
  • Grafana Advanced Visualization: Candlestick charts with indicator overlays, styled panels
  • Initial Backfill + Catch-up: 100 candles fetched on startup, all historical data processed

πŸ“ PHASE 3: Trading API & Strategy Framework (Day 5-6)

Goal: Build API and strategy execution engine with paper trading simulator

Minimal Features (βœ… Complete):

  • FastAPI REST endpoints:
    • GET /v1/prices/{exchange}/{symbol} - Latest price from Redis
    • GET /v1/candles/{exchange}/{symbol} - OHLCV data from ClickHouse
    • GET /v1/indicators/{exchange}/{symbol} - Technical indicators from Redis
    • GET /v1/orders / POST /v1/orders - Order management
    • GET /v1/portfolio / GET /v1/positions - Portfolio state
  • WebSocket endpoint: Real-time price streaming (/ws/prices)
  • Strategy base class/interface (BaseStrategy, Signal enum)
  • SMA Crossover strategy (SMA_20 > SMA_50 β†’ BUY, SMA_20 < SMA_50 β†’ SELL)
  • RSI Mean Reversion strategy (RSI < 30 β†’ BUY, RSI > 70 β†’ SELL)
  • Paper trading simulator (PaperBroker β€” fills at live Redis price)
  • Risk management (RiskManager β€” position sizing, daily loss limit)
  • PostgreSQL: paper_orders, paper_positions, paper_portfolio_snapshots
  • Strategy Engine Service (60s polling loop, +20s delay after Indicator Service)
  • Kafka audit trail: trading.signals, trading.orders (write-only, no consumer)
  • Grafana portfolio dashboard: equity curve, open positions, recent trades, P&L by strategy

Advanced Features (Optional β€” Phase 4+):

  • Strategy hot-reload (no restart needed)
  • Order types: Limit, Stop-Loss, Trailing Stop (Phase 3: market only)
  • Position sizing: Kelly Criterion (Phase 3: flat 10% per position)
  • Strategy parameter optimization via grid search (needs backtesting first)
  • RabbitMQ task queues (deferred β€” no value for paper trading, added in Phase 4)

Architecture Decision β€” No RabbitMQ in Phase 3:

Paper trading has no unreliable external boundary (no real exchange calls, no retries, no burst). A task queue adds zero value. Instead:

  • InlineTaskQueue β€” direct call, zero infra overhead
  • Phase 4 swaps to RabbitMQTaskQueue by changing 1 line in factory/client_factory.py

Services:

  • PostgreSQL (Docker) β€” source of truth for all paper trading state
  • FastAPI (Python service) β€” REST + WebSocket, port 8000
  • Strategy Engine (Python service) β€” 60s polling loop
  • Kafka (existing) β€” audit trail only, no new consumers

Tech Showcase:

  • Cloud-agnostic factory pattern (BaseBroker, BaseOrderStore, BaseTaskQueue)
  • PostgreSQL as source of truth (no in-memory state β€” crash-safe)
  • UUID generated at OrderManager β€” idempotent retries, no double-fills
  • Mark-to-market equity curve: cash + Ξ£(qty Γ— live_price_redis) updated every 60s
  • WebSocket fan-out for real-time price streaming
  • Kafka audit trail (fire-and-forget) for Phase 4 backtest replay

πŸ“ PHASE 4: Backtesting Engine βœ… COMPLETED

Goal: Test strategies against historical data with zero look-ahead bias

  • Backtester β€” fill at next-bar open, equity at current-bar close (intentional 1-bar lag)
  • BacktestBroker / BacktestOrderStore β€” in-memory, mirrors paper trading accounting
  • BacktestResult + compute_metrics β€” Sharpe (annualized √8760), MaxDD, win rate
  • CLI runner (services/backtest_runner/main.py) β€” argparse, ClickHouse only, --debug flag
  • JSON + CSV reports with per-trade log
  • WalkForwardRunner β€” sliding train/val windows with MLflow child runs
  • query_candles_history() β€” 2-year ClickHouse retention table for ML training data
  • 36 unit tests (including 4 look-ahead bias tests)

Key design decisions:

  • candles_1h_history table (730d TTL) separate from candles_1h (90d TTL) β€” backtests need full history
  • No Redis/Postgres required β€” ClickHouse only for speed
  • limit=None in query_candles for full date-range (never mix numeric limit + date range)

πŸ“ PHASE 5: ML/AI Integration βœ… COMPLETED

Goal: LightGBM regime classifier + volatility sizing model + MLflow tracking

  • FeaturePipeline β€” 10 regime features + 16 sizing features (superset)
  • LabelGenerator β€” rule-based pseudo-labeling, +1 bar shift (leak-free), train_atr_median explicit param
  • RegimeClassifier β€” LightGBM 3-class (trending/ranging/high_vol), thread-safe predict
  • SizingModel β€” LightGBM regressor predicting 24h forward realized vol
  • MLPositionSizer β€” dynamic target_vol, clamped [25%, 150%], fail-safe returns base_qty
  • VolatilityBreakoutStrategy β€” BUY on bb_position>0.95 + volume + ADX + regime gate
  • RegimeAwareStrategy β€” circuit breaker p_high_vol>0.60 β†’ HOLD; delegates to breakout or mean_reversion
  • MLflow Docker service (port 5000, PostgreSQL backend + LocalStack S3)
  • New indicators: ATR, ADX, BollingerBands, VolumeRatio, ZScore
  • ClickHouse migration 007: candles_1h_history (730d TTL)
  • 86 new unit tests

πŸ“ PHASE 6: Multi-Strategy Adaptive Portfolio Engine (MSAPE) βœ… COMPLETED

Goal: MVO-based multi-strategy portfolio with two-layer regime gating

Two-layer architecture:

Layer 1 (per-strategy regime gate):
  MATrendStrategy:            HOLD if regime_trending < 0.55
  RSIMeanReversionStrategy:   HOLD if regime_ranging  < 0.40
  VolatilityBreakoutStrategy: HOLD if regime_trending < 0.55

Layer 2 (portfolio MVO weights):
  EMA-smoothed Sharpe β†’ SLSQP MVO β†’ MRC cap β†’ weekly rebalance
  Vol overlay: leverage = target_vol / port_vol, clamped [0.5, 1.5]
  • domain/portfolio/ β€” pure numpy/scipy computation, no I/O
    • returns_matrix.py β€” align N equity curves β†’ forward-filled ReturnsMatrix
    • performance_engine.py β€” rolling Sharpe/Vol/MaxDD/LedoitWolf covariance
    • allocation_engine.py β€” stateful EMA-smoothed Sharpe β†’ MVO
    • vol_overlay.py β€” leverage scaling
  • PortfolioBacktester β€” N sequential sub-backtests β†’ bar-by-bar MVO simulation
  • PortfolioEngine (live) β€” reads Redis indicators β†’ MVO weights β†’ paper orders
  • CLI (services/portfolio_runner/main.py) β€” --use-yaml-slots, --regime-filter
  • MATrendStrategy β€” EMA50/200 crossover; requires "close" key in indicators dict
  • create_portfolio_backtester(use_regime_filter=False) β€” loads classifier from MLflow
  • Grafana portfolio dashboard
  • 46 new unit tests

πŸ“ PHASE 7a: Meta-Labeling βœ… COMPLETED

Goal: Filter strategy signals by trade quality confidence

  • triple_barrier_label() β€” PT/SL/timeout barriers; entry at next bar's open (look-ahead-free)
  • MetaLabeler β€” LightGBM binary; drops y==0 (timeout); threshold=0.55; untrained returns 0.5
  • Backtester meta_labeler param β€” after signal, if meta_confidence < threshold β†’ HOLD
  • --meta-labeler flag in backtest_runner/main.py
  • --train-meta-labeler --strategy <name> in ml_trainer/main.py
  • Factory: create_meta_labeler(), load_meta_labeler()
  • Config: ml.yaml meta_labeler section (pt_pct=0.015, sl_pct=0.008, max_hold_bars=48)
  • 17 unit tests

πŸ“ PHASE 7b: Short Selling + AdaptiveTrendStrategy βœ… COMPLETED

Goal: Long-short capability with ATR trailing stop

  • Signal.SHORT + Signal.COVER added to signal enum
  • BacktestOrderStore β€” SHORT (negative qty, cash+=), COVER (cash-=, PnL=(entry-cover)Γ—qty-commission)
  • BacktestBroker / PaperBroker β€” margin validation for SHORT, position validation for COVER
  • RiskManager β€” reject double-short, reject COVER with no short; symbol param in calculate_quantity
  • AdaptiveTrendStrategy β€” EMA+ATR long-short; BUY/SHORT on entry, SELL/COVER on ATR trailing stop; stateful; regime gate
  • 19 unit tests (short selling), 17 unit tests (adaptive trend)
  • Total: 470 unit tests passing

πŸ“ PHASE 7c: SHORT/COVER Integration Fixes βœ… COMPLETED

Goal: Close real bugs found after Phase 7b code review

  • OrderManager.process_signal() β€” add symbol=symbol to calculate_quantity call (bug: multi-symbol SELL/COVER used wrong position)
  • ml_trainer/main.py β€” capture Signal.SHORT in addition to Signal.BUY for meta-labeler training
  • Docstring updates: generate_signal(), validate(), process_signal()

πŸ“ PHASE 8: Alpha Factory πŸ”œ NEXT

Goal: Move from ~7 alphas to 20-30 validated signals using quant-grade validation

Execution order: B β†’ C β†’ A


8B β€” Signal Quality Filter (Layer 3: Alpha Validation)

Problem diagnosed from backtest: ma_trend (1,561 trades) and adaptive_trend (2,187 trades) lose 14–20% of capital to commission. Signal frequency is too high β€” not signal direction.

Plan:

  • Add min_confirmation_bars: int parameter to MATrendStrategy and AdaptiveTrendStrategy
    • Require N consecutive bars of signal confirmation before entry (default: 3)
    • Reduces ma_trend trades: 1,561 β†’ ~200, commission $1,512 β†’ ~$200
  • IC (Information Coefficient) framework in domain/alpha/ic.py
    • compute_ic(factor_values, forward_returns, periods=[1,4,8,24]) β€” Spearman rank correlation
    • IC > 0.02 = weak signal, > 0.05 = usable, > 0.10 = strong
  • Decay analysis β€” IC rolling window to detect when signal loses edge
  • Factor correlation matrix β€” prevent redundant alphas from dominating portfolio
  • services/alpha_lab/ β€” standalone script to evaluate new factors before wiring into strategies

Key files:

domain/alpha/
  ic.py              # IC + ICIR computation
  decay.py           # Rolling IC decay analysis
  correlation.py     # Factor cross-correlation matrix
services/alpha_lab/
  evaluate.py        # CLI: evaluate a factor against forward returns

8C β€” Data Expansion (Layer 2: Feature Engineering)

Problem: All current features are price-derived. Quant funds use data price cannot provide.

Plan:

  • Funding rate β€” Binance perpetual futures (ccxt: exchange.fetch_funding_rate)
    • Negative funding = shorts paying longs = forced short covering imminent
    • Extreme positive funding = overleveraged longs = mean reversion setup
  • Open interest β€” exchange.fetch_open_interest via ccxt
    • Rising OI + rising price = trend confirmation
    • Rising OI + falling price = capitulation risk
  • Cross-asset momentum β€” BTC 24h return as feature for ETH/SOL/BNB strategies
    • BTC leads altcoins by ~1-4 hours on large moves
  • Basis β€” spot vs futures price spread (when futures available)
  • Store in trading.market_context ClickHouse table (hourly snapshots)
  • Inject into FeaturePipeline as additional features
  • Add to indicators.yaml and config/settings.py

Key files:

providers/binance/futures.py         # Funding rate + OI fetcher
services/context_service/main.py     # Hourly market context collector
domain/ml/features.py                # Add FUNDING_FEATURES, OI_FEATURES
infrastructure/docker/clickhouse/migrations/008_market_context.sql

8A β€” Alpha Factory Scale-up (Layer 2+3: More Alphas + Validation)

Goal: Expand from 7 alphas to 20-30 using IC-validated factors

Candidate alpha families:

Family Examples IC target
Momentum 4h/12h/24h/72h price return, ROC 0.03–0.06
Seasonality hour-of-day, day-of-week return patterns 0.02–0.04
Microstructure bid-ask spread proxy, trade imbalance 0.04–0.08
Funding carry funding rate z-score, cumulative funding 0.05–0.10
Cross-asset BTC/ETH relative strength, BTC dominance delta 0.03–0.07
Volatility regime realized vol percentile rank, VIX analogue 0.03–0.06

Process for each alpha:

  1. Compute factor β†’ 2. IC test (needs IC > 0.03) β†’ 3. Decay check (still predictive at 8h+?) β†’ 4. Correlation check (< 0.60 with existing alphas) β†’ 5. Add to strategy or FeaturePipeline

Key files:

domain/alpha/
  momentum.py        # Multi-period price momentum factors
  seasonality.py     # Calendar-based return patterns
  carry.py           # Funding rate carry factors
  cross_asset.py     # BTC-relative strength signals
services/alpha_lab/
  backtest_alpha.py  # Fast vectorized alpha backtest (no strategy overhead)
  report.py          # IC, decay, correlation summary report

πŸ› οΈ Tech Stack Details

Messaging Architecture: Kafka vs RabbitMQ

When to use Kafka (Data Streaming):

  • βœ… Market data ingestion (trades, order books)
  • βœ… Event streaming with replay capability
  • βœ… Multiple consumers need same data
  • βœ… High throughput (60+ symbols, thousands msg/sec)
  • βœ… Message retention (24h+) for backtesting
  • βœ… Analytics pipelines

When to use RabbitMQ (Task Queues):

  • βœ… Order execution (need acknowledgment)
  • βœ… Priority queues (urgent stop-loss first)
  • βœ… Dead letter queues (failed task handling)
  • βœ… Work distribution (backtest jobs to workers)
  • βœ… Notifications (email, telegram)
  • βœ… Long-running async jobs

Implementation:

# factory/client_factory.py
def create_stream_client() -> BaseStreamClient:
    """Kafka/Kinesis for data streaming"""
    if settings.CLOUD_PROVIDER == "opensource":
        return KafkaStreamClient()
    elif settings.CLOUD_PROVIDER == "aws":
        return KinesisStreamClient()

def create_task_queue() -> BaseTaskQueue:
    """RabbitMQ/SQS for task queues (Phase 3+)"""
    if settings.CLOUD_PROVIDER == "opensource":
        return RabbitMQClient()
    elif settings.CLOUD_PROVIDER == "aws":
        return SQSClient()

LocalStack (AWS Services Emulation)

  • S3: Object storage for raw data, backups, ML artifacts
  • Kinesis: Real-time data streaming (alternative to Kafka)
  • Lambda: Serverless compute for event processing
  • DynamoDB: NoSQL database for high-throughput data
  • EventBridge: Event bus for decoupled architecture
  • SQS/SNS: Message queuing and pub/sub
  • API Gateway: REST/WebSocket API endpoints
  • CloudWatch: Logging and metrics
  • Secrets Manager: Secure credential storage
  • Step Functions (optional): Workflow orchestration

Stateful Services (Docker or Cloud Managed)

Data Storage

  • ClickHouse: Time-series OLAP database (billions of ticks)
    • Local: Docker container
    • Cloud: ClickHouse Cloud, Altinity Cloud
  • Redis: In-memory caching (latest prices, positions)
    • Local: Docker container
    • Cloud: Upstash Redis, AWS ElastiCache
  • PostgreSQL: Relational metadata (strategies, users, configs)
    • Local: Docker container
    • Cloud: Supabase, Neon, AWS RDS

ML & Analytics

  • Jupyter: Interactive data exploration
  • MLflow: Experiment tracking, model registry
  • scikit-learn, XGBoost, LightGBM: Traditional ML
  • TensorFlow/PyTorch: Deep learning (LSTM, Transformers)

Monitoring & Visualization

  • Grafana: Real-time operational dashboards (Docker)
  • Prometheus: Metrics collection (Docker)

Application Layer

  • Python 3.10+: Primary language
  • boto3: AWS SDK (works with LocalStack)
  • FastAPI: High-performance API framework
  • Pydantic: Data validation
  • SQLAlchemy: ORM for PostgreSQL
  • clickhouse-connect: ClickHouse Python client
  • redis-py: Redis Python client

Infrastructure as Code

  • AWS CDK (recommended): Define LocalStack + AWS resources in Python
  • Terraform (alternative): HCL-based IaC
  • LocalStack Docker Compose: Service orchestration

πŸ“¦ Services Breakdown

Minimal Stack (LocalStack + Core Services - ~3GB RAM)

LocalStack (unified container):
- All AWS services (S3, Kinesis, Lambda, DynamoDB, etc.) - 512MB

Docker Stateful Services:
- clickhouse (1.5GB)
- redis (256MB)
- postgres (512MB)
- grafana (256MB)

Python Services (run locally, not Docker):
- market-data-ingestion (256MB)
- trading-api (512MB)

Full Stack (All Services - ~8GB RAM)

+ LocalStack Pro features (optional)
+ jupyter (1GB)
+ mlflow (512MB)
+ prometheus (512MB)
+ Additional Lambda functions
+ Step Functions workflows

Cloud Alternative (Zero Local Resources)

Replace all with managed services:
- LocalStack β†’ Real AWS (free tier)
- Docker ClickHouse β†’ ClickHouse Cloud ($300 credit)
- Docker Redis β†’ Upstash Redis (free tier)
- Docker Postgres β†’ Supabase (free tier)
- Python services β†’ AWS Lambda or Railway

πŸš€ Quick Start

Prerequisites

  • Docker & Docker Compose
  • Python 3.10+
  • 8GB+ RAM (minimal), 16GB+ recommended (full stack)
  • 20GB+ disk space

1. Clone & Setup

git clone <repo-url>
cd DataPlatform

# Copy environment template
cp .env.example .env.local

2. Start Minimal Stack (Phase 1)

# Start LocalStack + stateful services
docker-compose up -d

# Services started:
# - localstack (all AWS services)
# - clickhouse
# - redis
# - postgres
# - grafana

# Check services health
docker-compose ps

# View logs
docker-compose logs -f localstack

3. Run Services (Phase 2)

Run in this order to ensure proper data flow:

# Terminal 1: Market Data Ingestion (WebSocket β†’ Redis signals)
uv run python services/market_data_ingestion/main.py

# Terminal 2: Sync Service (REST API β†’ ClickHouse candles, every 60s)
uv run python services/sync_service/main.py

# Terminal 3: Indicator Service (ClickHouse β†’ Calculate β†’ Redis/ClickHouse, every 60s)
uv run python services/indicator_service/main.py

4. Access Dashboards

5. Verify Data Flow

# Check LocalStack health
curl http://localhost:4566/_localstack/health

# List S3 buckets (LocalStack)
aws --endpoint-url=http://localhost:4566 s3 ls

# Check Kinesis stream (LocalStack)
aws --endpoint-url=http://localhost:4566 kinesis list-streams

# Query ClickHouse
curl "http://localhost:8123/?query=SELECT count() FROM trades"

🌐 Local β†’ Cloud Migration

Configuration-Based Deployment

All services use environment variables for endpoints:

# .env.local (LocalStack + Docker)
AWS_ENDPOINT_URL=http://localhost:4566
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test

CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
REDIS_URL=redis://localhost:6379
POSTGRES_URL=postgresql://admin:password@localhost:5432/trading

# .env.cloud (Production AWS)
AWS_ENDPOINT_URL=  # Empty = use real AWS
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=<real-key>
AWS_SECRET_ACCESS_KEY=<real-secret>

CLICKHOUSE_HOST=abc123.clickhouse.cloud
REDIS_URL=rediss://username:password@redis.cloud:6379
POSTGRES_URL=postgresql://user:pass@db.supabase.com/postgres

Switch Environments

# Local development with LocalStack
cp .env.local .env
docker-compose up -d
python services/market-data-ingestion/main.py

# Production (real AWS + managed databases)
cp .env.cloud .env
# Deploy Lambda functions
cd infra
cdk deploy  # or terraform apply

# Code remains IDENTICAL - boto3 SDK uses env vars!

Cloud Deployment Options

Option A: Docker on Cloud VM (easiest)

# On AWS EC2 / GCP Compute / Azure VM
git clone <repo>
docker-compose -f docker-compose.cloud.yml up -d

Option B: Managed Services

  • Kafka: Confluent Cloud, AWS MSK, Aiven
  • ClickHouse: ClickHouse Cloud, Altinity.Cloud
  • Redis: AWS ElastiCache, Redis Cloud
  • PostgreSQL: AWS RDS, Google Cloud SQL, Supabase
  • Airflow: Astronomer, Google Cloud Composer

Option C: Kubernetes

# Using Helm charts
helm install trading ./helm/trading-platform

πŸ“ˆ Project Milestones

Phase Status Can Demo Technical Highlights
Phase 1 βœ… Complete Real-time prices WebSocket, multi-exchange, ClickHouse
Phase 2 βœ… Complete Charts + indicators REST API sync, scheduled jobs, SMA/EMA/RSI/MACD
Phase 3 βœ… Complete Paper trading live FastAPI, strategy engine, PostgreSQL
Phase 4 βœ… Complete Backtest CLI + reports Backtester, walk-forward, JSON/CSV output
Phase 5 βœ… Complete ML regime classifier LightGBM 3-class, MLflow, vol sizing model
Phase 6 βœ… Complete Portfolio engine MSAPE, MVO, two-layer regime gates
Phase 7a βœ… Complete Meta-labeling Triple-barrier labels, LightGBM quality filter
Phase 7b βœ… Complete Long-short trading SHORT/COVER signals, AdaptiveTrendStrategy
Phase 7c βœ… Complete Bug fixes symbol param in calculate_quantity, ml_trainer SHORT capture
Phase 8B πŸ”œ Next Signal quality IC framework, confirmation bars, decay analysis
Phase 8C πŸ”œ Planned Alt data Funding rate, open interest, cross-asset momentum
Phase 8A πŸ”œ Planned Alpha factory 20-30 IC-validated factors, alpha lab CLI

Current: 470 unit tests passing | 12 strategies backtested | 4-asset portfolio live


πŸŽ“ Learning Outcomes

By completing this project, you will master:

Data Engineering

  • Stream processing architectures
  • Time-series database optimization
  • Data pipeline orchestration
  • ETL/ELT patterns

Backend Development

  • REST + WebSocket APIs
  • Event-driven microservices
  • Caching strategies
  • Database design

Machine Learning

  • Time-series forecasting
  • Feature engineering
  • Model training & evaluation
  • MLOps practices

DevOps

  • Containerization (Docker)
  • Infrastructure as Code
  • Monitoring & alerting
  • CI/CD pipelines

System Design

  • Distributed systems
  • Scalability patterns
  • Fault tolerance
  • Performance optimization

πŸ“Š Performance Targets

Latency

  • Market data ingestion β†’ ClickHouse: < 100ms (p99)
  • Strategy signal generation: < 50ms
  • API response time: < 100ms (p95)
  • ML model inference: < 50ms

Throughput

  • Market data ingestion: 10,000+ trades/second
  • Strategy evaluations: 1,000+ per second
  • API requests: 5,000+ req/second

Data Volume

  • 100M+ ticks per day (~1GB/day compressed)
  • 1B+ ticks for backtesting (2020-2024)
  • Query performance: Sub-second on billions of rows

πŸ” Security Considerations

Minimal (Phase 1-4)

  • Environment variables for secrets
  • Docker network isolation
  • Read-only API keys (exchange APIs)

Production (Phase 6)

  • API authentication (JWT)
  • Rate limiting
  • Input validation
  • HTTPS/TLS encryption
  • Secrets management (Vault, AWS Secrets Manager)
  • Network policies (firewall rules)
  • Regular security audits

πŸ§ͺ Testing Strategy

Unit Tests

  • Strategy logic
  • Technical indicators calculation
  • Data validation

Integration Tests

  • Kafka β†’ ClickHouse pipeline
  • API endpoints
  • ML model inference

Performance Tests

  • Load testing (Locust, K6)
  • Stress testing (max throughput)
  • Latency benchmarks

Backtests

  • Historical strategy validation
  • Out-of-sample testing
  • Walk-forward analysis

πŸ“š Resources & References

Documentation

Data Sources

Learning

  • Kaggle: Crypto/Stock datasets
  • QuantConnect: Algorithmic trading tutorials
  • TradingView: Technical analysis

🀝 Contributing

This is a learning project showcasing technical skills. Feel free to:

  • Fork and customize for your use case
  • Submit issues for bugs/improvements
  • Share your results and learnings

⚠️ Disclaimer

Educational & Research Purposes Only

This platform is built for:

  • Learning data engineering and ML concepts
  • Portfolio demonstration
  • Academic research

NOT intended for:

  • Real money trading without extensive modifications
  • Production use without proper risk management
  • Financial advice

Trading involves significant risk of loss. Past performance does not guarantee future results.


πŸ”„ Database Migrations (Alembic) - Phase 4+

Why Alembic?

Phase 1-3 (Development): Use postgres/init.sql (simple, fast iteration)

  • Schema is simple and changes infrequently
  • Can docker-compose down -v to recreate database
  • No production data to preserve

Phase 4+ (Production): Migrate to Alembic (version control, safety)

  • Have production data (cannot recreate database)
  • Schema changes need to be tracked and reversible
  • Team collaboration requires migration history

Setup Alembic

# Install
pip install alembic psycopg2-binary

# Initialize (creates migrations/ folder)
alembic init migrations

# Configure
# Edit migrations/env.py to use config/settings.py

migrations/env.py:

from config.settings import get_settings
settings = get_settings()

config.set_main_option("sqlalchemy.url", settings.postgres_dsn)

Create Migrations

Auto-generate from SQLAlchemy models:

# After changing models in domain/models/
alembic revision --autogenerate -m "add phone_number to users"

# Review the generated migration
# Edit migrations/versions/xxx_add_phone_number.py if needed

Manual migration:

alembic revision -m "add index on orders.symbol"

migrations/versions/001_add_phone.py:

from alembic import op
import sqlalchemy as sa

def upgrade():
    op.add_column('users',
        sa.Column('phone_number', sa.String(20), nullable=True)
    )
    op.create_index('idx_users_phone', 'users', ['phone_number'])

def downgrade():
    op.drop_index('idx_users_phone')
    op.drop_column('users', 'phone_number')

Apply Migrations

Local development:

# Apply all pending migrations
alembic upgrade head

# Rollback one migration
alembic downgrade -1

# Check current version
alembic current

# View migration history
alembic history

Production deployment:

# In Dockerfile or docker-compose
CMD alembic upgrade head && python main.py

docker-compose.yml:

services:
  trading-api:
    build: .
    command: >
      sh -c "alembic upgrade head &&
             uvicorn main:app --host 0.0.0.0"
    depends_on:
      postgres:
        condition: service_healthy

Migration Best Practices

1. Always test migrations:

# Test upgrade
alembic upgrade head

# Test downgrade
alembic downgrade -1

# Test re-upgrade
alembic upgrade head

2. Never modify old migrations:

  • Create new migration to fix issues
  • Old migrations are history (like Git commits)

3. Review auto-generated migrations:

  • Alembic may miss some changes
  • Check nullable, defaults, indexes

4. Use transactions:

def upgrade():
    with op.get_context().autocommit_block():
        # DDL statements here
        pass

5. Data migrations:

def upgrade():
    # Schema change
    op.add_column('users', sa.Column('status', sa.String(20)))

    # Data migration
    connection = op.get_bind()
    connection.execute(
        "UPDATE users SET status = 'active' WHERE is_active = true"
    )

CI/CD Integration

GitHub Actions:

- name: Run migrations
  run: |
    alembic upgrade head

- name: Run tests
  run: pytest

Deployment script:

#!/bin/bash
# deploy.sh

# Backup database
pg_dump $DB_URL > backup_$(date +%Y%m%d_%H%M%S).sql

# Run migrations
alembic upgrade head

# Deploy app
docker-compose up -d --build

Converting from init.sql to Alembic

Step 1: Initial migration from existing schema

# Start with empty migrations
alembic init migrations

# Create initial migration matching current init.sql
alembic revision -m "initial schema"

Step 2: Copy init.sql content to migration:

# migrations/versions/001_initial.py
def upgrade():
    # Copy CREATE TABLE statements from init.sql
    op.execute("""
    CREATE TABLE IF NOT EXISTS users (
        id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
        ...
    )
    """)

Step 3: Mark as applied (don't re-run on existing DB):

# On existing database
alembic stamp head

# On new database
alembic upgrade head

Step 4: Future changes use Alembic

# All new schema changes
alembic revision --autogenerate -m "add new column"
alembic upgrade head

Troubleshooting

Migration conflicts:

# Multiple developers created migrations
# Merge and renumber
alembic merge heads -m "merge migrations"

Reset migrations (development only!):

# WARNING: Deletes all data!
docker-compose down -v
rm -rf migrations/versions/*
alembic revision -m "initial"
# Recreate schema in migration
alembic upgrade head

πŸ“ License

MIT License - See LICENSE file for details


🎯 Next Steps (Phase 8B)

# Run all strategy backtests (2022–2026)
CLICKHOUSE_HOST=localhost uv run python services/backtest_runner/main.py \
  --strategy volatility_breakout --symbol SOLUSDT \
  --exchange binance --timeframe 1h \
  --start 2022-01-01 --end 2026-02-27

# Run portfolio with regime filter
CLICKHOUSE_HOST=localhost uv run python services/portfolio_runner/main.py \
  --use-yaml-slots --exchange binance --timeframe 1h \
  --start 2022-01-01 --end 2026-02-27 --regime-filter

# Run unit tests
uv run pytest tests/unit/ -v          # 470 tests

# Train meta-labeler
uv run python services/ml_trainer/main.py \
  --train-meta-labeler --strategy adaptive_trend \
  --symbol BTCUSDT --start 2022-01-01 --end 2024-12-31

Questions or Issues?

  • Check CLAUDE.md for architecture guide and design decisions
  • Check /docs folder for detailed guides

Built with ❀️ for learning and showcasing technical expertise

Keywords: #DataEngineering #MachineLearning #AlgorithmicTrading #StreamProcessing #ClickHouse #Kafka #Python #FastAPI #Docker #CloudNative

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages