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

333 lines
7.5 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "7a0be8d0",
"metadata": {},
"source": [
"<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
]
},
{
"cell_type": "markdown",
"id": "9159b91e",
"metadata": {},
"source": [
"This code uses the OpenBB Terminal and Riskfolio libraries to create and optimize a financial portfolio based on historical stock data. It first screens for stocks hitting new highs, filters them, and retrieves their historical prices. It calculates the returns, uses them to create a portfolio, and applies mean-variance optimization to determine the optimal asset allocation. The results are then visualized and detailed with the number of shares to purchase based on a specified investment amount."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef4428e3",
"metadata": {},
"outputs": [],
"source": [
"from openbb_terminal.sdk import openbb, TerminalStyle\n",
"theme = TerminalStyle(\"light\", \"light\", \"light\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "08c0afb0",
"metadata": {},
"outputs": [],
"source": [
"import riskfolio as rp"
]
},
{
"cell_type": "markdown",
"id": "4f3bdc68",
"metadata": {},
"source": [
"Screen for stocks hitting new highs using OpenBB Terminal."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "106cb79a",
"metadata": {},
"outputs": [],
"source": [
"new_highs = openbb.stocks.screener.screener_data(\"new_high\")"
]
},
{
"cell_type": "markdown",
"id": "6a71c50c",
"metadata": {},
"source": [
"Filter stocks with a price above $15 and located in the USA."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d2f32e31",
"metadata": {},
"outputs": [],
"source": [
"port_data = new_highs[\n",
" (new_highs.Price > 15) & (new_highs.Country == \"USA\")\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "0109063b",
"metadata": {},
"source": [
"Retrieve the list of ticker symbols from the filtered data."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aea54a4d",
"metadata": {},
"outputs": [],
"source": [
"tickers = port_data.Ticker.tolist()"
]
},
{
"cell_type": "markdown",
"id": "2f647c98",
"metadata": {},
"source": [
"Fetch historical price data for the selected tickers from 2016-01-01 to 2022-12-31."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5adbca4a",
"metadata": {},
"outputs": [],
"source": [
"data = openbb.economy.index(\n",
" tickers, \n",
" start_date=\"2016-01-01\", \n",
" end_date=\"2022-12-31\"\n",
")"
]
},
{
"cell_type": "markdown",
"id": "76163388",
"metadata": {},
"source": [
"Calculate the daily percentage returns of the stock prices and drop columns with any NaN values."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "785d23f5",
"metadata": {},
"outputs": [],
"source": [
"returns = data.pct_change()[1:]\n",
"returns.dropna(how=\"any\", axis=1, inplace=True)"
]
},
{
"cell_type": "markdown",
"id": "35afdcfe",
"metadata": {},
"source": [
"Create a portfolio object using the calculated returns."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c92245e0",
"metadata": {},
"outputs": [],
"source": [
"port = rp.Portfolio(returns=returns)"
]
},
{
"cell_type": "markdown",
"id": "c06747d1",
"metadata": {},
"source": [
"Compute asset statistics such as historical mean and covariance."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ecfd866",
"metadata": {},
"outputs": [],
"source": [
"port.assets_stats(method_mu='hist', method_cov='hist', d=0.94)"
]
},
{
"cell_type": "markdown",
"id": "b7b7529f",
"metadata": {},
"source": [
"Set the lower return constraint for the optimization problem."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "808168b2",
"metadata": {},
"outputs": [],
"source": [
"port.lowerret = 0.0008"
]
},
{
"cell_type": "markdown",
"id": "a7fed1c3",
"metadata": {},
"source": [
"Perform mean-variance optimization using historical data and no risk-free rate."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "85a8ec29",
"metadata": {},
"outputs": [],
"source": [
"w_rp_c = port.rp_optimization(\n",
" model=\"Classic\", # use historical\n",
" rm=\"MV\", # use mean-variance optimization\n",
" hist=True, # use historical scenarios\n",
" rf=0, # set risk-free rate to 0\n",
" b=None # don't use constraints\n",
")"
]
},
{
"cell_type": "markdown",
"id": "e7df27bc",
"metadata": {},
"source": [
"Plot the optimized portfolio allocation as a pie chart."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "22d9a70c",
"metadata": {},
"outputs": [],
"source": [
"ax = rp.plot_pie(w=w_rp_c)"
]
},
{
"cell_type": "markdown",
"id": "78e3c04c",
"metadata": {},
"source": [
"Plot the risk contributions of each asset in the portfolio."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e3d2307b",
"metadata": {},
"outputs": [],
"source": [
"ax = rp.plot_risk_con(\n",
" w_rp_c,\n",
" cov=port.cov,\n",
" returns=port.returns,\n",
" rm=\"MV\",\n",
" rf=0,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "e077bdaf",
"metadata": {},
"source": [
"Calculate the investment amount and number of shares to purchase for each asset."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e23ce3c7",
"metadata": {},
"outputs": [],
"source": [
"port_val = 10_000\n",
"w_rp_c[\"invest_amt\"] = w_rp_c * port_val\n",
"w_rp_c[\"last_price\"] = data.iloc[-1]\n",
"w_rp_c[\"shares\"] = (w_rp_c.invest_amt / w_rp_c.last_price).astype(int)"
]
},
{
"cell_type": "markdown",
"id": "086649c5",
"metadata": {},
"source": [
"Display the optimized portfolio with investment amounts and number of shares."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0ce0af32",
"metadata": {},
"outputs": [],
"source": [
"w_rp_c"
]
},
{
"cell_type": "markdown",
"id": "4c5e18cb",
"metadata": {},
"source": [
"Sort the portfolio by asset weights in ascending order."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "707e8c1f",
"metadata": {},
"outputs": [],
"source": [
"w_rp_c.sort_values(by=\"weights\")"
]
},
{
"cell_type": "markdown",
"id": "ed9a0034",
"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
}