← Back to Projects

TradeCraft

Algorithmic trading simulation platform

Live

What TradeCraft Does

TradeCraft is a trading simulation platform where you backtest algorithmic strategies against years of real market data, then deploy autonomous agents that mirror those trades using your own Alpaca API keys.

The core idea: Every other trading platform either wants your money (manage it for you) or your strategy (sell you theirs). TradeCraft is BYOK — Bring Your Own Keys. Your capital stays in your Alpaca account, you own the strategy logic, and the platform just shows you what works.

The Architecture

Three-Pillar Breakdown

🗄️ DATABASE: TimescaleDB (PostgreSQL with time-series extensions)
│
├─ market_candles        100M+ rows of OHLCV data (stocks + crypto)
├─ simulation_results    Every backtest run (strategy × symbol × timeframe)
├─ character_agents      39 personified strategies ("Characters")
├─ user_agents           Live trading agents that mirror simulations
└─ trades                Actual executions via Alpaca API

🖥️ INTERFACE: PHP + Bootstrap 5 (dark theme)
│
├─ Server-rendered HTML  Fast, no build step, SEO-friendly
├─ Character Dashboard   See how each strategy performs across all symbols
├─ Agent Dashboard       Monitor your live trading agents
└─ Account Settings      Link Alpaca keys, manage subscriptions

⚡ API LOGIC: PHP business layer + External APIs
│
├─ Simulation Engine     Runs backtests using historical candles
├─ Trade Mirror System   Copies simulation trades to Alpaca when agent active
├─ Data Pipeline         Fetches new candles from Alpaca/Tiingo (cron jobs)
└─ Stripe Integration    Subscription billing (3 tiers)

Why TimescaleDB?

We started with regular PostgreSQL. Queries on 100M candle rows were... painful. TimescaleDB gives us hypertables — it automatically partitions time-series data by time ranges. A query like "show me all SPY 1-minute candles from March 2024" becomes sub-second instead of minutes.

The Shared Database Pattern

Here's something unusual: development and production share the same database.

/opt/bened-tradecraft (dev) ──┐
                               ├──▶ TimescaleDB (ONE database)
/srv/bened-tradecraft (prod) ──┘

Why? The simulation engine and data collectors run as cron jobs from dev. They write candles, simulation results, and agent trades. Production just reads the same data. No replication lag, no sync issues, one data pipeline.

The consequence: Schema changes are ADDITIVE ONLY. You can't drop a column dev uses if prod is still SELECT-ing it. This forces disciplined database evolution.

The 39 Characters

Instead of "Strategy A" and "Strategy B", TradeCraft has personified algorithms — Characters. Each one has a name, personality, and trading style:

Each Character runs simulations across 114 symbols (102 stocks + 12 crypto). You study their results, see which ones align with your risk tolerance, then activate agents that mirror their trades.

Auth & Identity

Single sign-on via Keycloak at auth.bened.works. When you log into TradeCraft, you're actually getting a JWT from Keycloak. That same token works on the rental platform, the platform API — everything. One login, all apps.

We tried separate user databases first. It was a nightmare.

The Tech Stack

Layer Technology Why This Choice
Backend PHP 8.2 Fast, mature, no build step. Direct database access.
Database TimescaleDB PostgreSQL + time-series superpowers. Sub-second queries on 100M rows.
Frontend Bootstrap 5 (dark) Responsive, accessible, looks good without custom CSS.
Server Nginx + PHP-FPM Nginx proxies, PHP-FPM handles scripts. Standard, battle-tested.
Auth Keycloak (OIDC) Industry-standard SSO. JWT tokens, refresh flow, cross-app identity.
Trading API Alpaca Commission-free, good API, supports stocks + crypto.
Market Data Alpaca + Tiingo Historical candles, real-time quotes. Free tier sufficient for dev.
Payments Stripe Subscriptions 3 tiers: Free (demo), Basic, Pro. Stripe handles recurring billing.

Data Flow: How a Trade Happens

1. Simulation Engine (cron)
   └─ Runs backtests for all Characters × Symbols
   └─ Writes results to simulation_results table

2. User activates an Agent
   └─ Links Agent to a Character strategy
   └─ Agent starts monitoring simulation_results

3. Character generates a trade signal (via simulation)
   └─ Agent sees the signal in simulation_results
   └─ Agent calls Alpaca API to execute the trade
   └─ Trade recorded in trades table

4. User sees trade in their dashboard
   └─ PHP reads from trades table
   └─ Displays in Agent Dashboard

What's Proprietary (Not Shown Here)

This is appropriate disclosure — you see how the system works, not the secret sauce that makes strategies profitable.

Development vs Production

Development Production
URL devtradecraft.bened.works tradecraft.bened.works
Code /opt/bened-tradecraft /srv/bened-tradecraft
Database Shared TimescaleDB
Cron Jobs ✅ All run here ❌ None
Purpose Sandbox, new features, data engine Stable public-facing site

The Deployment Story

Code changes go like this:

1. Edit files in /opt/bened-tradecraft (dev)
2. Test at devtradecraft.bened.works
3. When stable, run deploy script:
   └─ Pulls code from /opt/ to /srv/
   └─ Runs composer install --no-dev
   └─ PHP-FPM serves new code instantly (no restart)
4. Production site at tradecraft.bened.works gets updates

PHP has a beautiful property: file changes are live immediately. No build step, no container restarts, no downtime.