Back to projects

Next.js 16, React 19, Vercel AI SDK, SQLite, Docker

CryptoAI Trader

Solo full-stack · Dec 2025 – present

CryptoAI Trader is a research platform I designed and built alone: live market signals, historical backtests, a journal, and a server-side paper auto-trader in one Next.js 16 workspace. The user picks a market and timeframe; the app pulls OHLCV candles, computes indicators, then asks an LLM or a deterministic rulebook for a LONG/SHORT setup with entry, take-profit, and stop-loss. The same decision path replays over history with fees, spread, and slippage; closed results feed a learning gate; a process-local paper worker manages positions over public book-ticker WebSockets. There is no exchange API-key field and no live order path — every “position” is a SQLite row marked to public prices. The design rule: a flattering number is a bug, not a feature.

Live Analysis / Rules → POST /api/analyze | /analyze-rules
  → Zod contract · server-computed R:R · canvas chart (TP/SL)

Backtest → same analyze path per window
  → realistic fills · fees/spread/slippage · walk-forward holdout
  → skip on model failure (never fabricate a substitute trade)

Auto-Trader (server worker)
  → SQLite WAL · risk circuit breakers · tick TP/SL
  → learning gate: allow | avoid | insufficient-data

Markets: Binance · Bybit · Coinbase (keyless public APIs)
LLMs: Anthropic · OpenAI · Google via Vercel AI SDK

Deep dive

Research cockpit, not a broker

Tabs cover Live Analysis, Backtest, My Trades, Auto-Trader, and Chat. Global mode switches between AI-controlled and rule-based on the same candle window. Trading styles (Cautious / Brave / Risky) and research profiles (daytrade vs swing) shape risk appetite without inventing fills. Favourites, multi-timeframe context, and context-strength budgets sit next to honest cost estimates so a batch of model calls is priced before it runs.

Honest fills and walk-forward

Limit entries open only when price trades through the level; gaps fill at the open, not at the level; TP and SL on the same bar resolve stop-first because OHLC cannot prove order. A failed analyze step is a skipped window — never a moving-average substitute — so a partial run cannot earn a forward-test candidate label. Trades are ordered by entry time: first 60% development, last 40% unseen. Random splits would leak future structure into the past.

Learning gate and paper auto-trader

Closed trades calibrate allow / avoid / insufficient-data with a conservative one-sided 95% EV lower bound. New paper entries need evidence; a capped 0.25% probe lets a fresh install bootstrap without the gate blocking its own data. The worker resumes from instrumentation.ts on Node start, enforces daily loss / drawdown / streak breakers, and models isolated-margin leverage and liquidation on perps while Live and Backtest stay spot.

Production-minded self-host

Docker Compose ships a standalone Next.js image with a named volume for SQLite. Sessions are HMAC-signed HttpOnly cookies; production fails closed without APP_USERNAME / APP_PASSWORD — including login — because analyze routes can spend Claude quota. Vitest (~50 specs) hermetically throws on unstubbed fetch so money-path functions stay pure contracts, not UI-coupled guesses.

Highlights

Solo Next.js 16 / React 19 research cockpit: live signals, backtest, journal, paper auto-trader — no live exchange orders
Keyless public market data (Binance, Bybit, Coinbase) plus Anthropic / OpenAI / Google via Vercel AI SDK with Zod contracts
Cost-aware backtester: realistic fills, walk-forward holdout, skip-on-analyze-failure — never fabricated substitute trades
SQLite learning gate (allow / avoid / insufficient-data) with conservative EV lower bound before paper entries
Server-side paper trader with circuit breakers, tick-level TP/SL WebSockets, and Docker Compose standalone deploy
Fail-closed HMAC sessions and Vitest suite that rejects unstubbed network fetch