FinTech

Quant Research Terminal

Stock research, macro data, and AI investor personas — research only

Built by Rogue AI · Research terminal, no order execution · Self-hosted

Started as a watchlist and Yahoo-quote viewer in early 2026. The analytics core (DCF, risk, optimization) and the macro layer landed as a deliberate Python → TypeScript port through Q2 2026, so the math could be unit-tested and run in-process. Most recent work: the signal scanner and the investor-persona panel.

The problem

Retail research tools either lock the useful analytics behind a subscription or hand you a number with no way to inspect the assumptions behind it. I wanted a terminal where the DCF inputs are mine to edit, the risk metrics are computed from real return series, and an AI second opinion is grounded in the same fundamentals — without sending my portfolio to a third party or wiring up anything that could place a trade.

What I built

A stock-research and analysis terminal. It screens and charts equities, imports broker positions (IBKR and Trading 212 CSV), converts a multi-currency portfolio to a base currency, and runs an analytics suite — assumption-driven DCF, risk metrics, and portfolio optimization with an efficient frontier — written as pure TypeScript. A macro section pulls keyless series from FRED, World Bank, IMF, and DBnomics; a signal scanner ranks tickers from trend, RSI, MACD, and Bollinger %B; and an AI panel produces five investor-persona reads of a name. It is research only.

Architecture

  • Analytics core

    Pure, side-effect-free TypeScript: returns, Sharpe/Sortino/VaR/CVaR/max-drawdown, DCF, mean-variance optimization + efficient frontier — fully unit-tested with Vitest

  • Market data

    Yahoo Finance for quotes and history, FMP for fundamentals and screening, behind a 3-tier cache (Redis → PostgreSQL → fetch)

  • Macro layer

    Keyless adapters for FRED, World Bank, IMF SDMX, and DBnomics, cached 24 hours

  • Signal scanner

    Composite of SMA cross, RSI, MACD, and Bollinger %B producing a -100..+100 score with human-readable reasons; ephemeral, Redis-cached per user

  • AI panel

    Five investor personas over a provider-switchable bridge (local Ollama or Claude), prompts grounded in the fetched fundamentals

  • Auth & data

    Custom JWT (jose) sessions, Prisma 7 with the PrismaPg adapter, per-user watchlists, portfolios, and alerts

Tech stack

Next.js 16React 19Prisma 7PostgreSQL 16Redis 7TypeScriptVitestOllama / Claude bridge

What broke first

  • Porting the optimizer from scipy SLSQP to a pure-TS projected-gradient solver was the hard part — the long-only constraint binds differently, so I label the method in the UI rather than pretend the weights are identical to the Python reference.

  • Yahoo Finance throttles hard. A naive per-ticker fetch died on a 20-name watchlist; a 3-tier cache (Redis 5 min → DB 24 h → fetch) plus concurrency-capped batches fixed it.

  • The investor personas are only as honest as their disclaimer. They read the same fundamentals five ways; I keep the prompt grounded in the actual numbers and label it analysis, never advice.

Outcome

A single self-hosted terminal where every analytic is inspectable: DCF assumptions are editable, risk numbers come from real return series, and the AI panel argues a name five ways while staying grounded in the fundamentals. No order execution, no portfolio data leaving the host.

Honest limits

Research only — there is no broker write path, and there never will be in this build. Macro series are cached 24 h, so intraday macro is out of scope. The optimizer is mean-variance with a long-only projected gradient, not a substitute for a real risk desk. Persona output is LLM commentary, explicitly non-fiduciary.

Rogue AI • Production Systems •