StockWatch

πŸ“ˆ StockWatch

CI License: MIT

A production-deployed stock monitoring app with live market data, interactive charts, and per-user watchlists. Built with Flask and Plotly Dash, backed by the Massive.com market API and PostgreSQL.

What this project demonstrates

A full-stack web app taken end to end β€” designed, built, deployed, and running live with a public demo. It shows real third-party API integration, response caching, authentication, schema migrations, and a modular Flask architecture, all wired together and shipped to production.


πŸ”— Live Demo

Β  Β 
URL stockwatch-cqzs.onrender.com
Demo login demo@stockwatch.dev / Demo123!

⏱️ Hosted on Render’s free tier β€” the first visit after idle may take ~30s to cold-start, then responds normally. The demo account is shared for evaluation and can be reset safely.


πŸ–ΌοΈ Screenshots

Stock dashboard
Stock dashboard
Watchlist management
Watchlist management

⭐ Highlights β€” why this matters


✨ Features

Feature Description
πŸ” Authentication Registration and login via Flask-Login with hashed passwords
πŸ“Š Live market data Current prices and company details from the Massive.com REST API
πŸ“ˆ Watchlist management Create and delete multiple watchlists; add or remove tickers
πŸ“‰ Interactive charts Line charts with volume overlays β€” Today shows intraday session bars; 5D–MAX use daily history
🏒 Company fundamentals Logo, market cap, exchange, website, description, and day-over-day price change
⚑ Response caching 5-minute price cache and 24-hour company-details cache
πŸ—„οΈ Database migrations Schema versioning with Flask-Migrate / Alembic

🧰 Tech Stack

Layer Technologies
Backend Flask, SQLAlchemy, Flask-Login, Gunicorn
Frontend Plotly Dash, Dash Bootstrap Components
Database PostgreSQL (production) Β· SQLite (development)
API Massive.com
Deployment Render, Docker Compose

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Browser    │◄────►│  Flask App   │◄────►│  PostgreSQL  β”‚
β”‚              β”‚      β”‚  + Dash UI   β”‚      β”‚              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                      β”‚Massive.com   β”‚
                      β”‚ REST API     β”‚
                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Design decisions

Project layout

StockWatch/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ blueprints/      # auth Β· main Β· stock Β· user route handlers
β”‚   β”œβ”€β”€ services/        # stock_services Β· user_services (business logic)
β”‚   β”œβ”€β”€ utils/           # cache_manager Β· cache_monitor
β”‚   β”œβ”€β”€ models.py        # User, Watchlist, Stock ORM models
β”‚   β”œβ”€β”€ extensions.py    # db, migrate, login, cache instances
β”‚   └── templates/       # Jinja2 HTML templates
β”œβ”€β”€ frontend/
β”‚   └── dashboard.py     # Plotly Dash interactive dashboard
β”œβ”€β”€ migrations/          # Alembic database migrations
β”œβ”€β”€ tests/               # pytest test suite
β”œβ”€β”€ config.py            # App configuration
β”œβ”€β”€ wsgi.py              # WSGI entry point
β”œβ”€β”€ docker-compose.yml   # Local PostgreSQL via Docker
β”œβ”€β”€ Pipfile              # Pipenv dependencies
└── requirements.txt     # pip dependencies

πŸš€ Getting Started

The quickest way to run StockWatch locally is with SQLite β€” no database server, no Docker, no ports to configure. You only need Python and a free API key. (Want production parity with PostgreSQL? See Run against PostgreSQL below.)

Prerequisites

1. Clone and install

git clone https://github.com/epeltz33/StockWatch.git
cd StockWatch
pipenv install

2. Configure environment variables

Create a .env file in the project root. For the SQLite quickstart, leave DATABASE_URL out β€” the app falls back to a local SQLite file (app.db):

SECRET_KEY=any-random-string
POLYGON_API_KEY=your_massive_api_key

3. Create the database schema

pipenv run flask db upgrade

This creates app.db with all tables. FLASK_APP is already set in .flaskenv, so no extra flags are needed.

4. (Optional) Seed the demo account

pipenv run flask seed-demo-user

Creates the demo account (demo@stockwatch.dev / Demo123!) with a pre-populated watchlist, so you can log in and see data right away.

5. Run the app

pipenv run flask run --port 8080

The app is available at http://localhost:8080.

For a production-style server, use Gunicorn: pipenv run gunicorn wsgi:app --bind 0.0.0.0:8080

🐘 Run against PostgreSQL (optional)

For parity with production, run PostgreSQL locally with the bundled Docker setup. The container is published on host port 15433 (mapped to its internal 5432) so it won’t clash with an existing Postgres:

docker compose up -d    # start
docker compose down     # stop

Point DATABASE_URL at it in your .env and re-run migrations:

SECRET_KEY=any-random-string
POLYGON_API_KEY=your_massive_api_key
DATABASE_URL=postgresql://stockwatch_user:stockwatch_password@localhost:15433/stockwatch
pipenv run flask db upgrade
pipenv run flask run --port 8080
Default Docker connection details (local development only) | Variable | Value | |---|---| | **Host port** | `15433` (mapped to the container's internal `5432`) | | `POSTGRES_DB` | `stockwatch` | | `POSTGRES_USER` | `stockwatch_user` | | `POSTGRES_PASSWORD` | `stockwatch_password` |

🌐 Deployment

StockWatch ships with a render.yaml blueprint for one-click deployment.

  1. Push to GitHub β€” Render deploys from Git.
  2. Create a Render account at render.com and connect GitHub.
  3. Create a Blueprint β€” go to Dashboard β†’ New β†’ Blueprint and select the StockWatch repo. Render detects render.yaml and provisions:
    • A PostgreSQL database (stockwatch-db, ~$7/mo)
    • A web service (stockwatch, free tier with cold starts)
  4. Set secrets β€” when prompted, set POLYGON_API_KEY to your Massive.com key. SECRET_KEY and DATABASE_URL are generated automatically.
  5. Seed the demo account β€” after the first deploy, open the Render Shell for the web service and run flask seed-demo-user.
  6. Verify:
    • https://your-app.onrender.com/health β†’ {"status": "healthy"}
    • Log in with demo@stockwatch.dev / Demo123!
    • Search a ticker and confirm chart data loads

Note: Migrations run in the start command, not the build command β€” Render’s internal database hostname is only reachable at runtime.

DigitalOcean App Platform (alternative)

Use app.yaml instead:

  1. Add a Managed PostgreSQL database in the DO dashboard.
  2. Set DATABASE_URL, SECRET_KEY, and POLYGON_API_KEY as encrypted env vars.
  3. Connect the GitHub repo β€” migrations run automatically on build.

πŸ§ͺ Running Tests

pipenv run pytest

πŸ“„ License

Released under the MIT License.

πŸ“¬ Contact

Questions or feedback? Reach out at erpeltz@gmail.com.