384 lines
8.8 KiB
Plaintext
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
|
|
}
|