Case study
StoxTox
A US-equities research and custom-screener platform — 30+ REST endpoints for financials, watchlists and screeners, live prices over websockets, and shareable screener URLs, built solo end-to-end.
- Role
- Full Stack Developer
- Mode
- Team
- Headline result
- 30+ endpoints live tick feed
Context
StoxTox is a stock-research and custom-screener platform for retail investors — a lighter-weight alternative to the paywalled screeners on Bloomberg or Finviz, built around Financial Modeling Prep's data feed. I built it in 2022 as the solo full-stack developer, front to back.
The problem
Retail investors either paid for a terminal or hand-rolled a screen across a dozen browser tabs. The platform had to ingest a moving universe of US symbols and their fundamentals, expose a screener that filters on any combination of price, marketcap, P/E, ROE, dividend yield, debt-to-equity and gross profit, keep quotes ticking in real time on every open watchlist, and let a user share a screener by URL without giving up their account.
Architecture & solution
Django 4 + DRF REST API against MySQL, with Redis as cache and pub/sub. Thirty-plus endpoints covering search, quotes, income statement / balance sheet / cash flow, dividends, insider trading, key executives, company profile, news, historical data, watchlists, subscribers, upvotes, custom screener and per-user shareable screeners at /user-screener/<uuid>. Auth via SimpleJWT with access + refresh, plus django-sesame magic-link tokens issued specifically for the websocket handshake. React 16 (CRA) frontend on react-router 6 with Formik + Yup, react-stockcharts and Chart.js for the equity views, OTP-verified signup, password reset, watchlist, profile and the shared screener page. A standalone Python websockets server backed by Redis pub/sub streams live quotes to authenticated clients; a Node ws-proxy pipes that feed through from Financial Modeling Prep's WebSocket API. Two ingest jobs run under systemd: symbols_collector seeds the symbol universe from FMP /stock/list, screener_data_collector uses a thread pool to fetch balance sheet, key metrics, dividends and income statement per symbol into the ScreenerData table. Gunicorn, daphne, ws-server, ws-client, the ingest jobs and the FE are all their own systemd units.
Key decisions & tradeoffs
Django for the REST surface because I needed real auth, real permissions and real migrations more than novelty. Redis for both cache and pub/sub kept the moving parts of live pricing to one dependency. Django-sesame magic-link tokens for websocket auth — solved 'how does the socket know who you are' without shoving the JWT into a URL. UUID-addressed shareable screeners so a user can hand a friend the exact screen they built without exposing account state. Ingest as separate scripted services on systemd, not in the API process — a slow upstream response shouldn't slow a page load.
Results
Shipped the end-to-end stack — search, per-stock detail with charts and financials, watchlist, screener builder, shareable screeners, OTP signup, password reset, live price ticks over websockets — QA-deployed at qa.stoxtox.com against a live Financial Modeling Prep feed. The platform is no longer hosted; the archived codebase is what remains.
Learnings
A stock UI is twenty percent feature work and eighty percent making live numbers feel live — the systemd + Redis + django-sesame path paid its cost back on day one of trading hours. Bundling three chart libraries (react-stockcharts, igniteui, chart.js) inflated the CRA build heavily; picking one up front would have saved a lot of vendor JS. Terminating the upstream feed at the server, not proxying it from the browser, was a lesson worth internalizing before the next realtime build. And a Create-React-App-on-React-16 base aged fast — a rebuild on Next 14 + a single modern chart library would cut the FE by more than half.
Screens
Login screen — full-bleed red gradient with 'stoxtox / Talks about Stocks' next to an email + password panel and a Create-an-Account CTA
// contact
Building something like this?
If this maps to what you're planning, I can walk you through how I'd approach yours.



