A comprehensive portfolio management application that integrates with Trading212 API and Yahoo Finance to provide real-time portfolio tracking, analysis, and screening capabilities.
- Portfolio Tracking: Real-time portfolio value, profit/loss, and performance metrics
- Technical Analysis: RSI, SMA, Bollinger Bands, and other technical indicators
- Stock Screening: Advanced screening capabilities with customizable criteria
- Chart Visualization: Interactive charts for price and metric analysis
- Top Movers: Track top gainers and losers across different time periods
- Allocation Analysis: Sector and country allocation breakdowns
- Async Backend: High-performance async FastAPI backend
- Modern Frontend: React-based responsive web interface
- Backend: FastAPI with async SQLAlchemy and PostgreSQL
- Frontend: React with modern UI components and charts
- Data Sources: Trading212 API, Yahoo Finance API
- Database: PostgreSQL with optimized queries and caching
- Background Tasks: Celery with Redis broker for scheduled data updates
The application uses Celery for periodic background data updates. Tasks are automatically scheduled via Celery Beat.
-
update_data_task: Updates portfolio holdings, prices, currency rates, and technical indicators- Runs every 4 hours
- Fetches fresh data from Trading212 API and Yahoo Finance
-
calculate_portfolio_returns_task: Calculates Money-Weighted Rate of Return (MWRR) and Time-Weighted Rate of Return (TWRR)- Runs every 4 hours on weekdays and every 8 hours on weekends (staggered 5 minutes after
update_data_task) - Uses incremental
update_returns(rebuild=False)for fast daily updates
- Runs every 4 hours on weekdays and every 8 hours on weekends (staggered 5 minutes after
# Start Celery worker (task executor)
celery -A celery_tasks.celery_app worker --loglevel=info
# Start Celery beat (task scheduler)
celery -A celery_tasks.celery_app beat --loglevel=infoThe project uses Alembic for database migrations.
To create a new migration after modifying models.py:
alembic revision --autogenerate -m "Description of changes"To apply pending migrations to the database:
alembic upgrade headTo revert the last applied migration:
alembic downgrade -1All scripts are located in the scripts/ directory. When running manually, you must set the PYTHONPATH environment variable to the project root:
# From the project root directory
PYTHONPATH=/home/debian/sites/portfolio_tracker python scripts/backfill_portfolio_daily.py
PYTHONPATH=/home/debian/sites/portfolio_tracker python scripts/update_data.pyAvailable Scripts:
backfill_portfolio_daily.py: Backfill and calculate MWRR/TWRR metrics for historical datesupdate_returns.py: Fast incremental MWRR/TWRR updates (--rebuildfor full historical recalculation)update_data.py: Update all database tables with fresh API databackfill_currency_rates.py: Backfill historical currency exchange ratesupdate_history_from_csv.py: Import Trading212 CSV transaction exportsupdate_pies.py: Update Trading212 Pies datascrape_macrotrends_pe.py: Scrape PE ratios from Macrotrendsscrape_wisesheets_pe.py: Scrape PE ratios from Wisesheetspopulate_cik.py: Populate missing instrument CIK values from SEC ticker mapscrape_13f.py: Scrape SEC 13F institutional holdings dataget_earnings_reports.py: Fetch SEC filings (10-Q/10-K/20-F/40-F/6-K) and generate structured LLM summariesget_uk_earnings_reports.py: Fetch UK RNS earnings announcements from Investegate for.Ltickers not routed via SEC, and generate the same structured LLM summariesingest_earnings_pr.py: One-shot ingest of a single earnings-release PDF or HTML page as a temporaryPRrow, intended for same-day signal weeks before the canonical SEC filing lands; replaced byget_earnings_reports.pyonce the official filing arrives
This project maintains high code quality standards with comprehensive typing, documentation, and automated quality checks.
# Code style and linting
pycodestyle --max-line-length 120 --exclude frontend/ .
flake8 --exclude frontend/ --max-line-length=120 .
pylint --max-line-length=120 backend/
# Code formatting
ruff format --line-length 120
# Type checking
mypy .
mypy . --check-untyped-def
# Import organization
isort .- 100% Type Coverage: All functions have comprehensive type annotations
- Complete Documentation: All functions have detailed docstrings
- Async Best Practices: Proper async/await patterns throughout
- Error Handling: Comprehensive error handling and logging
- Code Organization: Clean separation of concerns and modular design
- Performance: Optimized database queries and efficient data processing
- Module-level docstrings explaining purpose and functionality
- Function docstrings with Args, Returns, and Raises sections
- Inline comments for complex business logic
- Type hints for all parameters and return values