Product Design · Full-Stack Application · Finance

Market
Matchup

A fantasy investing competition where friends trade real stocks with simulated money. Build a league, set your rules, and track who's winning on a live leaderboard — all without risking a cent.

Product Design Full-Stack Dev React · Node · SQLite Live Market Data League System Social UX
Launch Market Matchup
ROLESolo Designer + Developer
STACKReact, Express, SQLite, Finnhub API
DEPLOYFly.io · Docker · GitHub
TYPEPersonal project · Social finance app
LIVEmarketmatchup.fly.dev
The Idea

Finance is more fun when it's a competition

Learning to invest is intimidating, and tracking stock prices is hard to care about until something's at stake. Market Matchup turns it into a competition — players start with the same simulated budget, build real portfolios using live market data, and race to grow it the most. The leaderboard updates as markets move, so every trading session actually means something.

The Fantasy Sports Model — Applied to Markets
Fantasy sports proved that real-world data becomes compelling when there's a competitive social layer. Market Matchup maps that same loop onto investing: pick stocks → track live valuations → climb the leaderboard → react to the market. The key insight: no real money means no fear barrier — players learn how markets actually behave by doing, not by reading about it.
Features & Design Process

From concept to deployed product

01
Dashboard — Your League at a Glance
The dashboard is the first thing players see after logging in. It surfaces everything that matters at once: total portfolio value with gain/loss since start, cash available vs. invested, current league rank, league status (active or ended), live standings for all competitors, and this week's performance rankings. The market status indicator shows whether the market is currently open and when it closes — and confirms that trades are allowed outside market hours, a key design decision that keeps the game accessible.
Live App — Dashboard View
Market Matchup dashboard
Live portfolio value · League rank · Overall standings · This week's performance · Auto-refresh every 30s
Real-time portfolio value League rank & standings Market open/close status Weekly performance panel Auto-refresh every 30s
02
League System — Invite Friends, Set the Rules
The league system is what makes Market Matchup a social experience rather than a solo tracker. Any user can create a league with custom rules: starting cash, competition duration, allowed stock market caps, short selling permission, and maximum position size as a percent of portfolio. Leagues generate a shareable invite code so friends can join instantly. Users can be in multiple leagues simultaneously, each with its own portfolio and leaderboard. The My Leagues view shows all active leagues side by side with full rule summaries.
Live App — My Leagues View
Market Matchup leagues
Create leagues with custom rules · Shareable invite codes · Multiple simultaneous leagues · Duration, caps, position limits
Custom league rules Starting cash amount Competition duration Max position size limit Shareable invite codes Multiple leagues per user
03
Trading — Search, Select, and Execute in Real Time
The Trade section handles the full buy/sell workflow. A stock search returns live results across the full market — typing a partial ticker or company name shows matching symbols with full names. Selecting any result loads a trade card showing the live price, today's open/high/low, previous close, and the current day's gain/loss. Players choose Buy or Sell, enter a share count, and see the total cost and their available cash update in real time before confirming. The trade executes immediately at the live market price.
Live App — Stock Search & Trade Execution
Market Matchup stock search
Live stock search · Full market coverage · Ticker + company name
Market Matchup trade panel
Live price quote · OHLC data · Buy/Sell · Real-time cost preview
Live price quotes Open · High · Low · Prev Close Buy & Sell execution Real-time cost calculation Available cash display
04
Portfolio — Full Holdings View with Live P&L
The Portfolio page shows every position in real time: symbol, shares held, average purchase price, current live price, today's price change, total position value, and gain/loss both in dollars and as a percentage. Summary cards at the top show Total Value, Cash remaining, Amount Invested, and Total Return — giving the player their complete financial picture at a glance. Buy and Sell buttons on each row let players act on any position instantly without navigating away.
Live App — Portfolio Holdings View
Market Matchup portfolio
Full holdings table · Live price & daily change · Gain/Loss per position · Summary totals · Inline buy/sell actions
Live price per holding Avg cost basis tracking Gain/Loss in $ and % Total Value · Cash · Invested Inline Buy/Sell buttons
05
Leaderboard — The Emotional Core of the Competition
The leaderboard is what turns individual investing into a competition. It shows every player's rank, total portfolio value, percentage return from starting cash, cash on hand, and holdings value — giving full transparency into who is winning and why. When a league ends, the final standings are preserved with a "Your Finish" banner so players can see exactly where they placed. The real outcome shown in the screenshot: a +27.45% return ($127,451 from a $100,000 starting balance) and a first-place finish.
Live App — Final League Leaderboard
Market Matchup leaderboard
Final standings with finish banner · Total value · % return · Cash vs. holdings breakdown · Real data from a live league
Live rank with total value Return % from starting cash Cash vs. holdings split Final standings preservation Real outcomes from live play
06
Real-Time Data Architecture — Finnhub + Express + SQLite
The app pulls live quotes from Finnhub's market data API, routes them through an Express backend, and stores portfolio snapshots in SQLite. The React frontend polls for updates every 30 seconds during market hours and every 5 minutes after hours, rendering animated gain/loss indicators as prices change. Trades are allowed at any hour — an important game design choice that lets players act on overnight news. SQLite over Postgres was a deliberate call: single-file persistence is perfect for Fly.io container deployment with no external database overhead.
Technical Architecture
DATA FLOW Finnhub API (live quotes) → Express/Node server
→ SQLite (portfolios, accounts, transactions, snapshots)
→ REST endpoints → React frontend
→ Poll: 30s market hours · 5min after hours

KEY DESIGN DECISIONS Trades allowed 24/7: players can act on overnight news
SQLite: single-file DB · zero config · perfect for Fly.io
Daily snapshots: portfolio value at market close for history
Polling over WebSocket: simpler, sufficient for 30s refresh
League isolation: separate portfolio per user per league
Finnhub live market data 30s refresh during market hours 24/7 trade execution Per-league portfolio isolation Fly.io · Docker deployment
Outcomes

Shipped, deployed, and played

Market Matchup is a fully functional, production-deployed app — not a prototype. Real leagues ran with real users and real competition outcomes. It covers the full product cycle from concept and design through frontend, backend, and deployment. The best proof it works: a +27% return in a real league, finishing first.

marketmatchup.fly.dev
+27%
Real League Return
$127,451 from $100,000 starting — #1 finish
Live
Production Deploy
Running on Fly.io with real Finnhub market data
6
Core Screens
Dashboard · Portfolio · Leagues · Leaderboard · Trade · Search
Technical Stack

Built with real tools

Frontend
React Vanilla CSS Fetch API Polling
Backend
Node.js Express SQLite Python
Data
Finnhub API Live quotes Daily snapshots 30s polling
Deploy
Fly.io Docker GitHub