5cf3726f598f97057526ed85050e6ce98cf98d4f
Chart now plots weekly data points from first purchase to today using candle/history price data, giving an accurate view of portfolio value over time rather than just at purchase dates. Backend seeds up to 365 days of daily close prices from CoinGecko as synthetic OHLC candles, refreshing stale entries older than 31 days. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BTC Portfolio Tracker
A full-stack Bitcoin portfolio tracker with live EUR pricing, purchase history, and interactive charts.
Features
- Live BTC price — fetched from CoinGecko in EUR
- Purchase tracking — log BTC buys with amount (EUR) and price per BTC
- Portfolio stats — total invested, current value, profit/loss
- Interactive charts — portfolio value over time and 1-year BTC price history
- Edit & delete — manage purchases with inline editing
- JWT authentication — secure per-user portfolios
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, Chart.js, dark theme |
| Backend | FastAPI, SQLAlchemy, SQLite |
| Auth | JWT (HS256, 24h expiry) + bcrypt |
| Pricing | CoinGecko API (EUR) |
| Deploy | Docker + Docker Compose |
Getting Started
Docker (recommended)
git clone <repo-url>
cd btc-portfolio
docker-compose up
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
Local Development
Backend
cd btc-portfolio/backend
pip install -r requirements.txt
uvicorn app.main:app --reload
Frontend
cd btc-portfolio/frontend
npm install
npm start
Project Structure
btc-portfolio/
├── backend/
│ └── app/
│ ├── main.py # FastAPI app + CORS
│ ├── models.py # User & Purchase ORM models
│ ├── auth.py # JWT + bcrypt
│ ├── dependencies.py # Auth dependency injection
│ ├── routes/
│ │ ├── users.py # POST /register, POST /login
│ │ ├── purchases.py # CRUD /purchases
│ │ ├── stats.py # GET /stats
│ │ └── history.py # GET /history (365-day BTC prices)
│ └── services/
│ └── btc.py # CoinGecko integration
└── frontend/
└── src/
├── App.js # Routing
├── pages/
│ └── Dashboard.js # Main view
└── components/
├── AddPurchase.js # Purchase form
├── PurchaseList.js # Purchase table (edit/delete)
├── PortfolioChart.js # Invested vs current value
└── BTCHistoryChart.js # 1-year BTC price history
API Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /register |
Create account | No |
| POST | /login |
Get JWT token | No |
| GET | /purchases |
List user purchases | Yes |
| POST | /purchases |
Add a purchase | Yes |
| PUT | /purchases/{id} |
Edit a purchase | Yes |
| DELETE | /purchases/{id} |
Delete a purchase | Yes |
| GET | /stats |
Portfolio stats (P&L) | Yes |
| GET | /history |
365-day BTC price history | Yes |
Database
SQLite, stored at /app/data/btc_portfolio.db (persisted via Docker volume).
| Table | Columns |
|---|---|
users |
id, username (unique), password (bcrypt hash) |
purchases |
id, amount_eur, price_eur, created_at, user_id (FK) |
Notes
- The
SECRET_KEYinauth.pyis hardcoded — use an environment variable in production. - CoinGecko requests are unauthenticated; failures return
0.0gracefully. - CORS is restricted to
localhost:3000by default.
Description
Languages
JavaScript
65.4%
Python
33.4%
Dockerfile
0.7%
HTML
0.5%