### Install and Setup Environment Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/1-RiskReturnModels.ipynb Install necessary dependencies and clone the repository to access sample data. ```python !pip install pandas numpy matplotlib PyPortfolioOpt import os if not os.path.isdir("data"): os.system("git clone https://github.com/pyportfolio/pyportfolioopt.git") os.chdir("PyPortfolioOpt/cookbook") ``` -------------------------------- ### Install PyPortfolioOpt from source Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md Install PyPortfolioOpt by cloning the repository and running setup.py install within the project directory. ```bash python setup.py install ``` -------------------------------- ### Install PyPortfolioOpt via pip Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/README.md Standard installation method using the Python package manager. ```bash pip install pyportfolioopt ``` -------------------------------- ### Install Dependencies and Clone Repository Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/5-Hierarchical-Risk-Parity.ipynb Installs required Python packages and clones the PyPortfolioOpt repository if the data directory does not exist. ```python !pip install pandas numpy matplotlib yfinance PyPortfolioOpt import os if not os.path.isdir('data'): os.system('git clone https://github.com/pyportfolio/pyportfolioopt.git') os.chdir('PyPortfolioOpt/cookbook') ``` -------------------------------- ### Install PyPortfolioOpt in editable mode from GitHub Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md Install PyPortfolioOpt in editable mode directly from its GitHub repository for development purposes. ```bash pip install -e git+https://github.com/pyportfolio/pyportfolioopt.git ``` -------------------------------- ### Installation Output Log Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb Console output confirming that the required dependencies are already satisfied in the current environment. ```text Requirement already satisfied: pandas in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (2.3.3) Requirement already satisfied: numpy in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (2.3.4) Requirement already satisfied: matplotlib in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (3.10.7) Requirement already satisfied: yfinance in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (0.2.66) Requirement already satisfied: PyPortfolioOpt in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (1.5.6) Requirement already satisfied: python-dateutil>=2.8.2 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from pandas) (2.9.0.post0) Requirement already satisfied: pytz>=2020.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from pandas) (2025.2) Requirement already satisfied: tzdata>=2022.7 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from pandas) (2025.2) Requirement already satisfied: contourpy>=1.0.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (1.3.3) Requirement already satisfied: cycler>=0.10 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (0.12.1) Requirement already satisfied: fonttools>=4.22.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (4.60.1) Requirement already satisfied: kiwisolver>=1.3.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (1.4.9) Requirement already satisfied: packaging>=20.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (25.0) Requirement already satisfied: pillow>=8 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (12.0.0) Requirement already satisfied: pyparsing>=3 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (3.2.5) Requirement already satisfied: requests>=2.31 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (2.32.5) Requirement already satisfied: multitasking>=0.0.7 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (0.0.12) Requirement already satisfied: platformdirs>=2.0.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (4.5.0) Requirement already satisfied: frozendict>=2.3.4 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (2.4.7) Requirement already satisfied: peewee>=3.16.2 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (3.18.3) Requirement already satisfied: beautifulsoup4>=4.11.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (4.14.2) Requirement already satisfied: curl_cffi>=0.7 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (0.13.0) Requirement already satisfied: protobuf>=3.19.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (6.33.0) Requirement already satisfied: websockets>=13.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (15.0.1) ``` -------------------------------- ### Import Libraries and Check Version Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/1-RiskReturnModels.ipynb Import core libraries and verify the installed PyPortfolioOpt version. ```python import matplotlib.pyplot as plt import numpy as np import pandas as pd import pypfopt from pypfopt import expected_returns, plotting, risk_models pypfopt.__version__ ``` -------------------------------- ### Package Installation Output Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/5-Hierarchical-Risk-Parity.ipynb System output confirming that all required dependencies are already satisfied in the current environment. ```text Output: Requirement already satisfied: pandas in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (2.3.3) Requirement already satisfied: numpy in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (2.3.4) Requirement already satisfied: matplotlib in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (3.10.7) Requirement already satisfied: yfinance in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (0.2.66) Requirement already satisfied: PyPortfolioOpt in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (1.5.6) Requirement already satisfied: python-dateutil>=2.8.2 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from pandas) (2.9.0.post0) Requirement already satisfied: pytz>=2020.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from pandas) (2025.2) Requirement already satisfied: tzdata>=2022.7 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from pandas) (2025.2) Requirement already satisfied: contourpy>=1.0.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (1.3.3) Requirement already satisfied: cycler>=0.10 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (0.12.1) Requirement already satisfied: fonttools>=4.22.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (4.60.1) Requirement already satisfied: kiwisolver>=1.3.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (1.4.9) Requirement already satisfied: packaging>=20.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (25.0) Requirement already satisfied: pillow>=8 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (12.0.0) Requirement already satisfied: pyparsing>=3 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from matplotlib) (3.2.5) Requirement already satisfied: requests>=2.31 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (2.32.5) Requirement already satisfied: multitasking>=0.0.7 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (0.0.12) Requirement already satisfied: platformdirs>=2.0.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (4.5.0) Requirement already satisfied: frozendict>=2.3.4 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (2.4.7) Requirement already satisfied: peewee>=3.16.2 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (3.18.3) Requirement already satisfied: beautifulsoup4>=4.11.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (4.14.2) Requirement already satisfied: curl_cffi>=0.7 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (0.13.0) Requirement already satisfied: protobuf>=3.19.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (6.33.0) Requirement already satisfied: websockets>=13.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from yfinance) (15.0.1) Requirement already satisfied: cvxpy>=1.1.19 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from PyPortfolioOpt) (1.7.3) Requirement already satisfied: scikit-learn>=0.24.1 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from PyPortfolioOpt) (1.7.2) Requirement already satisfied: scipy>=1.3.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from PyPortfolioOpt) (1.16.3) Requirement already satisfied: soupsieve>1.2 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from beautifulsoup4>=4.11.1->yfinance) (2.8) Requirement already satisfied: typing-extensions>=4.0.0 in /Users/thomasschmelzer/projects/PyPortfolioOpt/.venv/lib/python3.12/site-packages (from beautifulsoup4>=4.11.1->yfinance) (4.15.0) ``` -------------------------------- ### Install PyPortfolioOpt using pip Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md Use this command to install PyPortfolioOpt via pip. You may need to install cvxopt and cvxpy separately. ```bash pip install PyPortfolioOpt ``` -------------------------------- ### Display Cleaned Portfolio Weights Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Example output showing the resulting asset weights after applying L2 regularization. ```text {'GOOG': 0.06366, 'AAPL': 0.09947, 'FB': 0.15742, 'BABA': 0.08701, 'AMZN': 0.09454, 'GE': 0.0, 'AMD': 0.0, 'WMT': 0.01766, 'BAC': 0.0, 'GM': 0.0, 'T': 0.00398, 'UAA': 0.0, 'SHLD': 0.0, 'XOM': 0.03072, 'RRC': 0.00737, 'BBY': 0.07572, 'MA': 0.1769, 'PFE': 0.12346, 'JPM': 0.0, 'SBUX': 0.06209} ``` -------------------------------- ### Display Discrete Share Allocation Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Example output showing the number of shares to buy for a $20,000 portfolio. ```text {'AAPL': 2.0, 'FB': 12.0, 'BABA': 14.0, 'GE': 18.0, 'WMT': 40.0, 'GM': 58.0, 'T': 97.0, 'SHLD': 1.0, 'XOM': 47.0, 'RRC': 3.0, 'BBY': 1.0, 'PFE': 47.0, 'SBUX': 5.0} ``` -------------------------------- ### Check Library Version Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/4-Black-Litterman-Allocation.ipynb Verifies the installed version of the pypfopt library. ```python import pypfopt pypfopt.__version__ ``` -------------------------------- ### Portfolio Performance Output Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md Example output generated by the portfolio_performance method. ```text Expected annual return: 33.0% Annual volatility: 21.7% Sharpe Ratio: 1.43 ``` -------------------------------- ### Check PyPortfolioOpt Version Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/5-Hierarchical-Risk-Parity.ipynb Verify the installed version of the PyPortfolioOpt library. Ensure you have the correct version for compatibility. ```python import pandas as pd import yfinance as yf import pypfopt pypfopt.__version__ ``` -------------------------------- ### Clone PyPortfolioOpt repository Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md Clone the PyPortfolioOpt repository if you plan to use it as a starting template for modifications. ```bash git clone https://github.com/pyportfolio/pyportfolioopt ``` -------------------------------- ### Create 130/30 Portfolio Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Implement a 130/30 portfolio by setting appropriate `weight_bounds`. For example, `(-0.3, 1.0)` allows up to 30% shorting and unlimited long positions up to 100% of capital. ```python from pypfopt import EfficientFrontier, expected_returns, risk_models mu = expected_returns.mean_historical_return(df) S = risk_models.sample_cov(df) # 130/30 portfolio ef_130_30 = EfficientFrontier(mu, S, weight_bounds=(-0.3, 1.0)) weights = ef_130_30.max_sharpe() ``` -------------------------------- ### Optimize Portfolio with Custom Objective and Weight Constraint Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb This example shows how to apply a custom convex objective function while also enforcing a specific weight constraint on an asset (JD in this case). It involves adding a lambda function constraint to the EfficientFrontier object before minimizing the custom objective. Ensure `mu` and `S` are defined and `EfficientFrontier` is imported. ```python ef = EfficientFrontier(mu, S, weight_bounds=(0.01, 0.2)) jd_index = ef.tickers.index("JD") # get the index of JD ef.add_constraint(lambda w: w[jd_index] <= 0.15) ef.convex_objective(logarithmic_barrier_objective, cov_matrix=S, k=0.001) weights = ef.clean_weights() weights ``` -------------------------------- ### Import Libraries for Financial Analysis Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb Imports necessary libraries: yfinance for data retrieval, pandas for data manipulation, and numpy for numerical operations. Ensure these libraries are installed. ```python import yfinance as yf import pandas as pd import numpy as np ``` -------------------------------- ### Import necessary libraries Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/4-Black-Litterman-Allocation.ipynb Imports essential Python libraries for data manipulation, numerical operations, plotting, and financial data downloading. Ensure these libraries are installed. ```python import numpy as np import pandas as pd import matplotlib.pyplot as plt import yfinance as yf ``` -------------------------------- ### Initialize EfficientFrontier Optimizer Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Sets up the mean-variance optimization environment with expected returns and a risk model. ```python import pandas as pd from pypfopt import EfficientFrontier, expected_returns, risk_models # Prepare data df = pd.read_csv("stock_prices.csv", parse_dates=True, index_col="date") mu = expected_returns.mean_historical_return(df) S = risk_models.CovarianceShrinkage(df).ledoit_wolf() # Create optimizer ef = EfficientFrontier(mu, S) ``` -------------------------------- ### Define Convex Constraint Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb Example of a simple weight constraint in a convex optimization context. ```python ef.add_objective(lambda w: w[jd_index] == 0.10) ``` -------------------------------- ### Initialize Black-Litterman Model with Absolute Views Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/BlackLitterman.md Use a dictionary to provide absolute views for the BlackLittermanModel. ```python from pypfopt.black_litterman import BlackLittermanModel viewdict = {"AAPL": 0.20, "BBY": -0.30, "BAC": 0, "SBUX": -0.2, "T": 0.15} bl = BlackLittermanModel(cov_matrix, absolute_views=viewdict) ``` -------------------------------- ### Optimize Portfolio with Pre-calculated Metrics Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md Use this approach when expected returns and covariance matrices are already available. ```python from pypfopt.efficient_frontier import EfficientFrontier ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() ``` -------------------------------- ### Initialize Initial Portfolio Weights Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb Create an array of equal weights representing an initial portfolio allocation. ```python # Pretend that you started with a default-weight allocation initial_weights = np.array([1/len(tickers)] * len(tickers)) ``` -------------------------------- ### Initialize Efficient Frontier Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb Set up the EfficientFrontier object using expected returns and the risk model. ```python from pypfopt import EfficientFrontier, objective_functions ef = EfficientFrontier(mu, S) ``` -------------------------------- ### Add PyPortfolioOpt using Poetry Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md For best practices, add PyPortfolioOpt to your project using the dependency manager Poetry. ```bash poetry add PyPortfolioOpt ``` -------------------------------- ### Visualize and Verify Portfolio Weights Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Display the resulting weights and visualize them using a pie chart. ```python weights ``` ```python pd.Series(weights).plot.pie(figsize=(10,10)); ``` -------------------------------- ### Historical Price Data Format Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Example of the expected pandas DataFrame structure for historical asset prices, where the index is dates and columns are asset tickers. ```default XOM RRC BBY MA PFE JPM date 2010-01-04 54.068794 51.300568 32.524055 22.062426 13.940202 35.175220 2010-01-05 54.279907 51.993038 33.349487 21.997149 13.741367 35.856571 2010-01-06 54.749043 51.690697 33.090542 22.081820 13.697187 36.053574 2010-01-07 54.577045 51.593170 33.616547 21.937523 13.645634 36.767757 2010-01-08 54.358093 52.597733 32.297466 21.945297 13.756095 36.677460 ``` -------------------------------- ### Initialize Black-Litterman Model Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/4-Black-Litterman-Allocation.ipynb Creates a BlackLittermanModel instance using market-implied priors and provided views. ```python # We are using the shortcut to automatically compute market-implied prior bl = BlackLittermanModel(S, pi="market", market_caps=mcaps, risk_aversion=delta, absolute_views=viewdict, omega=omega) ``` -------------------------------- ### Optimize Portfolio with Custom Constraints Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Initialize the EfficientFrontier, apply sector constraints, and add specific ticker-level constraints before maximizing the Sharpe ratio. ```python mu = expected_returns.capm_return(prices) S = risk_models.CovarianceShrinkage(prices).ledoit_wolf() ef = EfficientFrontier(mu, S) # weight_bounds automatically set to (0, 1) ef.add_sector_constraints(sector_mapper, sector_lower, sector_upper) amzn_index = ef.tickers.index("AMZN") ef.add_constraint(lambda w: w[amzn_index] == 0.10) tsla_index = ef.tickers.index("TSLA") ef.add_constraint(lambda w: w[tsla_index] <= 0.05) ef.add_constraint(lambda w: w[10] >= 0.05) ef.max_sharpe() weights = ef.clean_weights() ``` -------------------------------- ### Configure Black-Litterman Model Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Initializes the Black-Litterman model with specific confidence levels for views. ```python # Confidence levels (0 to 1) confidences = [0.9, 0.5, 0.7] bl = BlackLittermanModel( S, pi="equal", # Equal-weighted prior absolute_views=viewdict, omega="idzorek", # Use Idzorek's method view_confidences=confidences ) posterior_rets = bl.bl_returns() weights = bl.bl_weights() ``` -------------------------------- ### Define Custom Logarithmic Barrier Objective Function Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb This Python function uses cvxpy to define a logarithmic barrier objective for portfolio optimization. It calculates the sum of logarithmic weights and portfolio variance, then subtracts a scaled sum of logs. Ensure cvxpy is installed. ```python import cvxpy as cp # Note: functions are minimised. If you want to maximise an objective, stick a minus sign in it. def logarithmic_barrier_objective(w, cov_matrix, k=0.1): log_sum = cp.sum(cp.log(w)) var = cp.quad_form(w, cov_matrix) return var - k * log_sum ``` -------------------------------- ### Import EfficientFrontier Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Required import for portfolio optimization. ```python from pypfopt import EfficientFrontier ``` -------------------------------- ### Visualize Portfolio Weights Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/5-Hierarchical-Risk-Parity.ipynb Generates a pie chart of the optimized portfolio weights. ```python pd.Series(weights).plot.pie(figsize=(10, 10)); ``` -------------------------------- ### Create Efficient Frontier with Sector Constraints and L2 Regularization Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Initialize an EfficientFrontier object, add sector constraints, and apply L2 regularization. Use this when you need to balance risk and return while adhering to sector-specific investment limits and encouraging diversified weights. ```python ef = EfficientFrontier(mu, S) ef.add_sector_constraints(sector_mapper, sector_lower, sector_upper) ef.add_objective(objective_functions.L2_reg, gamma=0.1) # gamma is the tuning parameter ef.efficient_risk(0.2) weights = ef.clean_weights() weights ``` -------------------------------- ### Compare Prior, Posterior, and Views Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/4-Black-Litterman-Allocation.ipynb Creates a DataFrame to compare market priors, posterior estimates, and user views. ```python rets_df = pd.DataFrame([market_prior, ret_bl, pd.Series(viewdict)], index=["Prior", "Posterior", "Views"]).T rets_df ``` -------------------------------- ### Enable Short Selling Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Allow short selling by setting `weight_bounds` to `(-1, 1)` in the `EfficientFrontier` constructor. Negative weights indicate short positions. ```python from pypfopt import EfficientFrontier, expected_returns, risk_models mu = expected_returns.mean_historical_return(df) S = risk_models.sample_cov(df) # Allow short selling ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1)) weights = ef.max_sharpe() print(ef.clean_weights()) # {'GOOG': 0.15, 'AAPL': 0.20, 'FB': -0.10, ...} # negative = short ``` -------------------------------- ### Initialize Black-Litterman with Idzorek Method Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/4-Black-Litterman-Allocation.ipynb Creates the BlackLittermanModel instance using Idzorek's method for the uncertainty matrix. ```python bl = BlackLittermanModel(S, pi=market_prior, absolute_views=viewdict, omega="idzorek", view_confidences=confidences) ``` -------------------------------- ### Sample Tickers for PyPortfolioOpt Testing Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/README.md A list of 20 tickers used in PyPortfolioOpt for testing purposes. These tickers were selected for their liquidity, diverse performance and volatility, and varying data availability to ensure test robustness. ```python ['GOOG', 'AAPL', 'FB', 'BABA', 'AMZN', 'GE', 'AMD', 'WMT', 'BAC', 'GM', 'T', 'UAA', 'SHLD', 'XOM', 'RRC', 'BBY', 'MA', 'PFE', 'JPM', 'SBUX'] ``` -------------------------------- ### Optimize Minimum Volatility Portfolio Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Constructs a global-minimum variance portfolio by setting weight bounds to (None, None) to allow short selling. ```python S = risk_models.CovarianceShrinkage(prices).ledoit_wolf() # You don't have to provide expected returns in this case ef = EfficientFrontier(None, S, weight_bounds=(None, None)) ef.min_volatility() weights = ef.clean_weights() weights ``` -------------------------------- ### Optimize Portfolio from Historical Price Data Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/index.md Use this approach to calculate expected returns and covariance matrices from a CSV file before optimizing. ```python import pandas as pd from pypfopt.efficient_frontier import EfficientFrontier from pypfopt import risk_models from pypfopt import expected_returns # Read in price data df = pd.read_csv("tests/resources/stock_prices.csv", parse_dates=True, index_col="date") # Calculate expected returns and sample covariance mu = expected_returns.mean_historical_return(df) S = risk_models.sample_cov(df) # Optimize for maximal Sharpe ratio ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() ef.portfolio_performance(verbose=True) ``` -------------------------------- ### Analyze Portfolio Sparsity and Performance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Check how many tickers have zero weight and display the overall portfolio performance metrics. ```python num_small = len([k for k in weights if weights[k] <= 1e-4]) print(f"{num_small}/{len(ef.tickers)} tickers have zero weight") ``` ```python ef.portfolio_performance(verbose=True); ``` -------------------------------- ### Black-Litterman Model with Market-Implied Prior Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Initialize `BlackLittermanModel` using market capitalization for a market-implied prior. Specify `pi='market'` and provide `market_caps`. ```python from pypfopt import BlackLittermanModel, risk_models, expected_returns import pandas as pd df = pd.read_csv("stock_prices.csv", parse_dates=True, index_col="date") S = risk_models.sample_cov(df) # Market caps for market-implied prior market_caps = { "GOOG": 1200e9, "AAPL": 2500e9, "FB": 800e9, "AMZN": 1600e9, "MSFT": 2300e9 } # Absolute views on specific assets viewdict = { "AAPL": 0.20, # AAPL will return 20% "FB": -0.10, # FB will return -10% "GOOG": 0.15 # GOOG will return 15% } # Create Black-Litterman model with market-implied prior bl = BlackLittermanModel( S, pi="market", market_caps=market_caps, absolute_views=viewdict ) # Get posterior expected returns posterior_rets = bl.bl_returns() print(posterior_rets) # Get posterior covariance posterior_cov = bl.bl_cov() # Get implied weights directly from BL model weights = bl.bl_weights() bl.portfolio_performance(verbose=True) ``` -------------------------------- ### Initialize EfficientFrontier with Shorting Allowed Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Initializes the EfficientFrontier object allowing for short positions by setting weight bounds between -1 and 1. ```python ef = EfficientFrontier(mu, S, weight_bounds=(-1,1)) ``` -------------------------------- ### Visualize Portfolio Weights Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Plots the resulting portfolio weights as a horizontal bar chart. ```python pd.Series(weights).plot.barh(); ``` -------------------------------- ### Optimize with Constraints Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb Running a nonconvex optimization with specific constraints applied. ```python ef = EfficientFrontier(mu, S, weight_bounds=(0.01, 0.12)) ef.nonconvex_objective( deviation_risk_parity, objective_args=S, weights_sum_to_one=True, constraints=[ {"type": "eq", "fun": lambda w: w[jd_index] - 0.10}, ], ) weights = ef.clean_weights() weights ``` -------------------------------- ### Optimize Portfolio for Maximum Sharpe Ratio Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/README.md Calculates expected returns and sample covariance from price data to determine optimal portfolio weights. ```python import pandas as pd from pypfopt import EfficientFrontier from pypfopt import risk_models from pypfopt import expected_returns # Read in price data df = pd.read_csv("tests/resources/stock_prices.csv", parse_dates=True, index_col="date") # Calculate expected returns and sample covariance mu = expected_returns.mean_historical_return(df) S = risk_models.sample_cov(df) # Optimize for maximal Sharpe ratio ef = EfficientFrontier(mu, S) raw_weights = ef.max_sharpe() cleaned_weights = ef.clean_weights() ef.save_weights_to_file("weights.csv") # saves to file for name, value in cleaned_weights.items(): print(f"{name}: {value:.4f}") ``` -------------------------------- ### Download Market Data Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/4-Black-Litterman-Allocation.ipynb Retrieves historical closing prices for a ticker using yfinance. ```python market_prices = yf.download("SPY", period="max")["Close"] market_prices.head() ``` -------------------------------- ### Create Market Neutral Portfolio Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Construct a market-neutral portfolio by setting `market_neutral=True` in the `efficient_return` method. The sum of weights will be approximately zero. ```python from pypfopt import EfficientFrontier, expected_returns, risk_models mu = expected_returns.mean_historical_return(df) S = risk_models.sample_cov(df) # Market neutral portfolio (weights sum to zero) ef_neutral = EfficientFrontier(mu, S, weight_bounds=(-1, 1)) weights = ef_neutral.efficient_return(target_return=0.15, market_neutral=True) print(sum(ef_neutral.weights)) # approximately 0 ``` -------------------------------- ### Optimize for Target Volatility Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Construct a portfolio that maximizes return for a specific target volatility level. ```python ef = EfficientFrontier(mu, S) ef.add_sector_constraints(sector_mapper, sector_lower, sector_upper) ef.efficient_risk(target_volatility=0.20) weights = ef.clean_weights() weights ``` -------------------------------- ### Calculate Posterior Returns and Optimize Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/BlackLitterman.md Generate posterior returns from the Black-Litterman model and pass them to an EfficientFrontier optimizer. ```python from pypfopt import black_litterman from pypfopt.black_litterman import BlackLittermanModel from pypfopt.efficient_frontier import EfficientFrontier viewdict = {"AAPL": 0.20, "BBY": -0.30, "BAC": 0, "SBUX": -0.2, "T": 0.15} bl = BlackLittermanModel(cov_matrix, absolute_views=viewdict) rets = bl.bl_returns() ef = EfficientFrontier(rets, cov_matrix) ``` -------------------------------- ### Generate Monte Carlo Simulations Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Simulates random portfolios using the Dirichlet distribution to visualize alongside the efficient frontier. ```python n_samples = 10000 w = np.random.dirichlet(np.ones(len(mu)), n_samples) rets = w.dot(mu) stds = np.sqrt((w.T * (S @ w.T)).sum(axis=0)) sharpes = rets / stds print("Sample portfolio returns:", rets) print("Sample portfolio volatilities:", stds) ``` ```python # mus = [] # stds = [] # sharpes = [] # for _ in range(10000): # w = np.random.dirichlet(np.ones(len(mu))) # # w = np.random.rand(len(mu)) # # w /= w.sum() # ret = mu.dot(w) # std = np.sqrt(w.dot(S @ w)) # mus.append(ret) # stds.append(std) # sharpes.append(ret / std) ``` ```python # Plot efficient frontier with Monte Carlo sim ef = EfficientFrontier(mu, S) fig, ax = plt.subplots() plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False) # Find and plot the tangency portfolio ef2 = EfficientFrontier(mu, S) ef2.max_sharpe() ret_tangent, std_tangent, _ = ef2.portfolio_performance() # Plot random portfolios ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r") ``` -------------------------------- ### Plot Portfolio Weights Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Displays portfolio weights as a bar chart. Requires cleaned weights from an EfficientFrontier object. Can save to a file. ```python from pypfopt import EfficientFrontier, plotting ef = EfficientFrontier(mu, S) weights = ef.max_sharpe() cleaned = ef.clean_weights() # Plot weights plotting.plot_weights(cleaned, filename="weights.png") ``` -------------------------------- ### Add Regularization to EfficientFrontier Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/MeanVariance.md Demonstrates how to incorporate an L2 regularization objective into an existing EfficientFrontier optimization problem. ```default ef = EfficientFrontier(expected_returns, cov_matrix) # setup ef.add_objective(objective_functions.L2_reg) # add a secondary objective ef.min_volatility() # find the portfolio that minimises volatility and L2_reg ``` -------------------------------- ### Optimize Portfolio for Target Return using EfficientSemivariance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/GeneralEfficientFrontier.md Demonstrates minimizing semivariance for a specific target annual return. Requires historical price data to calculate expected returns and returns series. ```python from pypfopt import expected_returns, EfficientSemivariance df = ... # your dataframe of prices mu = expected_returns.mean_historical_return(df) historical_returns = expected_returns.returns_from_prices(df) es = EfficientSemivariance(mu, historical_returns) es.efficient_return(0.20) # We can use the same helper methods as before weights = es.clean_weights() print(weights) es.portfolio_performance(verbose=True) ``` -------------------------------- ### Import Required Libraries Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Standard imports for data manipulation, visualization, and financial data retrieval. ```python import yfinance as yf import matplotlib.pyplot as plt import pandas as pd import numpy as np ``` -------------------------------- ### Import L2 Regularization Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Import the objective functions module to apply L2 regularization for better diversification. ```python from pypfopt import objective_functions ``` -------------------------------- ### Set Minimum/Maximum Position Size Constraints Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/README.md Constrain portfolio weights so that no single security exceeds a specified maximum percentage (e.g., 10%) by setting the `weight_bounds` accordingly. ```python ef = EfficientFrontier(mu, S, weight_bounds=(0, 0.1)) ``` -------------------------------- ### Visualize Sample Covariance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/1-RiskReturnModels.ipynb Load stock data and plot the sample covariance matrix against future realized covariance. ```python df = pd.read_csv("data/stock_prices.csv", parse_dates=True, index_col="date") past_df, future_df = df.iloc[:-250], df.iloc[-250:] future_cov = risk_models.sample_cov(future_df) sample_cov = risk_models.sample_cov(past_df) plotting.plot_covariance(sample_cov, plot_correlation=True) plotting.plot_covariance(future_cov, plot_correlation=True) plt.show() ``` -------------------------------- ### Perform HRP Optimization Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/5-Hierarchical-Risk-Parity.ipynb Initializes and runs the Hierarchical Risk Parity optimizer. Note that HRP does not support custom constraints or objective functions. ```python from pypfopt import HRPOpt ``` ```python hrp = HRPOpt(rets) hrp.optimize() weights = hrp.clean_weights() weights ``` -------------------------------- ### Define Black-Litterman Picking Matrix Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/BlackLitterman.md Construct the P matrix to map views to the asset universe, where rows represent views and columns represent assets. ```python P = np.array( [ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 1, -1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0.5, 0.5, -0.5, -0.5, 0, 0], ] ) ``` -------------------------------- ### Form a Market-Neutral Portfolio Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/README.md Achieve a market-neutral portfolio (weights sum to zero) using the `efficient_return` method with `market_neutral=True`. This requires negative weights and is not applicable to max Sharpe or min volatility portfolios. ```python ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1)) for name, value in ef.efficient_return(target_return=0.2, market_neutral=True).items(): print(f"{name}: {value:.4f}") ``` -------------------------------- ### Evaluate Portfolio Performance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/README.md Displays performance metrics including expected annual return, volatility, and Sharpe ratio. ```python exp_return, volatility, sharpe=ef.portfolio_performance(verbose=True) round(exp_return, 4), round(volatility, 4), round(sharpe, 4) ``` -------------------------------- ### Calculate and Display Returns Head Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Compute returns from price data, drop NaNs, and display the first few rows of the resulting returns DataFrame. This is a common step before further analysis or optimization. ```python returns = expected_returns.returns_from_prices(prices).dropna() returns.head() ``` -------------------------------- ### Verify Net Weight of Market Neutral Portfolio Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Calculate and print the sum of all portfolio weights to verify market neutrality. For a market-neutral portfolio, the net weight should be close to zero. ```python print(f"Net weight: {sum(weights.values()):.2f}") ``` -------------------------------- ### Display Portfolio Performance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/5-Hierarchical-Risk-Parity.ipynb Calculates and prints the expected annual return, volatility, and Sharpe ratio. ```python hrp.portfolio_performance(verbose=True); ``` -------------------------------- ### Handle Short Positions in Discrete Allocation Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Supports discrete allocation for portfolios containing short positions. ```python from pypfopt import EfficientFrontier, DiscreteAllocation from pypfopt.discrete_allocation import get_latest_prices # Portfolio with shorts ef = EfficientFrontier(mu, S, weight_bounds=(-1, 1)) weights = ef.max_sharpe() cleaned = ef.clean_weights() latest_prices = get_latest_prices(df) # Allocate with short positions da = DiscreteAllocation( cleaned, latest_prices, total_portfolio_value=100000, short_ratio=0.3 # 130/30 style ) allocation, leftover = da.greedy_portfolio(reinvest=True) print(allocation) # Negative values indicate short positions ``` -------------------------------- ### Calculate Portfolio Performance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Calculates and prints the expected annual return, annual volatility, and Sharpe Ratio for the optimized portfolio. ```python ef.portfolio_performance(verbose=True) ``` -------------------------------- ### Optimize Portfolio Weights Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/4-Black-Litterman-Allocation.ipynb Uses EfficientFrontier to optimize portfolio weights based on posterior returns and covariance. ```python from pypfopt import EfficientFrontier, objective_functions ef = EfficientFrontier(ret_bl, S_bl) ef.add_objective(objective_functions.L2_reg) ef.max_sharpe() weights = ef.clean_weights() weights ``` -------------------------------- ### Construct Discrete Allocation Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Converts portfolio weights into specific share counts for a given budget and short ratio. ```python from pypfopt import DiscreteAllocation latest_prices = prices.iloc[-1] # prices as of the day you are allocating da = DiscreteAllocation(weights, latest_prices, total_portfolio_value=20000, short_ratio=0.3) alloc, leftover = da.lp_portfolio() print(f"Discrete allocation performed with ${leftover:.2f} leftover") alloc ``` -------------------------------- ### Visualize Return Model Performance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/1-RiskReturnModels.ipynb Visualizes the expected returns calculated by different methods using bar charts. This helps in comparing the distribution of returns across methods. Requires past_df and return_methods to be defined. ```python fig, axs = plt.subplots(1, len(return_methods), sharey=True, figsize=(15, 10)) for i, method in enumerate(return_methods): mu = expected_returns.return_model(past_df, method=method) axs[i].set_title(method) mu.plot.barh(ax=axs[i]) ``` -------------------------------- ### Verify Weights Sum to One Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb Confirms that the sum of the portfolio weights equals 1.0, which is a standard constraint in many portfolio optimization problems. ```python ef.weights.sum() ``` ```result np.float64(1.0) ``` -------------------------------- ### Clean and Save Portfolio Weights Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Cleans the raw optimizer output by setting tiny weights to zero and rounding the rest. The cleaned weights can then be saved to a file. ```python cleaned_weights = ef.clean_weights() ef.save_weights_to_file("weights.txt") # saves to file print(cleaned_weights) ``` -------------------------------- ### Prepare Returns for EfficientSemivariance Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Calculate returns from price data and remove any NaN values. This is a required preprocessing step for the EfficientSemivariance class. ```python returns = expected_returns.returns_from_prices(prices) returns = returns.dropna() ``` -------------------------------- ### Convert Weights to Discrete Allocation Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Calculate the number of shares to purchase for a specific portfolio value using DiscreteAllocation. ```python from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices latest_prices = get_latest_prices(df) da = DiscreteAllocation(w, latest_prices, total_portfolio_value=20000) allocation, leftover = da.lp_portfolio() print(allocation) ``` -------------------------------- ### Integrate Black-Litterman with EfficientFrontier Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Combines posterior returns from the Black-Litterman model with mean-variance optimization. ```python from pypfopt import BlackLittermanModel, EfficientFrontier, risk_models S = risk_models.sample_cov(df) market_caps = {"GOOG": 1200e9, "AAPL": 2500e9, "FB": 800e9, ...} views = {"AAPL": 0.20, "GOOG": 0.15} # Get BL posterior returns bl = BlackLittermanModel(S, pi="market", market_caps=market_caps, absolute_views=views) bl_returns = bl.bl_returns() # Use posterior returns with EfficientFrontier ef = EfficientFrontier(bl_returns, S) weights = ef.max_sharpe() ef.portfolio_performance(verbose=True) ``` -------------------------------- ### Apply L2 Regularization to EfficientFrontier Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/docs/UserGuide.md Use the L2_reg objective function to encourage diversification and reduce the number of zero-weight assets. ```python from pypfopt import objective_functions ef = EfficientFrontier(mu, S) ef.add_objective(objective_functions.L2_reg, gamma=0.1) w = ef.max_sharpe() print(ef.clean_weights()) ``` -------------------------------- ### Perform Linear Programming Allocation Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Uses integer programming for more optimal discrete asset allocation. ```python from pypfopt import DiscreteAllocation from pypfopt.discrete_allocation import get_latest_prices # Using LP for allocation da = DiscreteAllocation(cleaned, latest_prices, total_portfolio_value=50000) allocation, leftover = da.lp_portfolio(verbose=True) print(allocation) print(f"Funds remaining: ${leftover:.2f}") ``` -------------------------------- ### Compute Risk Matrix via Unified Interface Source: https://context7.com/pyportfolio/pyportfolioopt/llms.txt Provides a single entry point for various covariance estimation methods. ```python from pypfopt import risk_models # Use different methods through a single interface S_sample = risk_models.risk_matrix(df, method="sample_cov") S_semi = risk_models.risk_matrix(df, method="semicovariance") S_exp = risk_models.risk_matrix(df, method="exp_cov", span=120) S_lw = risk_models.risk_matrix(df, method="ledoit_wolf") S_lw_sf = risk_models.risk_matrix(df, method="ledoit_wolf_single_factor") S_oas = risk_models.risk_matrix(df, method="oracle_approximating") ``` -------------------------------- ### Optimize Portfolio with EfficientCVaR Source: https://github.com/pyportfolio/pyportfolioopt/blob/main/cookbook/2-Mean-Variance-Optimisation.ipynb Constructs portfolios minimizing CVaR or maximizing return for a target CVaR. ```python from pypfopt import EfficientCVaR ec = EfficientCVaR(mu, returns) ec.min_cvar() ec.portfolio_performance(verbose=True); ``` ```python from pypfopt import EfficientCVaR ec = EfficientCVaR(mu, returns) ec.efficient_risk(target_cvar=0.025) ec.portfolio_performance(verbose=True); ```