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

384 lines
8.8 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "5f2ea2cb",
"metadata": {},
"source": [
"<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
]
},
{
"cell_type": "markdown",
"id": "ab6f458d",
"metadata": {},
"source": [
"This code analyzes the relationship between Tesla (TSLA) and S&P 500 (SPY) returns using linear regression. It downloads historical price data for TSLA and SPY, calculates daily returns, and plots them. A linear regression model is then used to estimate the alpha and beta of TSLA in relation to SPY. The code also constructs and evaluates a beta-hedged portfolio combining TSLA and SPY returns."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4e952311",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from statsmodels import regression\n",
"import statsmodels.api as sm\n",
"import matplotlib.pyplot as plt\n",
"import yfinance as yf"
]
},
{
"cell_type": "markdown",
"id": "60b5a085",
"metadata": {},
"source": [
"Download historical price data for TSLA and SPY from Yahoo Finance"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c84671a0",
"metadata": {},
"outputs": [],
"source": [
"data = yf.download(\"TSLA, SPY\", start=\"2014-01-01\", end=\"2015-01-01\")"
]
},
{
"cell_type": "markdown",
"id": "81dc42f6",
"metadata": {},
"source": [
"Extract adjusted close prices for TSLA and SPY"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bd0ff214",
"metadata": {},
"outputs": [],
"source": [
"asset = data[\"Adj Close\"].TSLA\n",
"benchmark = data[\"Adj Close\"].SPY"
]
},
{
"cell_type": "markdown",
"id": "b77d7257",
"metadata": {},
"source": [
"Calculate daily returns for TSLA and SPY and drop any missing values"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8c2ec45f",
"metadata": {},
"outputs": [],
"source": [
"asset_returns = asset.pct_change().dropna()\n",
"benchmark_returns = benchmark.pct_change().dropna()"
]
},
{
"cell_type": "markdown",
"id": "4b54ff94",
"metadata": {},
"source": [
"Plot daily returns for TSLA and SPY"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9da3ec4c",
"metadata": {},
"outputs": [],
"source": [
"asset_returns.plot()\n",
"benchmark_returns.plot()\n",
"plt.ylabel(\"Daily Return\")\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"id": "6864d36d",
"metadata": {},
"source": [
"Extract daily returns values for linear regression analysis"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "23a6712a",
"metadata": {
"lines_to_next_cell": 1
},
"outputs": [],
"source": [
"X = benchmark_returns.values\n",
"Y = asset_returns.values"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "04e42249",
"metadata": {
"lines_to_next_cell": 1
},
"outputs": [],
"source": [
"def linreg(x, y):\n",
" \"\"\"Perform linear regression on two arrays.\n",
" \n",
" This function adds a constant to x, performs linear regression, \n",
" and returns the alpha and beta coefficients.\n",
" \n",
" Parameters\n",
" ----------\n",
" x : np.ndarray\n",
" The independent variable (e.g., benchmark returns).\n",
" y : np.ndarray\n",
" The dependent variable (e.g., asset returns).\n",
" \n",
" Returns\n",
" -------\n",
" alpha : float\n",
" The intercept of the regression line.\n",
" beta : float\n",
" The slope of the regression line.\n",
" \"\"\"\n",
"\n",
" # Add a column of 1s to fit alpha\n",
" x = sm.add_constant(x)\n",
"\n",
" # Fit the OLS regression model to the data\n",
" model = regression.linear_model.OLS(y, x).fit()\n",
"\n",
" # Remove the constant now that we're done\n",
" x = x[:, 1]\n",
"\n",
" return model.params[0], model.params[1]"
]
},
{
"cell_type": "markdown",
"id": "789ba4a8",
"metadata": {},
"source": [
"Calculate alpha and beta for TSLA relative to SPY using linear regression"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ffd2463d",
"metadata": {},
"outputs": [],
"source": [
"alpha, beta = linreg(X, Y)\n",
"print(f\"Alpha: {alpha}\")\n",
"print(f\"Beta: {beta}\")"
]
},
{
"cell_type": "markdown",
"id": "4a34f58e",
"metadata": {},
"source": [
"Generate a range of X values for plotting the regression line"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "70e5fc38",
"metadata": {},
"outputs": [],
"source": [
"X2 = np.linspace(X.min(), X.max(), 100)"
]
},
{
"cell_type": "markdown",
"id": "cac07ff2",
"metadata": {},
"source": [
"Calculate the predicted Y values (regression line) for the generated X values"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "523900e1",
"metadata": {},
"outputs": [],
"source": [
"Y_hat = X2 * beta + alpha"
]
},
{
"cell_type": "markdown",
"id": "2d92649d",
"metadata": {},
"source": [
"Plot the raw data points (TSLA vs. SPY daily returns)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "79d7840d",
"metadata": {},
"outputs": [],
"source": [
"plt.scatter(X, Y, alpha=0.3)\n",
"plt.xlabel(\"SPY Daily Return\")\n",
"plt.ylabel(\"TSLA Daily Return\")"
]
},
{
"cell_type": "markdown",
"id": "90e244dc",
"metadata": {},
"source": [
"Plot the regression line on the scatter plot"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6ce9f245",
"metadata": {},
"outputs": [],
"source": [
"plt.plot(X2, Y_hat, 'r', alpha=0.9);"
]
},
{
"cell_type": "markdown",
"id": "7cf8a6a8",
"metadata": {},
"source": [
"Construct a beta-hedged portfolio by combining TSLA and SPY returns"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ada8b88c",
"metadata": {},
"outputs": [],
"source": [
"portfolio = -1 * beta * benchmark_returns + asset_returns\n",
"portfolio.name = \"TSLA + Hedge\""
]
},
{
"cell_type": "markdown",
"id": "ad5ee872",
"metadata": {},
"source": [
"Plot the returns of the beta-hedged portfolio, TSLA, and SPY"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "163b687b",
"metadata": {},
"outputs": [],
"source": [
"portfolio.plot(alpha=0.9)\n",
"benchmark_returns.plot(alpha=0.5)\n",
"asset_returns.plot(alpha=0.5)\n",
"plt.ylabel(\"Daily Return\")\n",
"plt.legend();"
]
},
{
"cell_type": "markdown",
"id": "d8eb7cbd",
"metadata": {},
"source": [
"Print the mean and standard deviation of the beta-hedged portfolio and TSLA returns"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "99d31898",
"metadata": {},
"outputs": [],
"source": [
"print(\"means: \", portfolio.mean(), asset_returns.mean())\n",
"print(\"volatilities: \", portfolio.std(), asset_returns.std())"
]
},
{
"cell_type": "markdown",
"id": "cab17da9",
"metadata": {},
"source": [
"Extract portfolio values for further linear regression analysis"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "81a44668",
"metadata": {},
"outputs": [],
"source": [
"P = portfolio.values"
]
},
{
"cell_type": "markdown",
"id": "a926759c",
"metadata": {},
"source": [
"Calculate alpha and beta for the beta-hedged portfolio using linear regression"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "383c99d8",
"metadata": {},
"outputs": [],
"source": [
"alpha, beta = linreg(X, P)\n",
"print('alpha: ' + str(alpha))\n",
"print('beta: ' + str(beta))"
]
},
{
"cell_type": "markdown",
"id": "3fdca098",
"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
}