divan van rooyen / dvr
← work

2026live

Roos Research

A pocket research desk for retail investors. It turns market data and company news into a plain-language research brief — a stance, a bull case, a bear case, and what to watch.

role
solo, end to end
built
2026
stack
python · fastapi · react · claude api · gcp · paystack

// the problem

An investor who wants to understand a company has to assemble the picture themselves — price and technicals on one site, valuation and cash flow on another, news and sentiment on a third — and then reconcile the three.

Professional research tools are priced for institutions. The free alternatives either dump raw numbers with no interpretation, or drift into advice you have no way to verify.

The gap isn't data. It's explanation — not “what is RSI”, but what does this set of numbers, taken together, actually say about this company right now.

// the approach

The product is two halves that get reconciled into one answer.

The quantitative half computes the measures: moving averages, RSI, MACD, Bollinger bands and volatility, alongside fundamentals — margins, return on equity, free-cash-flow yield, and the earnings growth a forward P/E implies.

The qualitative half pulls company news and the next earnings date, filters it down to what genuinely concerns the business, and reads the investor narrative.

A third step synthesises both into a single brief.

// the rule I'd defend

Every number is computed in Python. The model only interprets finished figures — it is never asked to calculate.

I made that rule after live testing caught the model getting exactly those derivations wrong: how far a price sits from its moving average, whether MACD is above its signal line. So anything it would otherwise have to derive is precomputed and handed to it as a named field.

It costs more code and more tests. What it buys is numbers that are reproducible, unit-testable, and correct regardless of which model is running underneath — which is the only basis on which anyone should act on them.

// what shipped

  • I set the pricing myself, off the modelled cost of a single analysis, with the gross margin worked through per tier before any tier went live.
  • Cost controlled by design: the free data endpoints never touch the model, results are cached across users, and the expensive call only fires when a user explicitly asks for it — so the unit cost stays where the pricing assumed it would.
  • The more expensive model earned its place. Two tiers were compared head-to-head on interpretation quality, and the better one was only adopted once its cost per analysis still cleared the margin.
  • Running in production on Google Cloud Run with card payments and public sign-up since July 2026, covered by 142 passing tests — the maths is tested, because the maths is the product.

// what I deliberately didn't build

  • No recommendations, price targets or ratings. Research, not advice. It costs the obvious engagement hook, and it's still the right call.
  • No portfolio alerts, trade signals or backtesting. All three were scoped and deferred rather than half-built.
  • No unlimited tier. Every analysis carries a real model cost, so an unlimited promise would have been one I couldn't fund.
  • The model never sees raw price history — only computed indicators. Cheaper and more accurate, but it means it can't spot a chart shape nobody wrote code to measure.
  • Billing in rand via Paystack, because Stripe doesn't operate in South Africa. Opens the local market, defers the dollar one.

Want something like this?

This is the kind of problem I take on: a business question that needs both a defensible number and a system that keeps producing it.

message me on linkedin →

this page:73.8 kB of code, gzipped0 trackers0 cookiesbuilt in 188 ms