{
 "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
}
