VestLab: Micro-Investment Platform is a highly scalable and robust educational application designed to empower beginners in the domain of investment strategies. By leveraging virtual currency to simulate micro-investments in a risk-free environment, this platform allows users to experiment with real-world investment strategies while avoiding the potential downsides of actual financial exposure.
The platform integrates with real-time stock data through the Alpha Vantage API, providing users with actionable insights into market trends and stock performance. It uses MongoDB with an in-memory database layer for rapid prototyping, and React.js for a dynamic, responsive user interface.
Live Application: https://microinvestmentplatform-frontend.onrender.com/
Note: The live app is hosted on Render's free tier, so the backend may take 1-2 minutes to wake up after inactivity.
VestLabDemo.mp4
- Features
- Code Structure
- Architecture Overview
- Environment and Config
- Installation
- API Reference
- Testing
- Requirements
- API Interaction with Postman
- Contributing
- Contact
Landing Page
- Public Homepage: A marketing landing page greets visitors before they log in β no account required to browse.
- Scrolling Stock Ticker: A continuously scrolling banner across the top of the landing page displays 18 stocks with live-simulated price fluctuations.
- Live Markets Grid: 18 stock cards showing symbol, price, % change badge, and a directional mini-bar β all updating every 3 seconds.
- Feature Highlights: Four cards covering Real-Time Charts, Portfolio Tracking, Leaderboard, and the What-If Simulator.
- Embedded Login: The login section at the bottom of the landing page displays the shared demo credentials (username and password visible) so anyone can enter the platform instantly with one click β no sign-up required.
Trading & Portfolio
- Secure Authentication: Login with bcrypt-hashed passwords and JWT tokens. All user-specific routes are protected and ownership-verified.
- Guest Mode: Credentials for the demo account (
Guest/demo123) are shown directly on the landing page β enter the platform with one click, no account creation needed. - Virtual Money Management: Every user starts with a $10,000 virtual balance to simulate real trading.
- Buy & Sell Stocks: Simulated trades update portfolio and balance in real time with toast notifications.
- Live Price Preview: Typing a stock symbol in the buy/sell form fetches the current price and shows the estimated cost or revenue before you trade.
- Trade Confirmation Modal: Every buy and sell shows a confirmation dialog with symbol, share count, current price, and estimated total β preventing accidental trades.
- Colour-Coded Portfolio Cards: Each held stock shows a live gain/loss badge (β²/βΌ % and $) comparing the current price to your average cost.
- Portfolio Allocation Chart: Donut chart showing the percentage breakdown of your holdings by market value.
- Portfolio Performance Chart: Line chart tracking your total portfolio value over time, computed from your full transaction history.
- Watchlist: Persist a list of stocks to monitor β prices refresh every 30 seconds. The watchlist lives in the sidebar for quick access: add a ticker with the inline form or via Stock Lookup, and remove any stock with the β button.
- Stock Lookup: Search any ticker symbol to see its current price before committing to a trade, with a one-click add to your watchlist.
- CSV Export: Download your full transaction history as a CSV file.
Market Data & Insights
- Market Indices Bar: Live-ticking strip showing S&P 500, NASDAQ, DOW Jones, Russell 2000, and VIX β displayed directly below the welcome banner.
- Interactive Stock Charts: 30-day price trends for 15 tickers rendered with Chart.js. Buttons scroll horizontally β no wrapping.
- Latest Stock News: Market headlines powered by NewsAPI, cached server-side and scrollable without pagination buttons.
- Popular Stocks: 39 tickers as pill buttons linking to Yahoo Finance for quick research.
Stats & Gamification
- Leaderboard: Top 8 users ranked by total portfolio value (cash balance + holdings at avg cost).
- User Stats Card: Total trades, buy/sell count, win rate, unique stocks traded, total invested, and realized P&L β all with hover tooltips explaining each metric.
- What-If Simulator: Enter any ticker, share count, and time horizon (1Wβ1Y) to see a simulated projected return without placing a real trade.
UI & Experience
- Redesigned Dashboard Layout: Chart and trade forms side by side, three-column row for Popular Stocks / Leaderboard / News, full-width sections for Portfolio and Transactions.
- Semantic Color System: Each section has its own color β green for Buy, red for Sell, blue for Chart/News, amber for Leaderboard/Simulator, teal for Popular/Watchlist, purple for Transactions.
- Glossary Tooltips: Hover the
?icon on any stat label for a plain-English explanation. - Shimmer Skeleton Loaders: Shown while portfolio data is loading.
- Slide-in Toast Notifications: Success and error feedback on every trade.
- Sidebar Navigation: Fixed left sidebar with section jump-links, inline watchlist with live prices, and user/logout footer.
- Scrollable Sections: Transaction history and news both scroll within a fixed-height container β no show-more buttons.
- Seeded Demo Data: Eight pre-built users with portfolios and transactions for instant demo use.
MicroInvestmentPlatform/
βββ backend/
β βββ index.js # Server entry, DB seed, route mounting
β βββ app.js # Express app factory (imported by index.js and tests)
β βββ middleware/
β β βββ auth.js # JWT verification middleware
β βββ models/
β β βββ User.js # User schema (portfolio, watchlist)
β β βββ Transaction.js # Trade record schema
β β βββ Leaderboard.js
β βββ routes/
β β βββ userRoutes.js # Auth, portfolio, balance, watchlist CRUD
β β βββ transactionRoutes.js # Buy, sell, history
β β βββ stockRoutes.js # Price lookup (Alpha Vantage + cache)
β β βββ leaderboardRoutes.js # Top 8 users by total value
β β βββ newsRoutes.js # Headlines (NewsAPI + cache)
β βββ utils/
β β βββ stockPrice.js
β βββ __tests__/
β βββ setup.js # Shared MongoDB Memory Server lifecycle helpers
β βββ userRoutes.test.js # Auth, portfolio, balance, watchlist tests
β βββ transactionRoutes.test.js # Buy, sell, history tests
β βββ stockPrice.test.js # Price fetching, caching, and fallback tests
βββ client/
βββ src/
βββ App.js # Root layout and state
βββ App.css
βββ index.css # Global design system (CSS variables, all component styles)
βββ config.js # API base URL and auth header helper
βββ components/
β βββ LandingPage.js # Public homepage (ticker, markets grid, embedded login)
β βββ AuthScreen.js
β βββ WelcomeBanner.js
β βββ MarketIndices.js # Live indices strip
β βββ Portfolio.js # Carousel + allocation donut
β βββ Portfolio.css
β βββ PortfolioAllocation.js # Donut chart (Chart.js)
β βββ PortfolioPerformance.js # Value-over-time line chart
β βββ StockChart.js # 30-day price trends
β βββ BuyStock.js
β βββ SellStock.js
β βββ StockSearch.js # Ticker lookup + watchlist add
β βββ Watchlist.js # Persistent watchlist with live prices
β βββ SidebarWatchlist.js # Compact watchlist panel rendered inside the sidebar
β βββ WhatIfSimulator.js # Hypothetical return calculator
β βββ PopularStocks.js # 39 ticker chips
β βββ Leaderboard.js # Top 8 users
β βββ LatestNews.js # Scrollable news feed
β βββ TransactionHistory.js # Scrollable table + CSV export
β βββ UserStats.js # Trade stats with tooltips
β βββ Tooltip.js # Reusable hover tooltip
β βββ ConfirmModal.js # Trade confirmation dialog
β βββ ScrollNav.js # Floating dot navigation
βββ context/
β βββ ToastContext.js
βββ hooks/
βββ useDebounce.js
- React UI renders dashboards and sends authenticated requests to the backend.
- Express API handles auth (bcrypt + JWT), trades, news proxying, and leaderboard logic.
- Auth Middleware verifies JWT tokens and enforces per-user data ownership on all protected routes.
- Alpha Vantage provides stock prices used in buy/sell flows and charts, served via a 5-minute in-memory cache.
- NewsAPI provides market headlines through a backend proxy with a 30-minute cache.
- MongoDB Memory Server stores users, portfolios, watchlists, and transactions in-memory by default.
Environment variables are split by layer:
backend/.env:ALPHA_VANTAGE_API_KEY,NEWS_API_KEY,PORT,JWT_SECRET,MONGODB_URI(optional)client/.env:REACT_APP_STOCK_API_KEY(optional, only for local stock charts)
-
Clone the repository:
gh repo clone mariarodr1136/MicroInvestmentPlatform
If you prefer HTTPS:
git clone https://github.com/mariarodr1136/MicroInvestmentPlatform.git
-
Navigate to the backend directory:
cd MicroInvestmentPlatform/backend -
Install backend dependencies:
npm install
-
Set up environment variables (backend): Create a
.envfile inbackend/with:ALPHA_VANTAGE_API_KEY=your_alpha_vantage_api_key NEWS_API_KEY=your_newsapi_key PORT=5001 JWT_SECRET=your-strong-random-secret-here
Optional β use MongoDB Atlas instead of in-memory storage:
MONGODB_URI=your_mongodb_uri
-
Start the backend server:
node index.js
-
In a new terminal, navigate to the frontend directory:
cd MicroInvestmentPlatform/client -
Install frontend dependencies:
npm install
-
Set up environment variables (frontend): Create a
.envfile inclient/only if you want live stock charts locally:REACT_APP_STOCK_API_KEY=your_alpha_vantage_api_key
-
Start the frontend:
npm start
The app runs on
http://localhost:3000by default.
API keys:
- Alpha Vantage: https://www.alphavantage.co
- NewsAPI: https://newsapi.org
Base URL: http://localhost:5001
Public endpoints (no auth required):
POST /api/user/registerPOST /api/user/loginGET /api/leaderboardGET /api/news
Protected endpoints (require Authorization: Bearer <token> header):
GET /api/user/{id}/portfolioGET /api/user/{id}/balanceGET /api/user/{id}/usernameGET /api/user/{id}/watchlistPOST /api/user/{id}/watchlistDELETE /api/user/{id}/watchlist/{symbol}POST /api/transactions/buyPOST /api/transactions/sellGET /api/transactions/{userId}/historyGET /api/stocks/price/{symbol}
The backend has an automated test suite built with Jest and Supertest, using mongodb-memory-server to spin up a real isolated MongoDB instance per test run β no mocks for the database layer.
Run the tests
cd backend
npm testTest suite overview β 41 tests across 3 files
| File | Tests | What's covered |
|---|---|---|
userRoutes.test.js |
18 | Auth (register/login), portfolio, balance, and full watchlist CRUD |
transactionRoutes.test.js |
18 | Buy/sell trade flows, input validation, and transaction history |
stockPrice.test.js |
5 | Alpha Vantage price parsing, rate-limit fallback, error fallback, and 5-min cache |
Key scenarios tested
- Registration: creates user with $10,000 default balance and returns a signed JWT; rejects missing fields; rejects duplicate usernames.
- Login: returns token for valid credentials; returns 401 for wrong password or unknown user.
- Auth middleware: all protected routes return 401 with no token and 403 when a user requests another user's data.
- Buy flow: deducts balance, adds position to portfolio, and recalculates weighted-average cost basis when adding to an existing position. Rejects insufficient funds, fractional shares, zero/negative shares, and missing fields.
- Sell flow: credits revenue, removes fully-sold positions from portfolio, and handles partial sells correctly. Rejects selling unowned stock and over-selling.
- Transaction history: returns results sorted newest-first and respects the
limitquery parameter. - Price caching: verifies that a second fetch for the same symbol within the 5-minute TTL skips the API call entirely.
- API fallback: confirms the fallback mock-price table is used when Alpha Vantage is rate-limited or unreachable.
- Node.js v18 or later
- MongoDB (optional β in-memory mode is built-in)
- React v18
- Alpha Vantage API key
- NewsAPI key
-
Register a user
- Endpoint:
POST /api/user/register - Body:
{ "username": "string", "password": "string", "balance": 10000 } - Response:
{ "_id": "string", "username": "string", "balance": 10000, "token": "eyJ..." }
- Endpoint:
-
Login
- Endpoint:
POST /api/user/login - Body:
{ "username": "string", "password": "string" } - Response:
{ "_id": "string", "username": "string", "balance": 10000, "token": "eyJ..." }
- Endpoint:
-
Get portfolio
- Endpoint:
GET /api/user/{id}/portfolio - Headers:
Authorization: Bearer <token> - Response:
[{ "symbol": "AAPL", "shares": 5, "avgPrice": 178.5 }]
- Endpoint:
-
Get / manage watchlist
GET /api/user/{id}/watchlistβ{ "watchlist": ["AAPL", "NVDA"] }POST /api/user/{id}/watchlistbody{ "symbol": "TSLA" }β updated watchlistDELETE /api/user/{id}/watchlist/TSLAβ updated watchlist
-
Buy a stock
- Endpoint:
POST /api/transactions/buy - Headers:
Authorization: Bearer <token> - Body:
{ "symbol": "AAPL", "shares": 2 } - Response:
{ "message": "Stock purchased successfully", "balance": 9643.0 }
- Endpoint:
-
Sell a stock
- Endpoint:
POST /api/transactions/sell - Headers:
Authorization: Bearer <token> - Body:
{ "symbol": "AAPL", "shares": 1 } - Response:
{ "message": "Stock sold successfully", "balance": 10178.5, "soldShares": 1, "revenue": 178.5 }
- Endpoint:
-
Transaction history
- Endpoint:
GET /api/transactions/{userId}/history?limit=100 - Headers:
Authorization: Bearer <token> - Response: Array of transactions (most recent first), each with
symbol,shares,pricePerShare,type,date, andbuyPricePerShareon sell rows.
- Endpoint:
-
Stock price
- Endpoint:
GET /api/stocks/price/{symbol} - Headers:
Authorization: Bearer <token> - Response:
{ "symbol": "AAPL", "price": 178.50 }
- Endpoint:
-
Leaderboard
- Endpoint:
GET /api/leaderboard - Response: Array of top 8 users with
usernameandtotalValue.
- Endpoint:
Contributions are welcome. To contribute:
- Fork the repository.
- Create a new branch:
git checkout -b feat/your-feature-name
- Make your changes and commit with a clear message:
git commit -m "your commit message" - Push your branch and open a pull request with a clear description of your changes.
For questions or feedback: mrodr.contact@gmail.com