Statistics · Quantitative finance
A nightly portfolio desk under coded risk vetoes
Abstract
Each market night a two-stage SLURM pipeline fits a 2-state Markov-switching Gaussian mixture per asset on 252 daily returns, simulates forward paths by circular block bootstrap — 10,000 paths of month-long blocks drawn from the asset's own two-year return history — and reduces each to P(up in 6m), CVaR(5%), and skew. A LangGraph DAG under a Llama-3.3-70B-AWQ server decoding guided JSON then walks a macro strategist, a per-ticker news-sentiment pass, a portfolio manager capped at six cited proposals, and a risk officer whose vetoes fire in code, not prompts. The parametric GBM simulator was rejected: it destroyed the fat tails and volatility clustering the regime model exists to capture. DianJin-R1-32B led finance benchmarks, but its promotion gate approved a reckless concentration trade, so it was rejected and the gate rewritten to demand sane verdicts, not valid JSON. No broker API exists anywhere in the pipeline; the desk grades its own closed recommendations against SPY and cannot execute.
keywords: regime switching · Monte Carlo · risk parity · guided decoding
## The nightly pipeline and its data
The run is two SLURM stages. A 16-CPU ingest pulls nine free sources into a SQLite corpus: two years of daily closes from yfinance, ten FRED macro series, Yahoo/Google/CNBC/Fed news RSS, options chains with put/call implied volatility, the earnings calendar, SEC Form 4 insider flow, EDGAR 10-K risk-language shift vectors, EDGAR odd-lot tender filings, and pasted deep-research reports. A GPU stage on two A100/H100-class cards serves Llama-3.3-70B-AWQ under vLLM and walks a LangGraph DAG: research ingest, macro strategist, the quant node, per-ticker news sentiment, an outcome scorer that reads the system's own record, a portfolio manager, the risk officer, and report compilation. One nightly is about 30 GPU-minutes and writes a single morning brief plus a deep-research prompt built from that night's holdings and the risk officer's open questions.
## Regimes and forward paths
Per asset, a 2-state Markov-switching Gaussian mixture is fit on the last 252 daily returns, producing a regime label and survival probabilities from the penalized transition matrix; the EDGAR fundamental-shift vector makes the high-volatility regime stickier when 10-K risk language diverged year over year. Forward paths are a circular block bootstrap of the asset's own last two years of real returns, 10,000 paths of month-long blocks, reduced to P(up in six months), CVaR(5%), and skew, with the macro strategist's bounded drift tilt applied to every simulation. The block bootstrap replaced a parametric GBM simulator that erased the fat tails and volatility clustering the regime model exists to capture. Signals combine as a cross-sectional z-blend whose weights are logged for recalibration once outcomes accrue:
- 0.25 momentum (12-1 plus 63-day)
- 0.15 regime health (Monte Carlo P(up))
- 0.15 analyst EPS-revision drift (30-day)
- 0.15 short-interest trend (decreasing is bullish)
- 0.10 insider flow, asymmetric: open-market buys weighted 4× sales
- −0.10 short-term volatility
## Covariance and the risk officer
Ledoit-Wolf shrunk covariance drives annualized volatility, per-holding risk contributions, historical one-day VaR/CVaR(95), and equal-risk-contribution reference weights, which are advisory and never auto-traded. Nonlinear shrinkage was rejected: at an N/T of 0.04–0.12 linear Ledoit-Wolf already captures the gain, and nonlinear estimators multiply turnover and are fragile to non-stationarity. The risk officer is long-only with no margin, and its hard constraints are enforced in code, not prompts:
- maximum position 25%
- maximum single trade 10%
- minimum cash 5%
- a SELL or TRIM whose avoidable short-term tax exceeds 1% of trade value is vetoed outright
- unheld sells blocked; earnings-window buys blocked; an 8-K item 4.02 non-reliance filing hard-vetoes new buys
A vetoed trade appears in the brief with its reason and never enters the ledger.
## Model selection on judgment
The model is gated on judgment, not syntax. DianJin-R1-32B led finance benchmarks, but under structured decoding its reasoning phase is suppressed, and its promotion gate approved a deliberately reckless concentration trade; it was rejected and the gate rewritten to require sane verdicts, not merely valid JSON, so syntax alone can never promote a model. Qwen3-Next-AWQ was rejected earlier: its DeltaNet finite-state machine loops under strict guided decoding. Llama-3.3-70B-AWQ is the standing pick for this strict structured-JSON pipeline. Multi-agent LLM debate was rejected for a structured single pass with programmatic gates: semantic drift and coordination failures dominate debate loops, and the gates carry the constraints debate cannot.
## Track record and evaluation
Every surviving recommendation is stamped with its entry price and marked to market against SPY nightly; a BUY counts as a hit when it beat SPY over its horizon, a SELL when the ticker lagged SPY. The scorecard feeds back into the portfolio manager's prompt, so the desk knows its own hit rate. An evaluation harness computes per-signal rank-IC with e-BH false-discovery control, James-Stein shrinkage, and block-bootstrap system alpha; it self-reports insufficient data until history accrues, and signal weights are recalibrated from closed outcomes once roughly 40–50 recommendations close. No recommendation has closed into a booked trade yet: no performance is claimed. Verification is a mock-LLM full-DAG harness in which the hard vetoes fire and the ledger round-trips, live-API ingest checks, and cluster nightlies passing since 2026-07-05.
Python, LangGraph, vLLM (Llama-3.3-70B-AWQ, guided JSON), scikit-learn, NumPy/pandas, hmmlearn, yfinance, aiohttp, SQLite. CUDA Monte Carlo; two-stage SLURM chain on 16 CPU + 2× A100/H100 GPUs, UGA Sapelo2. FRED, SEC EDGAR, Yahoo Finance — no paid data.
Liam Kozma · liam@liamkozma.com