d5197cde1462e816fe1e1e60a6774d405c2c6be6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BTC Portfolio Tracker
A full-stack Bitcoin portfolio tracker with live EUR pricing, purchase/sell history, candlestick charts, and price predictions.
Features
- Live BTC price — fetched from CoinGecko in EUR, with cached fallback and stale warning
- Purchase tracking — log BTC buys with amount (EUR), price per BTC, and a custom date
- Sell tracking — log BTC sells with BTC amount, price per BTC, and a custom date
- Portfolio stats — total invested, current value, profit/loss, net BTC held
- Price prediction — enter a target BTC price to see projected portfolio value and P&L
- Interactive charts — portfolio value over time and BTC candlestick chart (OHLC stored locally)
- Edit & delete — inline editing and deletion for both purchases and sells
- Admin panel — admin users can create, list, and delete accounts
- 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 + nginx |
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, Sell, OHLCCandle ORM models
│ ├── auth.py # JWT + bcrypt
│ ├── dependencies.py # Auth dependency injection
│ ├── routes/
│ │ ├── users.py # POST /register, POST /login
│ │ ├── purchases.py # CRUD /purchases
│ │ ├── sells.py # CRUD /sells
│ │ ├── stats.py # GET /stats
│ │ ├── history.py # GET /history (365-day BTC prices)
│ │ ├── candles.py # GET /candles (OHLC data + purchases overlay)
│ │ └── admin.py # GET/POST/DELETE /admin/users
│ └── services/
│ └── btc.py # CoinGecko integration
└── frontend/
└── src/
├── App.js # Routing
├── pages/
│ └── Dashboard.js # Main view: stats, predictions, charts, tables
└── components/
├── AddPurchase.js # Purchase form (amount EUR, price, date)
├── PurchaseList.js # Purchase table (inline edit/delete)
├── AddSell.js # Sell form (BTC amount, price, date)
├── SellList.js # Sell table (inline edit/delete)
├── PortfolioChart.js # Invested vs current value over time
└── BTCCandlestickChart.js # OHLC candlestick chart with purchase markers
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 | /sells |
List user sells | Yes |
| POST | /sells |
Add a sell | Yes |
| PUT | /sells/{sell_id} |
Edit a sell | Yes |
| DELETE | /sells/{sell_id} |
Delete a sell | Yes |
| GET | /stats |
Portfolio stats (P&L, net BTC) | Yes |
| GET | /history |
365-day BTC price history | Yes |
| GET | /candles |
OHLC candles + purchase overlay | Yes |
| GET | /admin/users |
List all users (admin only) | Admin |
| POST | /admin/users |
Create a user (admin only) | Admin |
| DELETE | /admin/users/{id} |
Delete a user (admin only) | Admin |
Database
SQLite, stored at /app/data/btc_portfolio.db (persisted via Docker volume).
| Table | Columns |
|---|---|
users |
id, username (unique), password (bcrypt hash), is_admin |
purchases |
id, amount_eur, price_eur, created_at, user_id (FK) |
sells |
id, btc_amount, price_eur, created_at, user_id (FK) |
ohlc_candles |
id, date (unique, YYYY-MM-DD), open, high, low, close |
Notes
- The
SECRET_KEYinauth.pyis hardcoded — use an environment variable in production. - CoinGecko requests are unauthenticated; failures fall back to the last cached price with a UI warning.
- OHLC candle data is fetched from CoinGecko and stored locally to reduce API calls.
- CORS is restricted to
localhost:3000by default. - The frontend is served via nginx in the Docker production setup.
Description
Languages
JavaScript
65.4%
Python
33.4%
Dockerfile
0.7%
HTML
0.5%