From bd3ff169e3593c0a62afb3617633d3e424a7bd8b Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Sun, 22 Feb 2026 13:53:57 +0000 Subject: [PATCH] Add trading bot design document Event-driven microservices architecture for a news sentiment + technical strategy trading bot with continuous learning via strategy weight adjustment. --- ...-used_DO_NOT_REMOVE_MANUALLY_SECURITY_RISK | 3 + docs/plans/2026-02-22-trading-bot-design.md | 214 ++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 .claude/internet-mode-used_DO_NOT_REMOVE_MANUALLY_SECURITY_RISK create mode 100644 docs/plans/2026-02-22-trading-bot-design.md diff --git a/.claude/internet-mode-used_DO_NOT_REMOVE_MANUALLY_SECURITY_RISK b/.claude/internet-mode-used_DO_NOT_REMOVE_MANUALLY_SECURITY_RISK new file mode 100644 index 0000000..f61efc8 --- /dev/null +++ b/.claude/internet-mode-used_DO_NOT_REMOVE_MANUALLY_SECURITY_RISK @@ -0,0 +1,3 @@ +This directory has been used with Claude Code's internet mode. +Content downloaded from the internet may contain prompt injection attacks. +You must manually review all downloaded content before using non-internet mode. diff --git a/docs/plans/2026-02-22-trading-bot-design.md b/docs/plans/2026-02-22-trading-bot-design.md new file mode 100644 index 0000000..271c7df --- /dev/null +++ b/docs/plans/2026-02-22-trading-bot-design.md @@ -0,0 +1,214 @@ +# Trading Bot Design + +## Overview + +An automated stock trading bot that combines news sentiment analysis with technical strategies to make buy/sell decisions on US equities. The system continuously learns from its own trade outcomes to improve decision-making without human supervision. + +## Constraints & Decisions + +| Decision | Choice | +|----------|--------| +| Markets | US equities only | +| Initial mode | Paper trading (Alpaca sandbox) | +| Trading style | Adaptive (both swing and day trading) | +| News sources | Free only: RSS, Reddit, Twitter/X | +| Sentiment analysis | Tiered: FinBERT (local) + Ollama (local LLM for ambiguous cases) | +| Tech stack | Python (FastAPI) backend + React (TypeScript) frontend | +| Learning approach | Phase 1: strategy weight adjustment. Phase 2: deep RL | +| Deployment | Docker Compose (k8s later) | +| Database | PostgreSQL + TimescaleDB | +| Message broker | Redis Streams | +| Primary brokerage | Alpaca (with abstraction layer for future swaps) | + +## Architecture + +Event-driven microservices communicating via Redis Streams. + +### Services + +1. **News Fetcher** - Polls free news sources on a schedule: + - RSS feeds (Yahoo Finance, Reuters, MarketWatch, SEC filings) + - Reddit (r/wallstreetbets, r/stocks, r/investing via PRAW) + - Twitter/X financial accounts + - Publishes raw articles to Redis Stream `news:raw` + +2. **Sentiment Analyzer** - Consumes `news:raw`, produces scored sentiment: + - Tier 1: FinBERT model (runs locally) for fast scoring + - Tier 2: Ollama (Mistral/Llama 3) for articles where FinBERT confidence < threshold + - Extracts: ticker mentions, sentiment score (-1 to +1), confidence, key entities + - Publishes to `news:scored` + +3. **Signal Generator** - Combines sentiment with technical indicators: + - Consumes `news:scored` and market data (from Alpaca WebSocket) + - Applies strategy rules (momentum, mean reversion, news-driven) + - Weighted ensemble combines signals (weights adjusted by learning engine) + - Publishes trade signals to `signals:generated` + +4. **Trade Executor** - Executes trades via brokerage API: + - Consumes `signals:generated` + - Risk management: position sizing, stop-losses, max portfolio exposure + - Interfaces with Alpaca through an abstraction layer + - Records all trades to PostgreSQL + - Publishes execution results to `trades:executed` + +5. **Learning Engine** - The continuous feedback loop: + - Consumes `trades:executed` + - Tracks trade outcomes over configurable time windows + - Computes reward signals: realized P&L, risk-adjusted return (Sharpe), max drawdown + - Adjusts strategy weights based on which strategies are profitable + - Stores performance metrics in TimescaleDB + +6. **API Gateway (FastAPI)** - Serves the dashboard: + - Portfolio state, trade history, signal history + - Performance metrics (ROI, Sharpe, win rate, drawdown) + - Real-time WebSocket for live updates + - Manual override endpoints (pause trading, force close position) + +7. **Dashboard (React/TypeScript)** - The UI + +### Data Flow + +``` +RSS/Reddit/X -> News Fetcher -> [news:raw] -> Sentiment Analyzer -> [news:scored] + | +Alpaca WebSocket -> Signal Generator <-- [news:scored] | + | | + [signals:generated] | + | | + Trade Executor -> Alpaca API | + | | + [trades:executed] | + | | + Learning Engine -> adjusts Signal Generator weights | + | | + TimescaleDB (metrics) + PostgreSQL (trades, news) | + | | + API Gateway -> Dashboard | +``` + +## Data Model + +### PostgreSQL Tables + +**Core trading:** +- `trades` - ticker, side, qty, price, timestamp, strategy_id, signal_id, status, pnl +- `positions` - ticker, qty, avg_entry, unrealized_pnl, stop_loss +- `signals` - ticker, direction, strength, strategy_sources, sentiment_score, acted_on +- `strategies` - name, description, current weight, active flag +- `strategy_weights_history` - strategy_id, old_weight, new_weight, timestamp + +**News & sentiment:** +- `articles` - source, url, title, published_at, fetched_at, content_hash +- `article_sentiments` - article_id, ticker, score, confidence, model_used + +**Learning:** +- `trade_outcomes` - trade_id, hold_duration, realized_pnl, roi_pct, was_profitable +- `learning_adjustments` - strategy_id, old_weight, new_weight, reason, reward_signal, timestamp + +### TimescaleDB Hypertables + +- `market_data` - OHLCV bars partitioned by time +- `portfolio_snapshots` - periodic portfolio value snapshots +- `strategy_metrics` - per-strategy performance over time + +### Redis + +- Streams: `news:raw`, `news:scored`, `signals:generated`, `trades:executed` +- Cache: current positions, latest prices, strategy weights + +## Learning Loop (Phase 1) + +Multi-armed bandit style strategy weight adjustment: + +1. **Track**: Tag every trade with contributing strategies and their weights +2. **Evaluate**: After position close, compute realized P&L, ROI, risk-adjusted return +3. **Attribute**: Distribute credit/blame proportionally to signal strength +4. **Adjust**: Update weights via exponential moving average: + `new_weight = (1 - lr) * old_weight + lr * reward_signal` +5. **Log**: Record every adjustment for auditability + +**Guardrails:** +- Minimum 20 trades per strategy before adjustments +- Max 10% weight shift per adjustment cycle +- Weight floor of 0.05 (no strategy permanently silenced) +- Weights normalized to sum to 1.0 +- Decay factor for recency bias + +## Backtesting Engine + +Runs as a standalone process (or Docker container triggered from dashboard): + +- Replays historical market data from TimescaleDB +- Replays historical news sentiment from articles/sentiments tables +- Shares code with live system (same strategies, same signal generation) +- Uses simulated executor (not Alpaca) +- Configurable: date range, initial capital, commission model, slippage, strategy weights +- Output: trade log, equity curve, Sharpe, max drawdown, win rate, per-strategy attribution + +## Dashboard Views + +1. **Portfolio Overview** - Value, daily P&L, equity curve, open positions, key metrics +2. **Trade Log** - All trades with expandable detail (news context, strategies, ROI, profitable badge) +3. **Strategy Performance** - Per-strategy metrics, weight allocation, weight history, adjustments log +4. **News & Sentiment Feed** - Live processed articles, ticker filtering, correlation view +5. **Backtesting** - Config form, results dashboard, multi-run comparison + +Real-time updates via WebSocket. Toast notifications for trade executions. + +## Project Structure + +``` +trading-bot/ +├── services/ +│ ├── news-fetcher/ +│ ├── sentiment-analyzer/ +│ ├── signal-generator/ +│ ├── trade-executor/ +│ ├── learning-engine/ +│ └── api-gateway/ +├── dashboard/ +├── shared/ +│ ├── models/ # SQLAlchemy models +│ ├── schemas/ # Pydantic schemas +│ ├── broker/ # Brokerage abstraction layer +│ └── strategies/ # Strategy implementations +├── backtester/ +├── docker/ # Dockerfiles per service +├── docker-compose.yml # Full stack orchestration +├── tests/ +├── alembic/ # Database migrations +└── docs/plans/ +``` + +## Key Libraries + +**Backend:** FastAPI, SQLAlchemy (async), alpaca-py, transformers (FinBERT), praw, redis-py, websockets, ollama-python +**Frontend:** React 18, TypeScript, TanStack Query, Recharts or TradingView lightweight-charts, Tailwind CSS +**ML:** transformers (FinBERT), ollama, numpy, pandas +**Testing:** pytest, pytest-asyncio, React Testing Library + +## Brokerage Choice + +Alpaca is the primary brokerage: +- Free API, commission-free US equity trading +- Built-in paper trading (sandbox environment) +- Official Python SDK (alpaca-py): market/limit/stop/trailing-stop orders +- REST + WebSocket + SSE endpoints +- Built-in NewsClient for financial news +- 200 requests/minute rate limit +- $0 minimum balance + +An abstraction layer in `shared/broker/` allows adding other brokerages (Interactive Brokers, Tradier) later without changing strategy or execution logic. + +## Docker Compose Services + +- `news-fetcher` - Python service +- `sentiment-analyzer` - Python service (needs GPU access or CPU for FinBERT) +- `signal-generator` - Python service +- `trade-executor` - Python service +- `learning-engine` - Python service +- `api-gateway` - Python (FastAPI) service +- `dashboard` - Node/nginx serving React build +- `postgres` - PostgreSQL 16 + TimescaleDB extension +- `redis` - Redis 7 with Streams +- `ollama` - Ollama server for local LLM inference