244 lines
5.9 KiB
Plaintext
244 lines
5.9 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e1e4398f",
|
|
"metadata": {},
|
|
"source": [
|
|
"<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "54e702d1",
|
|
"metadata": {},
|
|
"source": [
|
|
"This code performs hierarchical risk parity (HRP) portfolio optimization using historical price data of selected assets. It fetches historical price data, calculates returns, and constructs a hierarchical tree using the Pearson correlation. The code then optimizes the portfolio using HRP methodology and visualizes the portfolio allocation and risk contributions. This is useful for constructing diversified portfolios that minimize risk through hierarchical clustering."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "81a9b353",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import pandas as pd\n",
|
|
"import riskfolio as rp\n",
|
|
"from openbb import obb"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "987769bc",
|
|
"metadata": {},
|
|
"source": [
|
|
"Define a list of asset symbols for which historical price data will be retrieved"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b6b98345",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"assets = [\n",
|
|
" \"XLE\", \"XLF\", \"XLU\", \"XLI\", \"GDX\", \n",
|
|
" \"XLK\", \"XLV\", \"XLY\", \"XLP\", \"XLB\", \n",
|
|
" \"XOP\", \"IYR\", \"XHB\", \"ITB\", \"VNQ\", \n",
|
|
" \"GDXJ\", \"IYE\", \"OIH\", \"XME\", \"XRT\", \n",
|
|
" \"SMH\", \"IBB\", \"KBE\", \"KRE\", \"XTL\", \n",
|
|
"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "08cacea7",
|
|
"metadata": {},
|
|
"source": [
|
|
"Fetch historical price data for the specified assets and pivot the data into a DataFrame"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "72e8db71",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"data = (\n",
|
|
" obb\n",
|
|
" .equity\n",
|
|
" .price\n",
|
|
" .historical(assets, provider=\"yfinance\")\n",
|
|
" .to_df()\n",
|
|
" .pivot(columns=\"symbol\", values=\"close\")\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d6b073b0",
|
|
"metadata": {},
|
|
"source": [
|
|
"Calculate percentage returns from the historical price data and drop any missing values"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "3564caeb",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"returns = data.pct_change().dropna()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f9df6bf1",
|
|
"metadata": {},
|
|
"source": [
|
|
"Plot a dendrogram to visualize hierarchical clustering of asset returns using Pearson correlation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "4a6d85ac",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ax = rp.plot_dendrogram(\n",
|
|
" returns=returns,\n",
|
|
" codependence=\"pearson\",\n",
|
|
" linkage=\"single\",\n",
|
|
" k=None,\n",
|
|
" max_k=10,\n",
|
|
" leaf_order=True,\n",
|
|
" ax=None,\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "aa1da0d9",
|
|
"metadata": {},
|
|
"source": [
|
|
"Create an instance of HCPortfolio with the calculated returns for portfolio optimization"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "254f5052",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"port = rp.HCPortfolio(returns=returns)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "59421937",
|
|
"metadata": {},
|
|
"source": [
|
|
"Optimize the portfolio using Hierarchical Risk Parity (HRP) with specified parameters"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "44556ae2",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"w = port.optimization(\n",
|
|
" model=\"HRP\",\n",
|
|
" codependence=\"pearson\",\n",
|
|
" rm=\"MV\",\n",
|
|
" rf=0.05,\n",
|
|
" linkage=\"single\",\n",
|
|
" max_k=10,\n",
|
|
" leaf_order=True,\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e94bd8c4",
|
|
"metadata": {},
|
|
"source": [
|
|
"Plot a pie chart to visualize the portfolio allocation resulting from the HRP optimization"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "54d6c889",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ax = rp.plot_pie(\n",
|
|
" w=w,\n",
|
|
" title=\"HRP Naive Risk Parity\",\n",
|
|
" others=0.05,\n",
|
|
" nrow=25,\n",
|
|
" cmap=\"tab20\",\n",
|
|
" height=8,\n",
|
|
" width=10,\n",
|
|
" ax=None,\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "bc3e0460",
|
|
"metadata": {},
|
|
"source": [
|
|
"Plot the risk contributions of each asset in the optimized portfolio"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8b566981",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"ax = rp.plot_risk_con(\n",
|
|
" w=w,\n",
|
|
" cov=returns.cov(),\n",
|
|
" returns=returns,\n",
|
|
" rm=\"MV\",\n",
|
|
" rf=0,\n",
|
|
" alpha=0.05,\n",
|
|
" color=\"tab:blue\",\n",
|
|
" height=6,\n",
|
|
" width=10,\n",
|
|
" t_factor=252,\n",
|
|
" ax=None,\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2fd1f927",
|
|
"metadata": {},
|
|
"source": [
|
|
"<a href=\"https://pyquantnews.com/\">PyQuant News</a> 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 <a href=\"https://gettingstartedwithpythonforquantfinance.com/\">get started with Python for quant finance</a>. For educational purposes. Not investment advise. Use at your own risk."
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"jupytext": {
|
|
"cell_metadata_filter": "-all",
|
|
"main_language": "python",
|
|
"notebook_metadata_filter": "-all"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|