Files
strategy-lab/to_explore/pyquantnews/85_SkfolioMaxDiversification.ipynb
David Brazda e3da60c647 daily update
2024-10-21 20:57:56 +02:00

8.1 KiB

No description has been provided for this image

This notebook demonstrates the use of portfolio optimization techniques to analyze and compare different investment strategies. It fetches historical price data for various sector ETFs, preprocesses it to obtain returns, and splits the data into training and testing sets. Three portfolio models—Maximum Diversification, Equal Weighted, and Random Weighted—are trained and their diversification metrics are compared. Finally, it visualizes portfolio compositions and cumulative returns to assess performance.

In [ ]:
from plotly.io import show
from sklearn.model_selection import train_test_split
from skfolio import Population
from skfolio.optimization import (
    EqualWeighted, 
    MaximumDiversification,
    Random
)
from skfolio.preprocessing import prices_to_returns
from openbb import obb

List of sector ETFs to fetch historical price data for analysis

In [ ]:
sectors = [
    "XLE", 
    "XLF", 
    "XLU", 
    "XLI", 
    "GDX", 
    "XLK", 
    "XLV", 
    "XLY", 
    "XLP", 
    "XLB", 
    "XOP", 
    "IYR", 
    "XHB", 
    "ITB", 
    "VNQ", 
    "GDXJ", 
    "IYE", 
    "OIH", 
    "XME", 
    "XRT", 
    "SMH", 
    "IBB", 
    "KBE", 
    "KRE", 
    "XTL", 
]

Fetch historical price data for the specified sector ETFs

In [ ]:
df = obb.equity.price.historical(
    sectors, 
    start_date="2010-01-01", 
    provider="yfinance"
).to_df()

Pivot the fetched data to get closing prices for each ETF and drop missing values

In [ ]:
pivoted = df.pivot(
    columns="symbol", 
    values="close"
).dropna()

Convert the closing prices to returns

In [ ]:
X = prices_to_returns(pivoted)

Split the return data into training and testing sets without shuffling

In [ ]:
X_train, X_test = train_test_split(
    X, 
    test_size=0.33, 
    shuffle=False
)

Initialize and fit the Maximum Diversification model on the training data

In [ ]:
model = MaximumDiversification()
model.fit(X_train)
ptf_model_train = model.predict(X_train)

Initialize and fit the Equal Weighted model on the training data

In [ ]:
bench = EqualWeighted()
bench.fit(X_train)
ptf_bench_train = bench.predict(X_train)

Initialize and fit the Random Weighted model on the training data

In [ ]:
random = Random()
random.fit(X_train)
ptf_random_train = random.predict(X_train)

Print the diversification metrics for each trained model

In [ ]:
print(f"Maximum Diversification model: {ptf_model_train.diversification:0.2f}")
print(f"Equal Weighted model: {ptf_bench_train.diversification:0.2f}")
print(f"Random Weighted model: {ptf_random_train.diversification:0.2f}")

Predict the portfolio composition for the testing data using the trained models

In [ ]:
ptf_model_test = model.predict(X_test)
ptf_bench_test = bench.predict(X_test)
ptf_random_test = random.predict(X_test)

Create a Population object with the predicted portfolios for comparison

In [ ]:
population = Population([
    ptf_model_test, 
    ptf_bench_test, 
    ptf_random_test
])

Plot the composition of the portfolios in the population

In [ ]:
population.plot_composition()

Plot the cumulative returns of the portfolios in the population

In [ ]:
population.plot_cumulative_returns()

Display a summary of statistics for the portfolios in the population

In [ ]:
population.summary()

PyQuant News is where finance practitioners level up with Python for quant finance, algorithmic trading, and market data analysis. Looking to get started? Check out the fastest growing, top-selling course to get started with Python for quant finance. For educational purposes. Not investment advise. Use at your own risk.