← Back to portfolio
Case Study · 03 / 17
Applied ML · Full-Stack · 2025

Price, indicators,
and the mood of the news.

FinCast AI pulls Indian-market data, runs a battery of technical indicators, predicts direction with an SVM, and weighs the tone of the headlines with FinBERT — then puts all of it behind one TypeScript React dashboard. Here's how the three signals fit together, and where I drew a hard line.

Role
Solo build — ML & full-stack
Domain
NSE equities analysis
Stack
FastAPI · scikit-learn · FinBERT · React
Status
Educational project
Fig. 03 · signal fusion
03
A number, a trend, and a sentiment — three witnesses, not one oracle.
§ 01 — The problem

One indicator tells you almost nothing.

RSI says overbought, MACD says momentum, the news says a downgrade — and a retail dashboard usually shows you exactly one of those at a time, on its own tab, with no attempt to reconcile them. The interesting question is what happens when you place price action and headline sentiment side by side.

FinCast AI is that experiment: fold technical indicators, a learned price-direction model, and financial-news sentiment into a single view for NSE-listed stocks — and be honest about what each part can and can't claim.

This is a lens on the market, not advice about it.

§ 02 — Constraints

The rules the project runs under.

§ 03 — Architecture

Data in, three signals out.

A FastAPI backend fetches prices from Yahoo Finance, computes indicators with the ta library, runs the ML models, and scores news from NewsData.io through FinBERT. The React dashboard reads it all over a small REST surface.

01 — Ingest
yfinance
Live + historical OHLCV for NSE tickers, plus news via NewsData.io.
02 — Indicators
ta engine
EMA, RSI, MACD, Bollinger Bands and OBV computed with pandas.
03 — Models
SVR / SVC + FinBERT
SVR predicts price, SVC predicts direction, FinBERT scores headline tone.
04 — Surface
React dashboard
TypeScript + Recharts view with prediction charts and top movers.

FinBERT (yiyanghkust/finbert-tone) is the heavyweight piece — a ~440 MB model that classifies each headline positive, negative, or neutral, then scales that into a sentiment score fed alongside the indicators into the price model's feature set.

§ 04 — What broke first

Sentiment is noisy and slow.

Two things bit early. First, FinBERT's cold start: the first request downloads hundreds of megabytes of weights, so without warming and caching the model, the initial call felt broken. Second, news-API rate limits on the free tier meant naive per-request fetching ran dry fast — headline sentiment had to be cached, not recomputed on every view.

The deeper lesson was resisting the urge to collapse everything into one confident number. Blending a fuzzy sentiment score into a price prediction and reporting a single figure would have hidden the uncertainty instead of surfacing it. Keeping the signals visible and separate was the more honest design.

5
Technical indicators — EMA, RSI, MACD, Bollinger, OBV
3
Independent signals fused per stock view
~440MB
FinBERT weights loaded for sentiment scoring
§ 05 — Designing the surface

Charts that explain themselves.

The dashboard leads with historical-versus-predicted price on a chart you can zoom from all-time down to a week, then layers in top movers, portfolio value, and the news-sentiment read for the selected company. A Material UI shell and Recharts keep it legible rather than cluttered.

The design brief was: show the ingredients, not just the verdict. A user should be able to disagree with the model and still find the view useful.

§ 06 — What I'd do differently

Three things, next time.