A self-hosted, realish-time stock dashboard that displays current prices including pre-market, and after-hours data for your watchlist. Built with Node.js and vanilla JavaScript.
- 📈 Real-time stock price updates
- 🌙 Pre-market and after-hours trading data
- 📊 Interactive price charts
- 📝 Configurable watchlist with optional named sections via YAML
- 💾 Historical price tracking
- 🎨 Clean, responsive UI with price change animations
- 📈 BX Trender (short) on each watchlist card: value plus away/toward/flat chip vs prior day (hidden when history is insufficient)
- 📅 Next earnings badge on each watchlist card (Yahoo calendarEvents; hidden when unknown)
- 🔢 Sort watchlist by
|BX|(high→low; nulls last)
- Clone the repository:
git clone https://github.com/Firworksyt/PortfolioWrangler.git
cd PortfolioWrangler- Install dependencies:
npm install- Set up your configuration:
cp example.config.yaml config.yaml
# Edit config.yaml with your preferred stocks and settings- Start the server:
npm start- Open your browser to
http://localhost:3000(or your configured port)
PortfolioWrangler is available as a Docker container, published automatically with each change to the master branch.
Pull and run the latest image from GitHub Container Registry:
# Pull the latest image
docker pull ghcr.io/firworksyt/portfoliowrangler:latest
# Create a config.yaml file (or copy example.config.yaml)
cp example.config.yaml config.yaml
# Run the container
docker run -d \
-p 3000:3000 \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/data:/app/data \
--name portfoliowrangler \
ghcr.io/firworksyt/portfoliowrangler:latestThe container will be available at http://localhost:3000
The easiest way to run PortfolioWrangler with Docker:
# Clone the repository (to get docker-compose.yml)
git clone https://github.com/Firworksyt/PortfolioWrangler.git
cd PortfolioWrangler
# Create your configuration
cp example.config.yaml config.yaml
# Edit config.yaml with your preferred stocks
# Start the service
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the service
docker-compose downIf you prefer to build the Docker image yourself:
# Build the image
docker build -t portfoliowrangler .
# Run the container
docker run -d \
-p 3000:3000 \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/data:/app/data \
--name portfoliowrangler \
portfoliowranglerThe Docker container uses the following volume mounts:
/app/config.yaml- Your watchlist configuration file/app/data- SQLite database directory for persistent historical data/app/.env(optional) - Environment variables file (e.g., to override the PORT setting)
Copy example.config.yaml to config.yaml and customize it:
# Server configuration
server:
port: 3000 # Change this if you want to use a different port
# Stock watchlist with named sections
sections:
- name: Semiconductors
stocks:
- SKYT
- NVDA
- name: ETFs
stocks:
- SPYSection headers appear above each group on the dashboard. When sorting by Gainers, Losers, A–Z, or |BX|, headers are hidden and all cards are sorted globally; switching back to Default restores the sectioned layout. |BX| sorts by absolute BX high→low (null/insufficient BX sinks to the bottom).
Backward compatibility: The legacy
watchlistkey (a flat list of symbols) is still supported — no section headers will be rendered, and existing configs work without any changes.
- Frontend: Vanilla JavaScript, Chart.js
- Backend: Node.js, Express
- Database: SQLite
- Data Provider: Yahoo Finance API
The project uses a simple architecture:
server.js: Express server and API endpointsapp.js: Frontend JavaScriptdb.js: Database operationsstyles.css: UI stylingconfig.yaml: Watchlist configuration
- Cleanup structure to make it more maintainable