Skip to content
All projects

VYNN AI

A personal financial analyst for every investor

founder & sole engineer · 2025–present · 5,000+ registered users

Why it exists

I started VYNN because the research that moves markets is sold by the seat, and the AI tools built to replace it make up their numbers. Individual investors deserve what an analyst gets: the number, the arithmetic, and where every input came from.

What I built

So I built every investor a personal financial analyst. Name a company, a fund, a coin or a prediction market, in any language. VYNN reads the filings and the news, builds the valuation model and writes the report in about two minutes, for about three cents. Code computes every number, and every claim carries its source. I built every part of it and run it myself.

Where it’s going

Next, VYNN stops waiting to be asked. It will watch every portfolio around the clock and tell investors the moment news, earnings or a price move changes the case for what they own.

Impact

  • 5,000+ investors signed up, from a 500-person pilot.
  • Six to twelve hours of an analyst’s research in about two minutes, for about three cents.
  • Every release is checked against a set of reference valuations before it ships.
VYNN AI · complete system architecture

Scroll across to follow the full system

The company website leads to the React product. Caddy routes requests to FastAPI, which authenticates jobs and launches research workers. A tool-use agent selects research and valuation tools; the report is validated before output. MongoDB, Redis, and persistent files support the API and workers.FastAPI · identity, job lifecycle, streams, and research recordsResearch worker · ephemeral container, pinned image, user-scoped volumeDocker SDK · queued and bounded execution · progress over SSECompany websitevynnai.comNext.js · product, mission, demoResearch workspace · app.vynnai.comReact / TypeScript · Vite / Nginx · analyst chat + market terminalCompanies · funds · digital assets · prediction markets · positionsCaddy · HTTPS and reverse proxyREST · server-sent events · price and news WebSocketsIdentity & accessOAuth · ownership checksRedis-backed quotasResearch jobsQueue · launch · cancelReconcile after restartMarket streamsShared price/news pollingCache-backed universeSaved researchImmutable thesis recordsRevisioned portfoliosTool-use agent · research specialists & valuation engineReads the question, selects the work, and calls tools with structured argumentsFinancial dataFundamentals · filings · unitsShared typed FinancialStateSymbolic valuationSourced cost of capitalDCF formulas and assumptionsNews intelligenceRetrieve · rank · screenRuns alongside model workReport generationSix sections composed in parallelCalculator → evidence → narrativePublication checksClaim validation and citation coverageFlag a value the analysts do not backLive DCF workbookTen Excel sheetsEditable inputs and formulasSourced reportReport · PDFValuation, catalysts, and risksStructured resultsReturned to the APIStored as a dated thesisMongoDBMarket profiles, articles, conversationsImmutable theses and portfoliosShared article DAO in vynn-coreRedisQuotas and expiring job snapshotsCross-instance read-throughOnly the owner republishes job statePersistent filesResearch outputs and model inputsPer-user worker mountsAtomic reference-data cache writesStorage serves the API and research workers; records and cache have separate lifecycles.Hetzner · Docker · persistent volumesDigest-pinned worker images · bounded concurrency · owned artifact recovery
Explore the individual layers

Explore the stack

Research, calculate, then check the claim

A tool-use agent selects financial, market-data, and analysis tools, with specialists for deeper research. Financial statements feed a symbolic valuation engine; model and news work can run in parallel before the report is assembled.

Calculation
Code computes valuation and recommendation fields. Sourced market inputs ground the cost of capital; the exported ten-sheet workbook retains its formulas.
Publication
Evidence and citation checks gate the narrative. A value the analysts do not back is still published, at low confidence, with an alert that states both positions.
Research and valuation engine

Decisions behind the product

The model never writes a number

A deterministic DCF engine computes the valuation, and a formula evaluator reads the workbook back. The model writes the explanation. A validator rejects any figure that doesn’t match the calculator, and any write-up that cites fewer than 95% of its claims.

It stands by its value

When well-covered analysts disagree, VYNN still publishes its fair value and rating, at low confidence. An alert shows both numbers on the report’s first page, in the workbook and in the chat.

Discount rates from real market data

The cost of capital is built from published rates in the cash flows’ own currency (about 20 currencies), with Damodaran’s risk premiums and a beta measured against the company’s home index. A Tokyo listing is valued in yen, against Japanese rates.

Four repositories, one system

stock-analyst

Research engine · Python

The research engine. One agent chooses its tools for each question. Four specialist agents do the heavy research, with the model and the news work running in parallel. A deterministic engine owns every number.

Tools chosen per question

The agent reads a free-form question, calls tools, reads their structured results and keeps going until it can answer, so a price check never builds a DCF. A full report runs the dependent stages in order and the independent model and news work at the same time. The tools work with both supported model providers.

A valuation computed in code

