Apex Terminal — DevPost Project Story
Inspiration
Every retail trader knows the frustration: the tools available to us are either painfully basic (think Robinhood's single-line charts) or absurdly expensive (Bloomberg Terminal at \$24,000/year). There's a massive gap in the middle — serious retail traders who want institutional-grade analytics, real-time data, and AI-driven insights without mortgaging their house.
The moment the idea clicked was during a late-night trading session. I was juggling six browser tabs — TradingView for charts, Yahoo Finance for news, a spreadsheet for position tracking, Alpaca's dashboard for orders, and two more tabs for options data. I thought:
"Why can't I have everything Bloomberg has — charting, portfolio analytics, autopilot trading, risk management, options Greeks, backtesting — in a single, beautifully designed terminal that runs on localhost?"
That was the spark. Apex Terminal was born from the conviction that a solo developer, armed with modern frameworks and AI, could build a Bloomberg-class workstation from scratch.
The trading world also lacks transparency in decision-making. Most platforms give you data, but they don't give you an AI copilot that explains why it's buying AAPL at this exact moment, or shows you the full signal → score → order pipeline. I wanted to build something where the autopilot's brain is fully visible — every cycle, every candidate score, every risk check — laid bare for the trader to audit.
What It Does
Apex Terminal is a full-stack Bloomberg-style trading workstation packed with features that would normally require a team of 50 and a year of development:
Core Features
- 📊 Live Candlestick Charting — TradingView-quality charts powered by
lightweight-charts v5with 35+ server-side technical indicators (SMA, EMA, VWAP, RSI, MACD, Bollinger Bands, ATR, Ichimoku Cloud, Stochastic, OBV, MFI, and more) - 🤖 Autopilot AI Paper Trading Engine — A multi-signal autonomous trading system that scans a configurable symbol universe, scores candidates using a composite signal model, executes paper trades via Alpaca, and maintains a full audit trail
- 💼 Real-Time Portfolio — Live positions and P&L via Alpaca paper account with Sharpe ratio, max drawdown, volatility KPIs, and equity curve with drawdown overlay
- 📈 Options Chain — Full options chain with Black-Scholes Greeks (\(\Delta\), \(\Gamma\), \(\nu\), \(\Theta\), IV) computed server-side
- ⚡ Backtesting Engine — Run historical strategy backtests with walk-forward analysis, Monte Carlo simulation, and multi-strategy comparison
- 🛡️ Risk Management — Position sizing, exposure analysis, stress testing, margin monitoring, and compliance checks
- 🔍 Elasticsearch-Powered Search — Full-text search with faceted filters, KNN vector similarity, and saved search templates
- 🧠 AI Agents — Pluggable agent architecture for research, sentiment analysis, and strategy generation
- 📰 Live News & Sentiment — Real-time financial news aggregation with NLP-based sentiment scoring
By The Numbers
| Metric | Value |
|---|---|
| Frontend TypeScript/TSX files | 888 |
| Frontend lines of code | 324,039 |
| Backend Python files | 753 |
| Backend lines of code | 228,264 |
| API route modules | 249 |
| Playwright E2E test suites | 246 |
| Total lines of code | ~552,000 |
| Git commits | 51 |
How I Built It
Architecture
The system follows a clean client-server architecture with a React 19 SPA communicating with a FastAPI backend via REST and WebSocket:
$$ \text{Browser} \xrightarrow{\text{HTTP / WS}} \text{FastAPI} \xrightarrow{\text{REST}} \begin{cases} \text{Alpaca (broker + data)} \ \text{Finnhub (WS ticks)} \ \text{Tradier (options)} \ \text{yfinance (fallback)} \end{cases} $$
Frontend Stack:
- React 19 + TypeScript + Vite 5 for blazing-fast HMR and builds
- Zustand for global state management (positions, autopilot state, quotes)
lightweight-charts v5for institutional-quality candlestick rendering- Tailwind CSS 4 for the dense, Bloomberg-inspired dark theme
- React Router 7 for client-side routing across 20+ pages
react-resizable-panelsfor the drag-to-resize panel layout
Backend Stack:
- FastAPI (Python 3.10+) — asynchronous REST API with 249 route modules
- SQLite (via SQLAlchemy + aiosqlite) for persistent bar data, autopilot ledger, and trade journal
- Alpaca-py for live market data + paper trading execution
- yfinance as a zero-cost delayed fallback data source
- pandas + numpy for server-side technical indicator computation
- WebSocket manager for real-time tick streaming and autopilot state broadcasting
- Structlog for structured, queryable application logging
Testing & QA:
- 246 Playwright E2E test files covering navigation, portfolio, chart views, autopilot, indicators, and investor personas
- Vitest unit tests for frontend stores and services
- pytest for backend unit and integration tests
- Determinism proofs — run the same backtest 3x and diff the output to verify reproducibility
The Development Journey
The build followed an aggressive wave-based sprint model:
Phase 1 (Core): Built the FastAPI skeleton, Alpaca data integration, and basic candlestick chart rendering. Got a working trading terminal with live quotes in the first 48 hours.
Waves 1-10: Added the Autopilot AI engine, portfolio page, options chain, risk desk, search, Elasticsearch integration, and the first batch of technical indicators. Each wave was a focused 2-day sprint adding one major feature.
Waves 11-20 (Online-Only Pivot): Stripped out all mock/demo data and committed to 100% live data. Every API endpoint now hits real market data — Alpaca for broker data, Finnhub for WebSocket ticks, yfinance as fallback.
Waves 21-104 (The Masterplan): Implemented the Bloomberg feature parity roadmap — research notebooks, BQL queries, execution cockpit, blotter, pre-trade risk, surveillance, attribution, factor models, stress scenarios, smart routing, broker scoring, agent registry, and more.
Sprint 1 (Stability): Full Playwright E2E coverage, determinism proofs, media evidence pack, and comprehensive roadmap documentation.
Challenges I Faced
1. The WebSocket Hydra 🐉
The original design used 13 separate polling timers for real-time updates (quotes, positions, autopilot state, news, etc.). This was burning CPU and causing race conditions. Migrating to a unified WebSocket architecture with a centralized manager and topic-based subscriptions was a multi-day refactor that touched every store and service.
2. Alpaca Rate Limits
Alpaca's paper trading API has strict rate limits. A naïve implementation of "fetch quote for every symbol on every render" would get throttled instantly. The solution: batch quote endpoints (GET /api/v1/market/quote/batch?symbols=AAPL,MSFT,GOOG), client-side quote caching with TTL, and staggered polling intervals.
3. The Autopilot Double-Order Bug 🐛
Early on, I accidentally mounted two autopilot routers (v1 and v3) simultaneously. Both were independently scanning the same universe and placing orders — resulting in double orders on every signal. The fix was canonical: disable the v3 router entirely and route everything through unified_autopilot_router.
4. Options Greeks Computation
Computing Black-Scholes Greeks (\(\Delta = N(d_1)\), \(\Gamma = \frac{N'(d_1)}{S\sigma\sqrt{T}}\)) server-side for an entire options chain with 50+ strikes × 12 expirations is computationally expensive. The solution was vectorized numpy computation and aggressive caching with a 60-second TTL.
5. 552K Lines of Code, One Developer
Managing half a million lines of code solo — across two languages, three databases, five API providers, and 20+ frontend pages — required extreme discipline. Every feature got its own route module, its own Playwright test file, and its own wave number for traceability.
6. The CORS + Proxy Maze
Running the frontend on :5100 and the backend on :8000 with WebSocket upgrade requests, API path rewrites (/api/autopilot → /api/v1/autopilot), and multiple proxy rules in Vite's dev server config was a constant source of subtle bugs. The final working proxy configuration has 4 route-specific rewrites.
What I Learned
Zustand >> Redux for trading UIs. Zustand's minimal API (
create,get,set) and built-in middleware (immer, devtools) made it trivial to manage complex nested state (positions array, autopilot candidates, streaming quotes) without Redux's action-creator boilerplate.lightweight-chartsis production-ready. After evaluating Chart.js, Recharts, d3, and TradingView's widget, I landed onlightweight-charts v5for its native candlestick support, GPU-accelerated rendering, and minimal bundle size (~40KB gzip).FastAPI's router composition scales beautifully. With 249 route modules registered via
app.include_router(), the codebase stays modular. Each feature is a self-contained file with its own router, models, and logic — no monolithicviews.py.E2E tests are the best documentation. The 246 Playwright test files serve as living documentation of every feature's expected behavior. When a page breaks, the test tells you exactly what used to work.
Determinism proofs matter. Running a backtest three times and diffing the outputs catches floating-point drift, timestamp ordering issues, and non-deterministic API responses that unit tests would never find.
What's Next
- Sprint 2: Replace all remaining polling with WebSocket push, add autopilot candidate drill-down panel, and config save/load
- Sprint 3: Docker Compose full-stack deployment, nginx reverse proxy, rate limiting, connection pooling
- Sprint 4: Volume histogram overlay, virtual scroll for large option chains, performance regression testing, AI signal quality improvements
Built With
Languages
- TypeScript — Frontend (React 19, Vite 5)
- Python 3.10+ — Backend (FastAPI, data processing, ML)
- SQL — SQLite database schemas
- CSS — Tailwind CSS 4
Frameworks & Libraries
- React 19 — Frontend UI with concurrent features
- FastAPI — Async Python REST API
- Vite 5 — Frontend build tool and dev server
- Zustand — Lightweight state management
- lightweight-charts v5 — TradingView-quality financial charts
- Tailwind CSS 4 — Utility-first dark-theme styling
- React Router 7 — Client-side page routing
- SQLAlchemy 2.0 — Async ORM for SQLite
- pandas + numpy — Server-side data crunching and TA indicators
- structlog — Structured logging
APIs & Data Sources
- Alpaca — Live market data + paper trading broker
- Finnhub — Real-time WebSocket tick streaming + news
- Tradier — Options chain data with Greeks
- yfinance — Delayed market data fallback
- Polygon.io — Additional equities/options data
Infrastructure & Testing
- Playwright — 246 end-to-end browser tests
- Vitest — Frontend unit/integration tests
- pytest — Backend unit/integration tests
- SQLite — Embedded databases (
bars.db,autopilot_v3.db,phase1.db) - WebSocket — Real-time data streaming
Platforms
- Alpaca Paper Trading — Commission-free paper trading execution
- GitHub — Version control and CI
Built With
- amazon-nova-2-lite
- amazon-nova-multimodal-embeddings
- amazon-nova-pro
- amazon-nova-sonic
- aws-bedrock
- caching
- charts
- deterministic
- fastapi
- finance
- for
- lightweight
- local
- metadata
- mode
- nova-act
- offline
- playwright
- provenance
- pytest
- python
- react
- react-19
- recharts
- record/replay
- sqlite
- tradingview
- typescript
- vite
- vitest
- websockets
- yahoo
- zip/html
Log in or sign up for Devpost to join the conversation.