A comprehensive, professional-grade portfolio optimization platform combining Modern Portfolio Theory, Machine Learning, and Advanced Backtesting in an elegant web interface.
This system provides institutional-quality portfolio optimization tools accessible through both a web interface and Python API. It integrates classical portfolio theory with modern machine learning techniques to deliver robust, data-driven investment strategies.
-
π― Multiple Optimization Methods
- Mean-Variance Optimization (Markowitz)
- Black-Litterman Model with investor views
- Risk Parity & Hierarchical Risk Parity (HRP)
-
π€ Machine Learning Integration
- Random Forest for return prediction
- LSTM neural networks for time series
- Ensemble models combining multiple approaches
- 50+ technical indicators and features
-
π Professional Backtesting
- Realistic transaction costs
- Multiple rebalancing frequencies
- Comprehensive performance metrics
- Trade-by-trade analysis
-
π Modern Web Interface
- Interactive portfolio builder
- Real-time optimization
- Educational content
- Experiment validation tools
-
π Comprehensive Stock Database
- 600+ stocks across all sectors
- Major ETFs and indices
- Preset portfolios (Tech Giants, Mag 7, etc.)
- Real-time data via Yahoo Finance
- Installation
- Quick Start
- System Architecture
- Optimization Methods
- Machine Learning Models
- Web Application
- API Reference
- Usage Examples
- Validation & Testing
- Project Structure
- Contributing
- Python 3.8 or higher
- pip package manager
- 4GB+ RAM recommended
- Clone the repository
git clone <repository-url>
cd portfolio_optimization- Create virtual environment (recommended)
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install dependencies
pip install -r requirements.txtCore libraries include:
- Data:
yfinance,pandas,numpy - ML:
scikit-learn,tensorflow,xgboost,lightgbm - Optimization:
cvxpy,scipy - Web:
flask,flask-cors - Visualization:
matplotlib,seaborn,plotly - Technical Analysis:
ta
Start the Flask server:
python3 flask_app.pyAccess the application at http://localhost:5000
from src.main import PortfolioOptimizer
# Initialize optimizer
optimizer = PortfolioOptimizer(
tickers=['AAPL', 'GOOGL', 'MSFT', 'AMZN', 'META'],
start_date='2020-01-01',
end_date='2024-12-31'
)
# Collect data
optimizer.collect_data()
# Optimize portfolio
weights = optimizer.optimize_portfolio(
method='mean_variance',
objective='max_sharpe'
)
print("Optimal Weights:", weights)
# Run backtest
results = optimizer.backtest(
method='mean_variance',
rebalance_frequency='monthly'
)
print("Sharpe Ratio:", results['metrics']['sharpe_ratio'])
print("Total Return:", results['metrics']['total_return'])portfolio_optimization/
βββ src/
β βββ main.py # Main PortfolioOptimizer class
β βββ optimization/ # Optimization algorithms
β β βββ mean_variance.py # Markowitz optimization
β β βββ black_litterman.py # Black-Litterman model
β β βββ risk_parity.py # Risk parity & HRP
β βββ data/ # Data collection & processing
β β βββ data_collector.py # Yahoo Finance integration
β β βββ feature_engineering.py # Technical indicators
β βββ backtesting/ # Backtesting engine
β β βββ backtest_engine.py # Realistic backtesting
β βββ visualization/ # Plotting utilities
βββ flask_app.py # Web application server
βββ stock_database.py # 600+ stock database
βββ validate_forecasts.py # ML validation script
βββ templates/ # Web interface
βββ index.html # Portfolio optimizer
βββ learn.html # Educational content
βββ experiments.html # Validation tools
βββ about.html # Documentation
- Data Collection β Yahoo Finance API fetches historical prices
- Feature Engineering β 50+ technical indicators computed
- ML Training β Models predict expected returns
- Optimization β Algorithms find optimal weights
- Backtesting β Strategy validated on historical data
- Visualization β Results displayed in web interface
Classical portfolio theory balancing risk and return.
Objectives:
max_sharpe: Maximize Sharpe ratiomin_volatility: Minimize portfolio variancemax_return: Maximize return for target volatility
Features:
- Long-only or market-neutral constraints
- Position size limits (max weight per asset)
- Efficient frontier calculation
- Diversification ratio metrics
Example:
weights = optimizer.optimize_portfolio(
method='mean_variance',
objective='max_sharpe',
max_weight=0.4 # Max 40% per asset
)Combines market equilibrium with investor views.
Features:
- Absolute views: "AAPL will return 15%"
- Relative views: "TSLA will outperform GM by 10%"
- Confidence-weighted view integration
- Reduced estimation error vs. pure Markowitz
Example:
# Add investor views
views = [
{'type': 'absolute', 'asset': 'AAPL', 'return': 0.15, 'confidence': 0.7},
{'type': 'relative', 'asset1': 'TSLA', 'asset2': 'GM',
'outperformance': 0.10, 'confidence': 0.5}
]
weights = optimizer.optimize_portfolio(
method='black_litterman',
views=views,
risk_aversion=2.5
)Allocates capital so each asset contributes equally to portfolio risk.
Variants:
- Standard Risk Parity: Equal risk contribution
- Hierarchical Risk Parity (HRP): Uses clustering for stability
Features:
- More diversified than market-cap weighting
- Robust to estimation error
- No expected returns required
Example:
weights = optimizer.optimize_portfolio(
method='risk_parity',
use_hrp=True # Use hierarchical clustering
)50+ Technical Indicators:
- Trend: SMA, EMA, MACD, ADX
- Momentum: RSI, Stochastic, ROC
- Volatility: Bollinger Bands, ATR, Keltner Channels
- Volume: OBV, Volume SMA, VWAP
- Custom: Lagged returns, rolling statistics
- Ensemble of decision trees
- Handles non-linear relationships
- Feature importance analysis
- Fast training and prediction
- Captures temporal dependencies
- Sequence-to-sequence architecture
- Dropout for regularization
- Suitable for time series
- Combines Random Forest + LSTM
- Weighted averaging of predictions
- Improved robustness
- Reduced overfitting
# Engineer features
optimizer.engineer_features()
# Train models
optimizer.train_models(
train_ratio=0.8,
use_lstm=True,
use_rf=True,
use_ensemble=True
)
# Use ML predictions for optimization
weights = optimizer.optimize_portfolio(
method='mean_variance',
use_predictions=True # Use ML-predicted returns
)- Interactive stock selection
- Real-time optimization
- Multiple optimization methods
- Downloadable results
- Performance visualization
- Portfolio theory fundamentals
- Optimization method explanations
- Interactive examples
- Mathematical formulations
- ML model validation
- Train/test split analysis
- Prediction accuracy metrics
- Model comparison tools
- System documentation
- API usage guide
- Feature descriptions
- Getting started tutorial
- Stock Database: 600+ stocks organized by sector
- Preset Portfolios: Tech Giants, Mag 7, Diversified, etc.
- Date Range Selection: Flexible historical periods
- Advanced Options: ML integration, constraints, views
- Export: CSV download of weights and allocations
Get comprehensive stock database.
Response:
{
"Technology": {
"AAPL": "Apple Inc.",
"GOOGL": "Alphabet Inc.",
...
},
"Financial Services": {...},
...
}Get preset portfolios.
Response:
{
"Tech Giants": ["AAPL", "GOOGL", "MSFT", "AMZN", "META"],
"Mag 7": ["AAPL", "GOOGL", "MSFT", "AMZN", "NVDA", "TSLA", "META"],
...
}Optimize portfolio weights.
Request:
{
"tickers": ["AAPL", "GOOGL", "MSFT"],
"start_date": "2020-01-01",
"end_date": "2024-12-31",
"method": "mean_variance",
"objective": "max_sharpe",
"use_ml": true,
"max_position_weight": 0.4
}Response:
{
"session_id": "1234567890.123",
"weights": {
"AAPL": 0.35,
"GOOGL": 0.30,
"MSFT": 0.35
},
"statistics": {
"expected_return": 0.18,
"volatility": 0.22,
"sharpe_ratio": 0.82
}
}Run portfolio backtest.
Request:
{
"session_id": "1234567890.123",
"method": "mean_variance",
"rebalance_frequency": "monthly"
}Response:
{
"metrics": {
"total_return": 0.45,
"annual_return": 0.12,
"sharpe_ratio": 0.85,
"max_drawdown": -0.18,
"win_rate": 0.62,
"n_trades": 24
},
"timeseries": {
"dates": ["2020-01-01", ...],
"cumulative_returns": [1.0, 1.02, ...],
"drawdown": [0, -0.01, ...]
},
"trades": [...]
}Run ML validation experiment.
Request:
{
"tickers": ["AAPL", "GOOGL", "MSFT"],
"train_start_date": "2020-01-01",
"train_end_date": "2023-12-31",
"test_start_date": "2024-01-01",
"test_end_date": "2024-12-31",
"ml_model": "random_forest"
}Response:
{
"portfolio_metrics": {
"predicted_return": 0.15,
"actual_return": 0.18,
"error": 0.03,
"mae": 0.025,
"r2": 0.72
},
"asset_details": [
{
"ticker": "AAPL",
"predicted": 0.20,
"actual": 0.22,
"error": 0.02
},
...
]
}Health check endpoint.
Response:
{
"status": "healthy",
"timestamp": "2024-12-05T23:16:44",
"active_sessions": 3
}from src.main import PortfolioOptimizer
# Create optimizer
optimizer = PortfolioOptimizer(
tickers=['AAPL', 'MSFT', 'GOOGL', 'AMZN'],
start_date='2020-01-01',
end_date='2024-12-31'
)
# Collect data
optimizer.collect_data()
# Optimize for maximum Sharpe ratio
weights = optimizer.optimize_portfolio(
method='mean_variance',
objective='max_sharpe'
)
print(weights)# Engineer features
optimizer.engineer_features()
# Train ML models
optimizer.train_models(
use_rf=True,
use_ensemble=True
)
# Optimize using ML predictions
weights = optimizer.optimize_portfolio(
method='mean_variance',
use_predictions=True,
objective='max_sharpe'
)# Define investor views
views = [
{
'type': 'absolute',
'asset': 'AAPL',
'return': 0.20, # Expect 20% return
'confidence': 0.8
},
{
'type': 'relative',
'asset1': 'GOOGL',
'asset2': 'META',
'outperformance': 0.05, # GOOGL outperforms META by 5%
'confidence': 0.6
}
]
# Optimize with views
weights = optimizer.optimize_portfolio(
method='black_litterman',
views=views,
risk_aversion=2.5
)# Run backtest with monthly rebalancing
results = optimizer.backtest(
method='mean_variance',
rebalance_frequency='monthly'
)
# Access metrics
metrics = results['metrics']
print(f"Total Return: {metrics['total_return']:.2%}")
print(f"Sharpe Ratio: {metrics['sharpe_ratio']:.2f}")
print(f"Max Drawdown: {metrics['max_drawdown']:.2%}")
print(f"Win Rate: {metrics['win_rate']:.2%}")
# Get trade history
trades = optimizer.backtest_results['mean_variance']['engine'].get_trades()
print(trades.head())# Optimize using Hierarchical Risk Parity
weights = optimizer.optimize_portfolio(
method='risk_parity',
use_hrp=True
)
# Get risk contribution analysis
opt_obj = optimizer.optimizers['risk_parity']
risk_analysis = opt_obj.get_risk_contribution_analysis()
print(risk_analysis)The system includes a comprehensive validation script that trains models on historical data and tests predictions on out-of-sample periods.
Run validation:
python3 validate_forecasts.pyWhat it does:
- Trains ML models on 2020-2023 data
- Makes predictions for 2024-2025
- Compares predictions to actual returns
- Generates comprehensive visualizations
- Calculates error metrics (MAE, MAPE, RΒ²)
Preset portfolios tested:
- Tech Giants (AAPL, GOOGL, MSFT, AMZN, META)
- Mag 7 (+ NVDA, TSLA)
- Financial (JPM, BAC, WFC, GS, MS)
- Healthcare (JNJ, UNH, PFE, ABBV, TMO)
- Diversified (SPY, TLT, GLD, VNQ, IEF)
Output:
- Prediction accuracy metrics
- Portfolio-level error analysis
- Asset-by-asset comparison
- Visualization saved to
outputs/forecast_validation.png
Access /experiments page to:
- Configure train/test splits
- Select ML models
- Compare model performance
- Visualize prediction accuracy
- Export results
portfolio_optimization/
β
βββ src/ # Core source code
β βββ main.py # Main PortfolioOptimizer class
β βββ __init__.py
β β
β βββ optimization/ # Optimization algorithms
β β βββ __init__.py
β β βββ mean_variance.py # Markowitz optimization
β β βββ black_litterman.py # Black-Litterman model
β β βββ risk_parity.py # Risk parity & HRP
β β
β βββ data/ # Data collection & processing
β β βββ __init__.py
β β βββ data_collector.py # Yahoo Finance integration
β β βββ feature_engineering.py # Technical indicators
β β
β βββ backtesting/ # Backtesting engine
β β βββ __init__.py
β β βββ backtest_engine.py # Realistic backtesting
β β
β βββ models/ # ML models (generated)
β β
β βββ visualization/ # Plotting utilities
β βββ __init__.py
β βββ visualizer.py
β
βββ templates/ # Web interface templates
β βββ base.html # Base template
β βββ index.html # Portfolio optimizer
β βββ learn.html # Educational content
β βββ experiments.html # Validation tools
β βββ about.html # Documentation
β
βββ static/ # Static web assets
β βββ css/
β β βββ style.css
β βββ js/
β β βββ app.js # Main application logic
β β βββ experiments.js # Experiment page logic
β βββ images/
β
βββ examples/ # Usage examples
β βββ __init__.py
β βββ example_usage.py
β
βββ outputs/ # Generated outputs
β βββ forecast_validation.png
β
βββ config/ # Configuration files
β
βββ flask_app.py # Flask web application
βββ stock_database.py # 600+ stock database
βββ validate_forecasts.py # ML validation script
βββ requirements.txt # Python dependencies
βββ setup.py # Package setup
βββ .gitignore
βββ README.md # This file
Developed by Harry Markowitz, MPT provides a framework for constructing portfolios that maximize expected return for a given level of risk.
Key principles:
- Diversification reduces risk
- Efficient frontier represents optimal portfolios
- Sharpe ratio measures risk-adjusted returns
Addresses limitations of MPT by:
- Starting with market equilibrium
- Incorporating investor views with confidence levels
- Reducing sensitivity to input estimation errors
- Producing more stable, intuitive allocations
Alternative to mean-variance optimization:
- Allocates based on risk contribution, not capital
- Each asset contributes equally to portfolio risk
- More diversified than market-cap weighting
- Doesn't require expected return estimates
Advanced risk parity using machine learning:
- Uses hierarchical clustering on correlation matrix
- Recursive bisection for allocation
- More stable than traditional optimization
- Robust to estimation error
# Flask configuration
export FLASK_ENV=development
export FLASK_DEBUG=1
# Data configuration
export DATA_CACHE_DIR=./cache
export MAX_DATA_AGE_DAYS=7Create config/config.yaml:
data:
default_start_date: "2020-01-01"
cache_enabled: true
cache_dir: "./cache"
optimization:
default_method: "mean_variance"
risk_free_rate: 0.02
max_weight: 0.4
ml:
train_ratio: 0.8
random_state: 42
n_estimators: 100
backtesting:
initial_capital: 100000
transaction_cost: 0.001
rebalance_frequency: "monthly"- Total Return: Cumulative return over period
- Annual Return: Annualized return
- Volatility: Standard deviation of returns
- Sharpe Ratio: Risk-adjusted return
- Sortino Ratio: Downside risk-adjusted return
- Calmar Ratio: Return / max drawdown
- Max Drawdown: Largest peak-to-trough decline
- Win Rate: Percentage of profitable periods
- Profit Factor: Gross profit / gross loss
- VaR (95%): Value at Risk at 95% confidence
- CVaR (95%): Conditional Value at Risk
- MAE: Mean Absolute Error
- MAPE: Mean Absolute Percentage Error
- RΒ²: Coefficient of determination
- Directional Accuracy: % of correct direction predictions
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
pytest tests/
# Check code style
flake8 src/
black src/This project is licensed under the MIT License - see the LICENSE file for details.
- Harry Markowitz - Modern Portfolio Theory
- Fischer Black & Robert Litterman - Black-Litterman Model
- Marcos LΓ³pez de Prado - Hierarchical Risk Parity
- Yahoo Finance - Market data API
- scikit-learn, TensorFlow - ML frameworks
For questions, issues, or suggestions:
- Open an issue on GitHub
- Contact the development team
- Check the
/aboutpage in the web interface
- Additional optimization methods (CVaR, Mean-CVaR)
- More ML models (XGBoost, LightGBM integration)
- Real-time portfolio tracking
- Multi-period optimization
- Factor models (Fama-French)
- Options and derivatives support
- International markets
- Mobile application
- User authentication and portfolios
- Cloud deployment guide
- Markowitz, H. (1952). "Portfolio Selection". Journal of Finance
- Black, F., & Litterman, R. (1992). "Global Portfolio Optimization". Financial Analysts Journal
- LΓ³pez de Prado, M. (2016). "Building Diversified Portfolios that Outperform Out of Sample". Journal of Portfolio Management
- Modern Portfolio Theory and Investment Analysis - Elton et al.
- Advances in Active Portfolio Management - Grinold & Kahn
- Machine Learning for Asset Managers - LΓ³pez de Prado
Built with β€οΈ for quantitative finance enthusiasts