The engine computes the workbook and every recommendation field. The cost of capital comes from published market data in the cash flows’ own currency. Growth, margins, working capital and terminal value are grounded in the company’s own data wherever it allows; a model may propose an assumption only as a bounded fallback. Every formula in the exported workbook stays live, so a reader can check and change it.

Publishing with confidence

Correct arithmetic is not enough. When the model can’t support a single value, VYNN shows a range and its reason. When the valuation is sound but well-covered analysts disagree, it still publishes its fair value and rating at low confidence, with an alert that states both positions. Every claim in the write-up is checked against the calculator, and the write-up must cite at least 95% of its claims.

Currencies and units

Companies are valued on their home listing, in their own currency, from market data through the model to the report. Quotes in minor units, like London’s pence, are converted, and a missing currency is reported as missing, never shown as dollars. Tests cover both the engine and the app.

Python · LangGraph · Tool-use agents · Symbolic DCF · MongoDB

Agentic-Analyst/stock-analyst·DeepWiki

api-runner

Control plane · FastAPI

The control plane. Each analysis runs in its own locked-down container from a pinned image. Jobs survive restarts, progress streams live, and every record belongs to one user.

Jobs that survive restarts

Each analysis runs in its own short-lived worker container. Job records carry pending, running and terminal states; recovery reconciles persisted jobs with worker state after a service restart. Stopping a job sends SIGTERM before a bounded force-stop. Worker images are pinned to a digest so a recorded run names the code that produced it.

Data and caching

MongoDB stores market profiles, statements, conversations, positions, and immutable theses. Redis holds quotas and expiring job snapshots, published by the owning process every two seconds. Remote snapshots are read through, never republished as authoritative state. Research artifacts and cached financial inputs live on persistent storage. Universe page reads use the database; scheduled, sharded refreshes pace vendor calls overnight.

Live progress without extra load

SSE delivers job progress, heartbeats and the final result. Price and news WebSockets share their subscribers: the price poller is paced and one fetch serves everyone watching, so another open browser costs no extra vendor calls.

Versioned research and synced portfolios

A thesis stores what the run concluded, its date, version, source inputs and publication decision. A later run adds another version. Portfolio writes check revisions; stale writes return a conflict instead of silently overwriting another device. Deletions retain tombstones so an offline client cannot resurrect a removed position.

Per-user isolation

Every job, report and conversation belongs to one signed-in user; anyone else gets a 404, the same as a missing job. At most four analyses run at once, each capped at 768 MB and one CPU with every Linux capability dropped, and secrets are redacted from their logs. News reads come from the cache; a paid refresh is an explicit, attributed action.

Python · FastAPI · Docker · MongoDB · SSE · WebSocket · OAuth · Redis

Private repository

vynnai-web

Product interface · React + TypeScript

The app: research chat next to a dashboard for companies, funds, crypto and prediction markets. Every number keeps its source, date, currency and confidence on screen.

The alert stays with the number

When the engine publishes a value with a confidence alert, the interface shows VYNN’s value, the analysts’ and the gap between them. A value the valuation model cannot support is shown as its range and reason, never reinterpreted as a bearish recommendation. VYNN’s thesis and third-party analyst consensus are distinct surfaces, with attribution attached to the Street’s figures.

Prices in the right units

A London quote in GBp is in pence, not pounds. Prices are converted once, market capitalization is left alone because the provider already reports it in pounds, and the app refuses to compare values in unknown or mismatched currencies.

Data fetching and live streams

TanStack Query owns request/response data with deliberate stale times and retry rules. Shared contexts own persistent WebSocket subscriptions. Historical requests are coalesced and cached. Subscriber lifetimes and chat-stream ownership account for remounts and concurrent conversations, keeping one view from stranding another’s work.

Missing data shown as missing

A missing value is shown as missing. If a sync fails, saved positions stay on screen, and a cached quote is never labelled live. CI rejects code patterns that could fabricate financial data in the interface.

React · TypeScript · Vite · TanStack Query · WebSocket · Recharts

Private repository

vynn-core

Shared persistence · Python

Shared storage for the API and the research workers. One implementation of article identity, timestamps and connections, so the two services can’t disagree about a record.

One identity per article

Canonical URLs drop tracking parameters and produce a stable hash. A unique index enforces deduplication, while upserts compare the actual source fields. An unchanged article does not acquire a new updatedAt timestamp simply because it was fetched again.

Timestamps in UTC

Publication and update times normalize to UTC at MongoDB’s millisecond precision. Both consumers import the same implementation, avoiding differences between timezone-aware Python values and BSON round trips.

Shared connections

Process-level MongoDB and Redis clients reuse connection pools. Index setup and article persistence live with the shared schema; consumer repositories pin the library revision used in their build.

Python · MongoDB · Redis · Canonical URLs · UTC / BSON

Agentic-Analyst/vynn-core