Professional portfolio management with analytics, optimization, risk tools, and forecasting.
Live demo (Streamlit) · Full stack (Docker) · User guide
Two ways to use the app
| Streamlit | Next.js + FastAPI (Docker) | |
|---|---|---|
| Role | Fast online preview; full feature set in the original UI | Modern web UI + API, same core/ and services/ |
| Try it | proportfolio.streamlit.app | docker compose up --build → http://localhost:3000 |
CI runs Ruff, Black, isort, Mypy, Pytest on Python 3.11 with core/ coverage ≥ 70% (see .coveragerc).
- Screenshots
- Key features
- Requirements
- Project structure
- Run locally
- Testing & code quality
- Performance
- Configuration
- Documentation
- Roadmap
- Contributing
- License
- Acknowledgments
- 4 creation methods: text, CSV, manual entry, templates
- 5-step wizard for guided creation
- Full CRUD and transaction tracking (BUY / SELL / DEPOSIT / WITHDRAWAL)
- Positions: validation, inline editing, bulk actions
- 70+ metrics: performance, risk, ratios, market
- 5 analysis tabs with interactive Plotly charts
- Benchmark comparison vs indices
- 18 methods (mean-variance, Black–Litterman, risk parity, HRP, CVaR, …)
- Efficient frontier, out-of-sample tests, flexible constraints
- VaR: historical, parametric, Cornish–Fisher, Monte Carlo
- Stress tests and scenario chains (e.g. historical crisis templates)
- 9 model families (ARIMA, GARCH, LSTM, XGBoost, Prophet, ensemble, …)
- Validation metrics and portfolio-level horizons
- History, CSV import/export, automatic positions, buy-and-hold vs with-transactions modes
- Python 3.9+ locally (CI uses 3.11)
- OS: Windows, macOS, or Linux
- Network for market data (yfinance)
- RAM 4GB+ recommended for large portfolios
- Full stack: Docker, Node.js 18+ (for
frontend/when not using Docker)
Portfolio_Management_Pro/
├── core/ # Business logic (framework-agnostic)
│ ├── analytics_engine/
│ ├── data_manager/
│ ├── optimization_engine/
│ ├── risk_engine/
│ ├── forecasting_engine/
│ └── scenario_engine/
├── services/ # Orchestration over core
├── api/ # FastAPI app (uses services + core)
├── frontend/ # Next.js UI
├── streamlit_app/ # Streamlit UI (live demo + legacy-style UI)
│ ├── app.py
│ ├── pages/
│ └── components/
├── models/ # SQLAlchemy models
├── database/ # Session, migrations
├── config/ # Settings
├── tests/ # Unit, integration, performance
└── docker-compose.yml # API + web
api/main.py— FastAPI on top ofservices/*andcore/*frontend/— Next.js, aligned with Streamlit navigation where applicabledocker-compose.yml— PostgreSQL + API + web (migrations run on API startup)
docker compose up --buildOpen:
- Frontend: http://localhost:3000
- API health: http://localhost:8000/health
Postgres is exposed on localhost:5432 (portfolio / portfolio, database portfolio).
Develop without Docker (with Postgres)
docker compose up -d postgres
# Copy .env.example → .env (DATABASE_URL with localhost)
alembic upgrade head
uvicorn api.main:app --reload --host 127.0.0.1 --port 8000Develop without Docker (SQLite only — Streamlit / quick API)
# .env: DATABASE_URL=sqlite:///./data/wmc.db
uvicorn api.main:app --reload --host 127.0.0.1 --port 8000Frontend:
cd frontend
npm install
npm run devpip install -r requirements.txt
streamlit run streamlit_app/app.pyUse a .env file if you override database or cache paths (see Configuration).
pytest# Coverage (CI uses .coveragerc — core ≥ 70%)
pytest --cov=core --cov-config=.coveragerc --cov-report=html --cov-report=term-missingpytest tests/unit/
pytest tests/integration/
pytest tests/performance/Tooling is configured in pyproject.toml (Ruff, Black, isort, Mypy). Mypy targets core/, services/, api/, config/, models/, database/.
ruff check .
black --check .
isort --check-only .
mypy core/ services/ api/ config/ models/ database/
pytest
pre-commit install # optional: git hooks| Operation | Target | Actual | Status |
|---|---|---|---|
| Portfolio creation | <100ms | ~50ms | OK |
| Fetch 1y (cached) | <10ms | <1ms | OK |
| Calculate 70 metrics | <500ms | ~14ms | OK |
| Bulk fetch (8 tickers) | <500ms | ~212ms | OK |
| Parallel fetch speedup | — | 6.83× | OK |
Create .env in the project root (optional; defaults exist in config/settings.py):
# Docker / production (see .env.example)
DATABASE_URL=postgresql+psycopg2://portfolio:portfolio@localhost:5432/portfolio
# Streamlit / local quick start without Postgres:
# DATABASE_URL=sqlite:///./data/wmc.db
LOG_LEVEL=INFO
LOG_FILE=logs/app.log
# Cache (align with your settings / deploy)
CACHE_DIR=data/cache
RISK_FREE_RATE=0.0435- USER_GUIDE.md — manual, examples, workflows
- Production plan — roadmap, status, phase-by-phase runbooks (PostgreSQL → auth → deploy)
- Portfolio management (CRUD, transactions, multiple creation flows)
- Analytics (70+ metrics), optimization (18 methods), risk, forecasting, scenarios
- Next.js + FastAPI + Docker stack alongside Streamlit
- CI: lint, format, types, tests, core coverage gate
- Transaction ledger (
ledger_mode=transactions) with scheduled rebalance maintenance - Optimization / Risk / Forecasting parity for transaction-led portfolios (synthetic optimized ledger mirrors deposits, withdrawals, and rebalance interval — see Phase 4)
- Stripe billing — Free/Pro tiers, checkout, webhooks, plan limits (Product Phase 5)
- Rebalance strategy UI — target weights editor (technical runbook)
- Reports & export (e.g. PDF) polish
- Next.js parity and UX polish vs Streamlit where needed
See docs/production/README.md for the full phased plan (status: STATUS.md).
- Railway deploy, CSV import (Phase 6+)
- Real-time or push-based data updates (where applicable)
- Fork the repository
- Branch:
git checkout -b feature/your-feature - Commit with clear messages
- Push and open a Pull Request
Guidelines
- Add or update tests for new behavior
- Keep
core/coverage ≥ 70% as enforced by CI and.coveragerc - Prefer type hints; follow existing layout and SOLID / DRY
- Run Ruff, Black, isort, Mypy before pushing (or use pre-commit)
This project is licensed under the MIT License.
- yfinance, Streamlit, Next.js, FastAPI, Plotly
- CVXPy, NumPy, Pandas, scikit-learn, TensorFlow (where used in forecasting)

