Market-structure reconstruction. Radon surfaces convex options trades from dark pool and OTC flow, the volatility surface, and cross-asset positioning. The system runs every candidate through a hard three-gate framework before sizing it.
Flow signal or nothing. No narrative trades, no chart-pattern trades.
- What it does
- Three gates, in order
- Quick start
- External services
- Architecture at a glance
- Now true
- What's where
- Project layout
- Data source priority
- Deployment
- Tests
- Glossary
- Detects institutional positioning through Interactive Brokers, Unusual Whales, MenthorQ CTA, and cross-asset feeds.
- Designs convex options structures and sizes them with fractional Kelly.
- Streams live quotes, greeks, P&L, and order state to a Next.js terminal at
localhost:3000(laptop dev) andapp.radon.run(production). - Auto-deploys to a Hetzner VPS on every push to
main.
| Gate | Rule |
|---|---|
| Convexity | Potential gain >= 2x potential loss. Defined-risk default. |
| Edge | Specific, data-backed signal that has not fully moved price. |
| Risk | Fractional Kelly, hard cap 2.5% of bankroll per position. |
Any gate fails, no trade. Full rules in CLAUDE.md. Strategy specs in docs/strategies.md.
Prerequisites
- Python 3.13 (3.14 has an
ib_insync/eventkitincompatibility) - Node.js 18+ and
bun(npm is not used for the JS stack) - Interactive Brokers Gateway (cloud via Tailscale, Docker, or local TWS)
- Accounts at the external services listed below — start with
.env.exampleandweb/.env.example, both fully annotated with sign-up URLs
git clone https://github.com/joemccann/radon.git
cd radon
cp .env.example .env # then fill in
cp web/.env.example web/.env # then fill in
pip install -r requirements.txt
cd web && bun install && cd ..The two .env.example files are the canonical variable reference — every required and optional key has an inline comment with purpose, format, and required-vs-optional. Read those before the operations runbook.
Dev launchers
scripts/cloud.sh # default: laptop runs Next.js + newsfeed, VPS serves FastAPI/relay/IB Gateway over Tailscale
scripts/local.sh # fully local: laptop runs everything including the IB Gateway Docker containercloud.sh is the everyday workflow. local.sh is for offline dev or when the VPS is down. Mode persists to .env.ib-mode; toggle later via scripts/ib mode local|cloud.
Open http://localhost:3000. Clerk auto-bypasses on localhost in non-production.
Radon is glued together from a long list of third-party services. The full env-var matrix lives in .env.example and web/.env.example; the table below summarises why each one is there and where to sign up.
| Service | Purpose | Env vars | Where |
|---|---|---|---|
| Interactive Brokers | Real-time quotes, options chains, order routing, positions. IB Gateway + IB Flex Web Service. | TWS_USERID, TWS_PASSWORD, IB_FLEX_TOKEN, IB_FLEX_QUERY_ID (blotter), IB_FLEX_NAV_QUERY_ID (cash flows), IB_GATEWAY_* |
ibkr.com · IB Pro account · Flex Web Service enabled in Account Management |
| Unusual Whales | Dark pool flow, options flow, OI changes, sweeps, analyst data, LEAP IV. | UW_TOKEN |
unusualwhales.com |
| Clerk | JWT auth for the terminal + FastAPI. Localhost auto-bypassed in dev. | CLERK_ISSUER, CLERK_JWKS_URL, CLERK_SECRET_KEY, NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, ALLOWED_USER_IDS |
clerk.com |
| Turso (libSQL) | Cloud-hosted SQLite. Canonical store for journal, service_health, snapshots. | TURSO_DB_URL, TURSO_AUTH_TOKEN |
turso.tech |
| Anthropic Claude API | Assistant chat, share-card OG renders, vision tagger (newsfeed), seasonality vision fallback. | ANTHROPIC_API_KEY (aliases CLAUDE_CODE_API_KEY, CLAUDE_API_KEY) |
console.anthropic.com |
| Backblaze B2 | Off-box cold archive for portfolio_snapshots older than ~30d (radon-portfolio-archive oneshot). S3-compatible API via boto3. Required on the production VPS; unit fails closed without keys. |
RADON_ARCHIVE_S3_ENDPOINT, RADON_ARCHIVE_S3_BUCKET, RADON_ARCHIVE_S3_ACCESS_KEY_ID, RADON_ARCHIVE_S3_SECRET_ACCESS_KEY, RADON_ARCHIVE_S3_REGION |
backblaze.com/b2 · bucket radon-archive |
| Service | Subsystem | Env vars | Where |
|---|---|---|---|
| MenthorQ | /menthorq/* CTA / dashboard / screener / forex / summary / quin surfaces. Username/password login via Playwright. |
MENTHORQ_USER, MENTHORQ_PASS |
menthorq.com |
| MarketDataWorks (MDW) | Inbound shared-secret used by MDW → FastAPI pushes that feed CTA enrichment. Validates X-API-Key header. |
MDW_API_KEY |
Vendor-issued |
| The Market Ear | Real-time intraday news scraped by scripts/newsfeed/. Headless Playwright login; session cached at data/newsfeed-storage.json (~30d), full re-auth ~6h. |
THEMARKETEAR_EMAIL, THEMARKETEAR_PASSWORD |
themarketear.com (paid subscription) |
| Cerebras | Newsfeed text tagger (gpt-oss-120b → qwen-3 fallback). Falls back to Anthropic when unset. | CEREBRAS_API_KEY |
cerebras.ai |
| Artificial Analysis | LLM Token Expenditure Index (/regime/llm, daily timer). Free tier 1000 req/day. |
ARTIFICIAL_ANALYSIS_API_KEY |
artificialanalysis.ai → Insights dashboard |
| Exa | Company and market research surfaces. | EXA_API_KEY |
dashboard.exa.ai |
| Service | Purpose | Notes |
|---|---|---|
| Hetzner Cloud | VPS that hosts FastAPI, IB Gateway (docker), the WS relay, the monitor daemon, the newsfeed, Caddy, and media.radon.run. Host secrets in /home/radon/radon-cloud/.env include Turso + Backblaze B2 archive keys. |
Resolved as ib-gateway via Tailscale on the laptop |
| Backblaze B2 | Cold storage for archived portfolio snapshot months (portfolio_snapshots/YYYY-MM.jsonl.gz). See required table above. |
Bucket radon-archive |
| Tailscale | Mesh VPN between laptop and VPS. Laptop reaches ib-gateway:4001 over Tailscale; FastAPI on the VPS binds to localhost-only. |
tailscale.com |
| Caddy | TLS termination + reverse proxy on the VPS. Serves app.radon.run and media.radon.run. |
Canonical config: cloud/caddy/ |
| GitHub Actions | git push origin main triggers .github/workflows/ci.yml, which runs the Vitest + pytest gate then deploys the tested monorepo SHA on green. |
Confirm: gh run list --workflow=ci.yml --limit 1 |
| Service | Purpose | Env vars | Where |
|---|---|---|---|
| Pushover | Watchdog P1 (emergency) starts laptop Grok auto-fix. Grok follow-up and live deploys are normal-priority (radon grok:, radon deploy live) and must never be P1. P2/P3 stay in service_health. Absent vars degrade gracefully. Spec: docs/grok-page-responder.md. |
PUSHOVER_USER, PUSHOVER_TOKEN |
pushover.net |
| FRED (St. Louis Fed) | Risk-free rate (DFF) for Black-Scholes implied value. No key required; 24h cache + 0.0 fallback. | none | Public API |
| Cboe | COR1M historical fallback when IB / UW are missing the series. | none | Public CSV feed |
| Yahoo Finance | Last-resort price fallback when IB and UW both fail. Never the first or second source. | none | Public API |
Production .env lives on the VPS at /home/radon/radon-cloud/.env (0600): this is the sole legacy-directory exception during the monorepo migration, not a source of deploy code or services. Laptop dev uses the root .env for FastAPI and scripts, plus web/.env for Next.js (some keys are duplicated because Next.js can't read the root file from inside web/).
Unusual Whales ─┐
Interactive Brokers ├──> Signal Detection ──> Strategy Evaluation
MenthorQ ──┘ │
▼
Convex Structure Builder
│
▼
Kelly Position Sizing
│
▼
Execution / Monitoring
│
▼
Radon Terminal
Process layout
localhost:3000for the Next.js 16 terminal:8321for FastAPI (40+ endpoints, JWT-gated, localhost bypass for server-to-server):8765for the IB realtime WebSocket relay- 120s loop for the newsfeed scraper (headless Playwright)
Storage
- Turso libSQL cloud DB (canonical). Every Radon process talks directly to cloud — no embedded replica anywhere (retired 2026-05-20; see
docs/cloud-services.md) - JSON files in
data/as fallback / DR archive - Hetzner-hosted
media.radon.runfor newsfeed images
Full architecture and the Phase 0-6 migration history live in docs/cloud-services.md. The developer runbook is CLAUDE.md.
Durable facts. History and mechanism live in the owner file, not here.
- Indicators. Regime tabs at
/regime/{skew,skew2d,straddle,cor,curve}. Cheap-wing scanner at/scanner?mode=vol-cone. Specs:docs/indicators/. - CMD+J. Quotes, priced UW chains, and
evaluate.pyrun from the in-app assistant. KB miss is not a dead end. - Stop orders. Desktop and mobile tickets place
STPandSTP LMTthrough/api/orders/place. - Incidents. Watchdog artifacts under
data/incidents/. Triage with/incident <path>. Cases:docs/incident-runbook.md. - Factory. GitHub issues labeled
factorybecome draft PRs via Foreman injoemccann/radon-factory. Contract:docs/factory.md.
| Topic | Doc |
|---|---|
| Developer runbook, gates, calculations, component cheat sheet | CLAUDE.md |
| Authoring toolchain map (agents, session tooling, verification, creative stack) | DEVELOPMENT.md |
| Cloud architecture, two-mode deploy, Turso DB | docs/cloud-services.md |
| Background services, watchdogs, deploy flow, env vars | docs/operations.md |
Incident cases and /incident playbook |
docs/incident-runbook.md |
| Regime and scanner indicator specs | docs/indicators/README.md |
| Equibles market-structure API | docs/equibles-api.md |
| Software factory (Foreman, draft PRs from labeled issues) | docs/factory.md |
| CLI commands and test runners | docs/scripts-reference.md |
| Strategy specs (Dark Pool, LEAP, GARCH, VCG-R, CRI, Risk Reversal) | docs/strategies.md |
| VCG-R research notes | docs/cross_asset_volatility_credit_gap_spec_(VCG).md |
| GARCH convergence strategy | docs/strategy-garch-convergence.md |
| Options structures catalogue | docs/options-structures.md |
| Chart system | docs/chart-system.md |
| Brand identity and design tokens | docs/brand-identity.md |
| IB Gateway Docker setup | docs/ib-gateway-docker.md |
| IB connection troubleshooting | docs/ib-connection-troubleshooting.md |
| Unusual Whales API reference | docs/unusual_whales_api.md |
| Performance reconstruction | docs/performance-reconstruction.md |
| OAuth subscription auth | docs/oauth-subscription-auth.md |
radon/
├─ scripts/ Python scanners, evaluators, broker integrations
│ ├─ clients/ Broker and data-provider adapters
│ ├─ monitor_daemon/ Background fill/exit/rebalance daemon
│ ├─ db/ Turso writers + migrations
│ ├─ knowledge/ radon-kb MCP (journal, evals, incidents)
│ └─ watchdog/ Service-health alerting
├─ web/ Next.js 16 terminal + FastAPI server scripts
├─ site/ Standalone marketing site (separate Vercel project)
├─ cloud/ Production infrastructure, services, and deploy tooling
├─ docs/ Topic-scoped documentation
│ └─ indicators/ Regime and scanner specs
├─ data/ Runtime artifacts (gitignored except taxonomy + presets)
├─ config/ launchd plists and service configuration
├─ brand/ Design system and tokens
└─ CLAUDE.md Authoritative developer runbook
Strict order for any price / flow / chain lookup. The full external-service inventory is in External services above.
- Interactive Brokers for real-time quotes, options chains, and portfolio state
- Unusual Whales for dark pool flow, sweeps, options flow, and analyst data
- Cboe official feeds for COR1M historical fallback
- Yahoo Finance as a strict last resort
Never skip to Yahoo or web scrape without trying IB then Unusual Whales first. Research surfaces (Exa) and news (themarketear, MenthorQ) are orthogonal — they don't substitute for missing price data.
git push origin main is the deploy. After the CI gates pass, GitHub Actions extracts cloud/ from the exact tested SHA into an immutable VPS runner at /home/radon/.radon-deploy-runners/<sha>.<run>/cloud and runs its deploy contract. Before any dependency build, service stop, or transition write, the deploy verifies the installed root control plane against its manifest.
The monorepo cloud/ directory is the canonical source for systemd units, Caddy, the IB Gateway Compose project, and deploy tooling. /home/radon/radon-cloud/.env remains the only legacy-path exception for stable host secrets. Confirm releases with gh run list --workflow=ci.yml --limit 1. For the exact privileged recovery sequence, use cloud/CLAUDE.md and docs/monorepo-cloud-migration.md; do not reconstruct it from this overview.
python3.13 scripts/run_pytest_affected.py # scoped Python tests
python -m pytest scripts/tests/ -v # full Python suite
cd web && bun test # Vitest
cd web && npx playwright test # E2EMocked API calls cover most of the surface, so development rarely needs a live broker session. Order-route integration uses an isolated test-mode FastAPI harness (web/tests/fastapiHarness.ts) that never reuses the broker-backed localhost:8321 server.
| Term | Definition |
|---|---|
| Convexity | Asymmetric payoff where expected upside materially exceeds downside |
| CRI | Crash Risk Index, composite crash-risk and CTA deleveraging model |
| CTA | Commodity Trading Advisor, typically systematic trend-following funds |
| Dark Pool | Private off-exchange venue used for institutional trading |
| Edge | A specific reason the market is mispricing an outcome |
| GEX | Gamma exposure surface across the options chain |
| Kelly Criterion | Position-sizing framework that scales exposure to edge and odds |
| VCG-R | Volatility-Credit Gap, VIX>28 + VCG>2.5σ risk-off trigger |
