{ "cells": [ { "cell_type": "markdown", "id": "4884f415", "metadata": {}, "source": [ "# Elementary Asset Pricing Theory\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "id": "1bba4052", "metadata": {}, "source": [ "## Contents\n", "\n", "- [Elementary Asset Pricing Theory](#Elementary-Asset-Pricing-Theory) \n", " - [Overview](#Overview) \n", " - [Key Equation](#Key-Equation) \n", " - [Implications of Key Equation](#Implications-of-Key-Equation) \n", " - [Expected Return - Beta Representation](#Expected-Return---Beta-Representation) \n", " - [Mean-Variance Frontier](#Mean-Variance-Frontier) \n", " - [Sharpe Ratios and the Price of Risk](#Sharpe-Ratios-and-the-Price-of-Risk) \n", " - [Mathematical Structure of Frontier](#Mathematical-Structure-of-Frontier) \n", " - [Multi-factor Models](#Multi-factor-Models) \n", " - [Empirical Implementations](#Empirical-Implementations) \n", " - [Exercises](#Exercises) " ] }, { "cell_type": "markdown", "id": "919f40c0", "metadata": {}, "source": [ "## Overview\n", "\n", "This lecture is about some implications of asset-pricing theories that are based on the equation\n", "$E m R = 1,$ where $R$ is the gross return on an asset, $m$ is a stochastic discount factor, and $E$ is a mathematical expectation with respect to a joint probability distribution of $R$ and $m$.\n", "\n", "Instances of this equation occur in many models.\n", "\n", ">**Note**\n", ">\n", ">Chapter 1 of [[LS18](https://python-advanced.quantecon.org/zreferences.html#id173)] describes the role that this equation plays in a diverse set of\n", "models in macroeconomics, monetary economics, and public finance.\n", "\n", "We aim to convey insights about empirical implications of this equation brought out in the work of Lars Peter Hansen [[HR87](https://python-advanced.quantecon.org/zreferences.html#id115)] and Lars Peter Hansen and Ravi Jagannathan [[HJ91](https://python-advanced.quantecon.org/zreferences.html#id20)].\n", "\n", "By following their footsteps, from that single equation we’ll derive\n", "\n", "- a mean-variance frontier \n", "- a single-factor model of excess returns \n", "\n", "\n", "To do this, we use two ideas:\n", "\n", "- the equation $E m R =1$ that is implied by an application of a *law of one price* \n", "- a Cauchy-Schwartz inequality \n", "\n", "\n", "In particular, we’ll apply a Cauchy-Schwartz inequality to a population linear least squares regression equation that is\n", "implied by $E m R =1$.\n", "\n", "We’ll also describe how practitioners have implemented the model using\n", "\n", "- cross sections of returns on many assets \n", "- time series of returns on various assets \n", "\n", "\n", "For background and basic concepts about linear least squares projections, see our lecture [orthogonal projections and their applications](https://python-advanced.quantecon.org/orth_proj.html).\n", "\n", "As a sequel to the material here, please see our lecture [two modifications of mean-variance portfolio theory](https://python-advanced.quantecon.org/black_litterman.html)." ] }, { "cell_type": "markdown", "id": "949da64f", "metadata": {}, "source": [ "## Key Equation\n", "\n", "We begin with a **key asset pricing equation**:\n", "\n", "\n", "\n", "$$\n", "E m R^i = 1 \\tag{35.1}\n", "$$\n", "\n", "for $i=1, \\ldots, I$ and where\n", "\n", "\n", "\\begin{aligned}\n", "m &=\\text { stochastic discount factor } \\\\\n", "R^{i} &= \\text {random gross return on asset } i \\\\\n", "E &\\sim \\text { mathematical expectation }\n", "\\end{aligned}\n", "\n", "\n", "The random gross return $R^i$ for every asset $i$ and the scalar stochastic discount factor $m$\n", "live in a common probability space.\n", "\n", "[[HR87](https://python-advanced.quantecon.org/zreferences.html#id115)] and [[HJ91](https://python-advanced.quantecon.org/zreferences.html#id20)] explain how **existence** of a scalar stochastic discount factor that verifies equation\n", "[(35.1)](#equation-eq-emr1) is implied by a **law of one price** that requires that all portfolios of assets\n", "that bring the same payouts have the same price.\n", "\n", "They also explain how the **absence of an arbitrage** opportunity implies that the stochastic discount\n", "factor $m \\geq 0$.\n", "\n", "In order to say something about the **uniqueness** of a stochastic discount factor, we would have to impose more theoretical structure than we do in this\n", "lecture.\n", "\n", "For example, in **complete markets** models like those illustrated in this lecture [equilibrium capital structures with incomplete markets](https://python-advanced.quantecon.org/BCG_incomplete_mkts.html),\n", "the stochastic discount factor is unique.\n", "\n", "In **incomplete markets** models like those illustrated in this lecture [the Aiyagari model](https://python.quantecon.org/aiyagari.html), the stochastic discount factor is not unique." ] }, { "cell_type": "markdown", "id": "44c06f2b", "metadata": {}, "source": [ "## Implications of Key Equation\n", "\n", "We combine key equation [(35.1)](#equation-eq-emr1) with a remark of Lars Peter Hansen that “asset pricing theory is all about covariances”.\n", "\n", ">**Note**\n", ">\n", ">Lars Hansen’s remark is a concise summary of ideas in [[HR87](https://python-advanced.quantecon.org/zreferences.html#id115)] and\n", "[[HJ91](https://python-advanced.quantecon.org/zreferences.html#id20)]. Important foundations of these ideas were set down by\n", "[[Ros76](https://python-advanced.quantecon.org/zreferences.html#id16)], [[Ros78](https://python-advanced.quantecon.org/zreferences.html#id15)], [[HK79](https://python-advanced.quantecon.org/zreferences.html#id17)], [[Kre81](https://python-advanced.quantecon.org/zreferences.html#id18)], and\n", "[[CR83](https://python-advanced.quantecon.org/zreferences.html#id14)].\n", "\n", "This remark of Lars Hansen refers to the fact that interesting restrictions can be deduced by recognizing that $E m R^i$ is a component of the covariance between $m$ and $R^i$ and then using that fact to rearrange equation [(35.1)](#equation-eq-emr1).\n", "\n", "Let’s do this step by step.\n", "\n", "First note that the definition of a\n", "covariance\n", "$\\operatorname{cov}\\left(m, R^{i}\\right) = E (m - E m)(R^i - E R^i)$\n", "implies that\n", "\n", "$$\n", "E m R^i = E m E R^{i}+\\operatorname{cov}\\left(m, R^{i}\\right)\n", "$$\n", "\n", "Substituting this result into\n", "equation [(35.1)](#equation-eq-emr1) gives\n", "\n", "\n", "\n", "$$\n", "1 = E m E R^{i}+\\operatorname{cov}\\left(m, R^{i}\\right) \\tag{35.2}\n", "$$\n", "\n", "Next note that for a risk-free asset with non-random gross return $R^f$, equation\n", "[(35.1)](#equation-eq-emr1) becomes\n", "\n", "$$\n", "1 = E R^f m = R^f E m.\n", "$$\n", "\n", "This is true because we can pull the constant $R^f$ outside the mathematical expectation.\n", "\n", "It follows that the gross return on a risk-free asset is\n", "\n", "$$\n", "R^{f} = 1 / E(m)\n", "$$\n", "\n", "Using this formula for $R^f$ in equation [(35.2)](#equation-eq-emr2) and rearranging, it follows that\n", "\n", "$$\n", "R^{f} = E R^{i}+\\operatorname{cov}\\left(m, R^{i} \\right) R^{f}\n", "$$\n", "\n", "which can be rearranged to become\n", "\n", "$$\n", "E R^i = R^{f}-\\operatorname{cov}\\left(m, R^{i}\\right) R^{f} .\n", "$$\n", "\n", "It follows that we can express an **excess return** $E R^{i}-R^{f}$ on asset $i$ relative to the risk-free rate as\n", "\n", "\n", "\n", "$$\n", "E R^{i}-R^{f} = -\\operatorname{cov}\\left(m, R^{i}\\right) R^{f} \\tag{35.3}\n", "$$\n", "\n", "Equation [(35.3)](#equation-eq-emr3) can be rearranged to display important parts of asset pricing theory." ] }, { "cell_type": "markdown", "id": "013daa6f", "metadata": {}, "source": [ "## Expected Return - Beta Representation\n", "\n", "We can obtain the celebrated **expected-return-Beta -representation** for gross return $R^i$ by simply rearranging excess return equation [(35.3)](#equation-eq-emr3) to become\n", "\n", "$$\n", "E R^{i}=R^{f}+\\left(\\underbrace{\\frac{\\operatorname{cov}\\left(R^{i}, m\\right)}{\\operatorname{var}(m)}}_{\\quad\\quad\\beta_{i,m} = \\text{regression coefficient}}\\right)\\left(\\underbrace{-\\frac{\\operatorname{var}(m)}{E(m)}}_{\\quad\\lambda_{m} = \\text{price of risk}}\\right)\n", "$$\n", "\n", "or\n", "\n", "\n", "\n", "$$\n", "E R^{i}=R^{f}+\\beta_{i, m} \\lambda_{m} \\tag{35.4}\n", "$$\n", "\n", "Here\n", "\n", "- $\\beta_{i,m}$ is a (population) least squares regression coefficient of gross return $R^i$ on stochastic discount factor $m$ \n", "- $\\lambda_m$ is minus the variance of $m$ divided by the mean of $m$, an object that is sometimes called a **price of risk**. \n", "\n", "\n", "Because $\\lambda_m < 0$, equation [(35.4)](#equation-eq-erbetarep) asserts that\n", "\n", "- assets whose returns are **positively** correlated with the stochastic discount factor (SDF) $m$ have expected returns **lower** than the risk-free rate $R^f$ \n", "- assets whose returns are **negatively** correlated with the SDF $m$ have expected returns **higher** than the risk-free rate $R^f$ \n", "\n", "\n", "These patterns will be discussed more below.\n", "\n", "In particular, we’ll see that returns that are **perfectly** negatively correlated with the SDF $m$ have a special\n", "status:\n", "\n", "- they are on a **mean-variance frontier** \n", "\n", "\n", "Before we dive into that more, we’ll pause to look at an example of an SDF.\n", "\n", "To interpret representation [(35.4)](#equation-eq-erbetarep), the following widely used example helps.\n", "\n", "**Example**\n", "\n", "Let $c_t$ be the logarithm of the consumption of a *representative consumer* or just a single consumer for whom we have consumption data.\n", "\n", "A popular model of $m$ is\n", "\n", "$$\n", "m_{t+1} = \\beta \\frac{U'(C_{t+1})}{U'(C_t)}\n", "$$\n", "\n", "where $C_t$ is consumption at time $t$, $\\beta = \\exp(-\\rho)$ is a discount **factor** with $\\rho$ being\n", "the discount **rate**, and $U(\\cdot)$ is a concave, twice-diffential utility function.\n", "\n", "For a constant relative risk aversion (CRRA) utility function $U(C) = \\frac{C^{1-\\gamma}}{1-\\gamma}$ utility\n", "function $U'(C) = C^{-\\gamma}$.\n", "\n", "In this case, letting $c_t = \\log(C_t)$, we can write $m_{t+1}$ as\n", "\n", "$$\n", "m_{t+1} = \\exp(-\\rho) \\exp(- \\gamma(c_{t+1} - c_t))\n", "$$\n", "\n", "where $\\rho > 0$, $\\gamma > 0$.\n", "\n", "A popular model for the growth of log of consumption is\n", "\n", "$$\n", "c_{t+1} - c_t = \\mu + \\sigma_c \\epsilon_{t+1}\n", "$$\n", "\n", "where $\\epsilon_{t+1} \\sim {\\mathcal N}(0,1)$.\n", "\n", "Here $\\{c_t\\}$ is a random walk with drift $\\mu$, a good approximation to US per capital consumption growth.\n", "\n", "Again here\n", "\n", "- $\\gamma >0$ is a coefficient of relative risk aversion \n", "- $\\rho >0$ is a fixed intertemporal discount rate \n", "\n", "\n", "So we have\n", "\n", "$$\n", "m_{t+1} = \\exp(-\\rho) \\exp( - \\gamma \\mu - \\gamma \\sigma_c \\epsilon_{t+1})\n", "$$\n", "\n", "In this case\n", "\n", "$$\n", "E m_{t+1} = \\exp(-\\rho) \\exp \\left( - \\gamma \\mu + \\frac{\\sigma_c^2 \\gamma^2}{2} \\right)\n", "$$\n", "\n", "and\n", "\n", "$$\n", "\\operatorname{var}(m_{t+1}) = E(m) [ \\exp(\\sigma_c^2 \\gamma^2) - 1) ]\n", "$$\n", "\n", "When $\\gamma >0$, it is true that\n", "\n", "- when consumption growth is **high**, $m$ is **low** \n", "- when consumption growth is **low**, $m$ is **high** \n", "\n", "\n", "According to representation [(35.4)](#equation-eq-erbetarep), an asset with a gross return $R^i$ that is expected to be **high** when consumption growth is **low** has $\\beta_{i,m}$ positive and a **low** expected return.\n", "\n", "- because it has a high gross return when consumption growth is low, it is a good hedge against consumption risk. That justifies its low average return. \n", "\n", "\n", "An asset with an $R^i$ that is **low** when consumption growth is **low** has $\\beta_{i,m}$ negative and a **high** expected return.\n", "\n", "- because it has a low gross return when consumption growth is low, it is a poor hedge against consumption risk. That justifies its high average return. " ] }, { "cell_type": "markdown", "id": "ba17afb9", "metadata": {}, "source": [ "## Mean-Variance Frontier\n", "\n", "Now we’ll derive the celebrated **mean-variance frontier**.\n", "\n", "We do this using a method deployed by Lars Peter Hansen and Scott\n", "Richard [[HR87](https://python-advanced.quantecon.org/zreferences.html#id115)].\n", "\n", ">**Note**\n", ">\n", ">Methods of Hansen and Richard are described and used extensively by [[Coc05](https://python-advanced.quantecon.org/zreferences.html#id19)].\n", "\n", "Their idea was rearrange the key equation [(35.1)](#equation-eq-emr1), namely, $E m R^i = 1$, and then to apply a Cauchy-Schwarz inequality.\n", "\n", "A convenient way to remember the Cauchy-Schwartz inequality in our context is that it says that an $R^2$ in any regression has to be less than or equal to $1$.\n", "\n", "(Please note that here $R^2$ denotes the coefficient of determination in a regression, not a return on an asset!)\n", "\n", "Let’s apply that idea to deduce\n", "\n", "\n", "\n", "$$\n", "1= E\\left(m R^{i}\\right)=E(m) E\\left(R^{i}\\right)+\\rho_{m, R^{i}}\\frac{\\sigma(m)}{E(m)} \\sigma\\left(R^{i}\\right) \\tag{35.5}\n", "$$\n", "\n", "where the correlation coefficient $\\rho_{m, R^i}$ is defined as\n", "\n", "$$\n", "\\rho_{m, R^i} \\equiv \\frac{\\operatorname{cov}\\left(m, R^{i}\\right)}{\\sigma(m) \\sigma\\left(R^{i}\\right)}\n", "$$\n", "\n", "and where $\\sigma(\\cdot)$ denotes the standard deviation of the variable in parentheses\n", "\n", "Equation [(35.5)](#equation-eq-emr5) implies\n", "\n", "$$\n", "E R^{i}=R^{f}-\\rho_{m, R^i} \\frac{\\sigma(m)}{E(m)} \\sigma\\left(R^{i}\\right)\n", "$$\n", "\n", "Because $\\rho_{m, R^i} \\in [-1,1]$, it follows that $|\\rho_{m, R^i}| \\leq 1$ and that\n", "\n", "\n", "\n", "$$\n", "\\left|E R^i-R^{f}\\right| \\leqslant \\frac{\\sigma(m)}{E(m)} \\sigma\\left(R^{i}\\right) \\tag{35.6}\n", "$$\n", "\n", "Inequality [(35.6)](#equation-eq-erm6) delineates a **mean-variance frontier**\n", "\n", "(Actually, it looks more like a **mean-standard-deviation frontier**)\n", "\n", "Evidently, points on the frontier correspond to gross returns that are perfectly correlated\n", "(either positively or negatively) with the stochastic discount factor $m$.\n", "\n", "We summarize this observation as\n", "\n", "$$\n", "\\rho_{m, R^{i}}=\\left\\{\\begin{array}{ll}\n", "+1 & \\implies R^i \\text { is on lower frontier } \\\\\n", "-1 & \\implies R^i \\text { is on an upper frontier }\n", "\\end{array}\\right.\n", "$$\n", "\n", "Now let’s use matplotlib to draw a mean variance frontier.\n", "\n", "In drawing a frontier, we’ll set $\\sigma(m) = .25$ and $E m = .99$, values roughly consistent with what many studies calibrate from quarterly US data." ] }, { "cell_type": "code", "execution_count": null, "id": "48970bc1", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "%matplotlib inline\n", "\n", "# Define the function to plot\n", "def y(x, alpha, beta):\n", " return alpha + beta*x\n", "def z(x, alpha, beta):\n", " return alpha - beta*x\n", "\n", "sigmam = .25\n", "Em = .99\n", "\n", "# Set the values of alpha and beta\n", "alpha = 1/Em\n", "beta = sigmam/Em\n", "\n", "# Create a range of values for x\n", "x = np.linspace(0, .15, 100)\n", "\n", "# Calculate the values of y and z\n", "y_values = y(x, alpha, beta)\n", "z_values = z(x, alpha, beta)\n", "\n", "# Create a figure and axes object\n", "fig, ax = plt.subplots()\n", "\n", "# Plot y\n", "ax.plot(x, y_values, label=r'$R^f + \\frac{\\sigma(m)}{E(m)} \\sigma(R^i)$')\n", "ax.plot(x, z_values, label=r'$R^f - \\frac{\\sigma(m)}{E(m)} \\sigma(R^i)$')\n", "\n", "plt.title('mean standard deviation frontier')\n", "plt.xlabel(r\"$\\sigma(R^i)$\")\n", "plt.ylabel(r\"$E (R^i)$\")\n", "plt.text(.053, 1.015, \"(.05,1.015)\") \n", "ax.plot(.05, 1.015, 'o', label=\"$(\\sigma(R^j), E R^j)$\")\n", "# Add a legend and show the plot\n", "ax.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "1b03f04a", "metadata": {}, "source": [ "The figure shows two straight lines, the blue upper one being the locus of $( \\sigma(R^i), E(R^i)$ pairs that are on\n", "the **mean-variance frontier** or **mean-standard-deviation frontier**.\n", "\n", "The green dot refers to a return $R^j$ that is **not** on the frontier and that has moments\n", "$(\\sigma(R^j), E R^j) = (.05, 1.015)$.\n", "\n", "It is described by the statistical model\n", "\n", "$$\n", "R^j = R^i + \\epsilon^j\n", "$$\n", "\n", "where $R^i$ is a return that is on the frontier and $\\epsilon^j$ is a random variable that has mean zero and that is orthogonal to $R^i$.\n", "\n", "Then $E R^j = E R^i$ and, as a consequence of $R^j$ not being on the frontier,\n", "\n", "$$\n", "\\sigma^2(R^j) = \\sigma^2(R^i) + \\sigma^2(\\epsilon^j)\n", "$$\n", "\n", "The length of a horizontal line from the point $\\sigma(R^j), E (R^j) = .05, 1.015$ to\n", "the frontier equals\n", "\n", "$$\n", "\\sqrt{ \\sigma^2(R^i) + \\sigma^2( \\epsilon^j)} - \\sigma(R^i)\n", "$$\n", "\n", "This is a measure of the part of the risk in $R^j$ that is not priced because it is uncorrelated with the stochastic discount factor and so can be diversified away (i.e., averaged out to zero by holding a diversified portfolio)." ] }, { "cell_type": "markdown", "id": "0b7e0577", "metadata": {}, "source": [ "## Sharpe Ratios and the Price of Risk\n", "\n", "An asset’s **Sharpe ratio** is defined as\n", "\n", "$$\n", "\\frac{E(R^i) - R^f}{\\sigma(R^i)}\n", "$$\n", "\n", "The above figure reminds us that all assets $R^i$ whose returns are on the mean-standard deviation frontier\n", "satisfy\n", "\n", "$$\n", "\\frac{E(R^i) - R^f}{\\sigma(R^i)} = \\frac{\\sigma(m)}{E m}\n", "$$\n", "\n", "The ratio $\\frac{\\sigma(m)}{E m}$ is often called the **market price of risk**.\n", "\n", "Evidently it equals the maximum Sharpe ratio for any asset or portfolio of assets." ] }, { "cell_type": "markdown", "id": "452dc6f0", "metadata": {}, "source": [ "## Mathematical Structure of Frontier\n", "\n", "The mathematical structure of the mean-variance frontier described by inequality [(35.6)](#equation-eq-erm6) implies\n", "that\n", "\n", "- all returns on the frontier are perfectly correlated. \n", " Thus, \n", " - Let $R^m, R^{mv}$ be two returns on the frontier. \n", " - Then for some scalar $a$, a return $R^{m v}$ on the mean-variance frontier satisfies the affine equation\n", " $R^{m v}=R^{f}+a\\left(R^{m}-R^{f}\\right)$ . This is an **exact** equation with no **residual**. \n", "- each return $R^{mv}$ that is on the mean-variance frontier is perfectly (negatively) correlated with $m$ \n", " - $\\left(\\rho_{m, R^{mv}}=-1\\right) \\Rightarrow \\begin{cases} m=a+b R^{m v} \\\\ R^{m v}=e+d m \\end{cases}$ for some scalars $a, b, e, d$, \n", " Therefore, **any return on the mean-variance frontier is a legitimate stochastic discount factor** \n", "- for any mean-variance-efficient return $R^{m v}$ that is on the frontier but that is **not** $R^{f}$, there exists a **single-beta representation** for any return $R^i$ that takes the form: \n", "\n", "\n", "\n", "\n", "$$\n", "E R^{i}=R^{f}+\\beta_{i, R^{m v}}\\left[E\\left(R^{m v}\\right)-R^{f}\\right] \\tag{35.7}\n", "$$\n", "\n", "- the regression coefficient $\\beta_{i, R^{m v}}$ is often called asset $i$’s **beta** \n", "- The special case of a single-beta representation [(35.7)](#equation-eq-emr7) with $R^{i}=R^{m v}$ is \n", " $E R^{m v}=R^{f}+1 \\cdot\\left[E\\left(R^{m v}\\right)-R^{f}\\right]$ " ] }, { "cell_type": "markdown", "id": "44ab8d1b", "metadata": {}, "source": [ "## Multi-factor Models\n", "\n", "The single-beta representation [(35.7)](#equation-eq-emr7) is a special case of the multi-factor model\n", "\n", "$$\n", "E R^{i} =\\gamma+\\beta_{i, a} \\lambda_{a}+\\beta_{i, b} \\lambda_{b}+\\cdots\n", "$$\n", "\n", "where $\\lambda_j$ is the price of being exposed to risk factor $f_t^j$ and $\\beta_{i,j}$ is asset $i$’s exposure to that\n", "risk factor.\n", "\n", "To uncover the $\\beta_{i,j}$’s, one takes data on time series of the risk factors $f_t^j$ that are being priced\n", "and specifies the following least squares regression\n", "\n", "\n", "\n", "$$\n", "R_{t}^{i}=a_{i}+\\beta_{i, a} f_{t}^{a}+\\beta_{i, b} f_{t}^{b}+\\ldots+\\epsilon_{t}^{i}, \\quad t=1,2, \\ldots, T\\\\\n", "\\epsilon_{t}^{i} \\perp f_{t}^{j}, i=1,2, \\ldots, I; j = a, b, \\ldots \\tag{35.8}\n", "$$\n", "\n", "Special cases are:\n", "\n", "- a popular **single-factor** model specifies the single factor $f_t$ to be the return on the market portfolio \n", "- another popular **single-factor** model called the **consumption-based model** specifies the factor to be $m_{t+1} = \\beta \\frac{u^{\\prime}\\left(c_{t+1}\\right)}{u^{\\prime}\\left(c_{t}\\right)}$, where $c_t$ is a representative consumer’s time $t$ consumption. \n", "\n", "\n", "As a reminder, model objects are interpreted as follows:\n", "\n", "- $\\beta_{i,a}$ is the exposure of return $R^i$ to risk factor $f_a$ \n", "- $\\lambda_{a}$ is the price of exposure to risk factor $f_a$ " ] }, { "cell_type": "markdown", "id": "734e2ca0", "metadata": {}, "source": [ "## Empirical Implementations\n", "\n", "We briefly describe empirical implementations of multi-factor generalizations of the single-factor model described above.\n", "\n", "Two representations of a multi-factor model play importnt roles in empirical applications.\n", "\n", "One is the time series regression [(35.8)](#equation-eq-timeseriesrep)\n", "\n", "The other representation entails a **cross-section regression** of **average returns** $E R^i$ for assets\n", "$i =1, 2, \\ldots, I$ on **prices of risk** $\\lambda_j$ for $j =a, b, c, \\ldots$\n", "\n", "Here is the cross-section regression specification for a multi-factor model:\n", "\n", "$$\n", "E R^{i} =\\gamma+\\beta_{i, a} \\lambda_{a}+\\beta_{i, b} \\lambda_{b}+\\cdots\n", "$$\n", "\n", "**Testing strategies:**\n", "\n", "Time-series and cross-section regressions play roles in both **estimating** and **testing** beta representation\n", "models.\n", "\n", "The basic idea is to implement the following two steps.\n", "\n", "**Step 1:**\n", "\n", "- Estimate $a_{i}, \\beta_{i, a}, \\beta_{i, b}, \\cdots$ by running a **time series regression:** $R_{t}^{i}$ on a constant and $f_{t}^{a}, f_{t}^{b}, \\ldots$ \n", "\n", "\n", "**Step 2:**\n", "\n", "- take the $\\beta_{i, j}$’s estimated in step one as regressors together with data on average returns\n", " $E R^i$ over some period and then estimate the **cross-section regression** \n", "\n", "\n", "$$\n", "\\underbrace{E\\left(R^{i}\\right)}_{\\text{average return over time series}}=\\gamma+\\underbrace{\\beta_{i, a}}_{\\text{regressor}\\quad} \\underbrace{\\lambda_{a}}_{\\text{regression}\\text{coefficient}}+\\underbrace{\\beta_{i, b}}_{\\text{regressor}\\quad} \\underbrace{\\lambda_{b}}_{\\text{regression}\\text{coefficient}}+\\cdots+\\underbrace{\\alpha_{i}}_{\\text{pricing errors}}, i=1, \\ldots, I; \\quad \\underbrace{\\alpha_i \\perp \\beta_{i,j},j = a, b, \\ldots}_{\\text{least squares orthogonality condition}}\n", "$$\n", "\n", "- Here $\\perp$ means **orthogonal to** \n", "- estimate $\\gamma, \\lambda_{a}, \\lambda_{b}, \\ldots$ by an appropriate regression technique, recognizing that the regressors have been generated by a step 1 regression. \n", "\n", "\n", "Note that presumably the risk-free return $E R^{f}=\\gamma$.\n", "\n", "For excess returns $R^{ei} = R^i - R^f$ we have\n", "\n", "$$\n", "E R^{e i}=\\beta_{i, a} \\lambda_{a}+\\beta_{i, b} \\lambda_{b}+\\cdots+\\alpha_{i}, i=1, \\ldots, I\n", "$$\n", "\n", "In the following exercises, we illustrate aspects of these empirical strategies on artificial data.\n", "\n", "Our basic tools are random number generator that we shall use to create artificial samples that conform to the theory and\n", "least squares regressions that let us watch aspects of the theory at work.\n", "\n", "These exercises will further convince us that asset pricing theory is mostly about covariances and least squares regressions." ] }, { "cell_type": "markdown", "id": "7f9e2b30", "metadata": {}, "source": [ "## Exercises\n", "\n", "Let’s start with some imports." ] }, { "cell_type": "code", "execution_count": null, "id": "f458d32a", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import numpy as np\n", "from scipy.stats import stats\n", "import statsmodels.api as sm\n", "from statsmodels.sandbox.regression.gmm import GMM\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "id": "9eaee485", "metadata": {}, "source": [ "Lots of our calculations will involve computing population and sample OLS regressions.\n", "\n", "So we define a function for simple univariate OLS regression that calls the OLS routine from statsmodels." ] }, { "cell_type": "code", "execution_count": null, "id": "b7b34343", "metadata": { "hide-output": false }, "outputs": [], "source": [ "def simple_ols(X, Y, constant=False):\n", "\n", " if constant:\n", " X = sm.add_constant(X)\n", "\n", " model = sm.OLS(Y, X)\n", " res = model.fit()\n", "\n", " β_hat = res.params[-1]\n", " σ_hat = np.sqrt(res.resid @ res.resid / res.df_resid)\n", "\n", " return β_hat, σ_hat" ] }, { "cell_type": "markdown", "id": "92870784", "metadata": {}, "source": [ "## Exercise 35.1\n", "\n", "Look at the equation,\n", "\n", "$$\n", "R^i_t - R^f = \\beta_{i, R^m} (R^m_t - R^f) + \\sigma_i \\varepsilon_{i, t}.\n", "$$\n", "\n", "Verify that this equation is a regression equation." ] }, { "cell_type": "markdown", "id": "1781bd57", "metadata": {}, "source": [ "## Solution to[ Exercise 35.1](https://python-advanced.quantecon.org/#apl_ex1)\n", "\n", "To verify that it is a **regression equation** we must show that the residual is orthogonal to the regressor.\n", "\n", "Our assumptions about mutual orthogonality imply that\n", "\n", "$$\n", "E\\left[\\epsilon_{i,t}\\right]=0,\\quad E\\left[\\epsilon_{i,t}u_{t}\\right]=0\n", "$$\n", "\n", "It follows that\n", "\n", "\n", "\\begin{aligned}\n", "E\\left[\\sigma_{i}\\epsilon_{i,t}\\left(R_{t}^{m}-R^{f}\\right)\\right]&=E\\left[\\sigma_{i}\\epsilon_{i,t}\\left(\\xi+\\lambda u_{t}\\right)\\right] \\\\\n", "\t&=\\sigma_{i}\\xi E\\left[\\epsilon_{i,t}\\right]+\\sigma_{i}\\lambda E\\left[\\epsilon_{i,t}u_{t}\\right] \\\\\n", "\t&=0\n", "\\end{aligned}\n", "" ] }, { "cell_type": "markdown", "id": "2ca41ccc", "metadata": {}, "source": [ "## Exercise 35.2\n", "\n", "Give a formula for the regression coefficient $\\beta_{i, R^m}$." ] }, { "cell_type": "markdown", "id": "76bf1b07", "metadata": {}, "source": [ "## Solution to[ Exercise 35.2](https://python-advanced.quantecon.org/#apl_ex2)\n", "\n", "The regression coefficient $\\beta_{i, R^m}$ is\n", "\n", "$$\n", "\\beta_{i,R^{m}}=\\frac{Cov\\left(R_{t}^{i}-R^{f},R_{t}^{m}-R^{f}\\right)}{Var\\left(R_{t}^{m}-R^{f}\\right)}\n", "$$" ] }, { "cell_type": "markdown", "id": "eca3061b", "metadata": {}, "source": [ "## Exercise 35.3\n", "\n", "As in many sciences, it is useful to distinguish a **direct problem** from an **inverse problem**.\n", "\n", "- A direct problem involves simulating a particular model with known parameter values. \n", "- An inverse problem involves using data to **estimate** or **choose** a particular parameter vector from a manifold of models indexed by a set of parameter vectors. \n", "\n", "\n", "Please assume the parameter values provided below and then simulate 2000 observations from the theory specified\n", "above for 5 assets, $i = 1, \\ldots, 5$.\n", "\n", "\n", "\\begin{align*}\n", "E\\left[R^f\\right] &= 0.02 \\\\\n", "\\sigma_f &= 0.00 \\\\\n", "\\xi &= 0.06 \\\\\n", "\\lambda &= 0.04 \\\\\n", "\\beta_{1, R^m} &= 0.2 \\\\\n", "\\sigma_1 &= 0.04 \\\\\n", "\\beta_{2, R^m} &= .4 \\\\\n", "\\sigma_2 &= 0.04 \\\\\n", "\\beta_{3, R^m} &= .6 \\\\\n", "\\sigma_3 &= 0.04 \\\\\n", "\\beta_{4, R^m} &= .8 \\\\\n", "\\sigma_4 &= 0.04 \\\\\n", "\\beta_{5, R^m} &= 1.0 \\\\\n", "\\sigma_5 &= 0.04\n", "\\end{align*}\n", "\n", "\n", "**More Exercises**\n", "\n", "Now come some even more fun parts!\n", "\n", "Our theory implies that there exist values of two scalars, $a$ and $b$, such that a legitimate stochastic discount factor is:\n", "\n", "$$\n", "m_t = a + b R^m_t\n", "$$\n", "\n", "The parameters $a, b$ must satisfy the following equations:\n", "\n", "\n", "\\begin{align*}\n", "E[(a + b R_t^m) R^m_t)] &= 1 \\\\\n", "E[(a + b R_t^m) R^f_t)] &= 1\n", "\\end{align*}\n", "" ] }, { "cell_type": "markdown", "id": "a7b32343", "metadata": {}, "source": [ "## Solution to[ Exercise 35.3](https://python-advanced.quantecon.org/#apl_ex3)\n", "\n", "**Direct Problem:**" ] }, { "cell_type": "code", "execution_count": null, "id": "37204bf6", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# Code for the direct problem\n", "\n", "# assign the parameter values\n", "ERf = 0.02\n", "σf = 0.00 # Zejin: Hi tom, here is where you manipulate σf\n", "ξ = 0.06\n", "λ = 0.08\n", "βi = np.array([0.2, .4, .6, .8, 1.0])\n", "σi = np.array([0.04, 0.04, 0.04, 0.04, 0.04])" ] }, { "cell_type": "code", "execution_count": null, "id": "ccffe3a9", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# in this cell we set the number of assets and number of observations\n", "# we first set T to a large number to verify our computation results\n", "T = 2000\n", "N = 5" ] }, { "cell_type": "code", "execution_count": null, "id": "becb266c", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# simulate i.i.d. random shocks\n", "e = np.random.normal(size=T)\n", "u = np.random.normal(size=T)\n", "ϵ = np.random.normal(size=(N, T))" ] }, { "cell_type": "code", "execution_count": null, "id": "1bcfc012", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# simulate the return on a risk-free asset\n", "Rf = ERf + σf * e\n", "\n", "# simulate the return on the market portfolio\n", "excess_Rm = ξ + λ * u\n", "Rm = Rf + excess_Rm\n", "\n", "# simulate the return on asset i\n", "Ri = np.empty((N, T))\n", "for i in range(N):\n", " Ri[i, :] = Rf + βi[i] * excess_Rm + σi[i] * ϵ[i, :]" ] }, { "cell_type": "markdown", "id": "5997308c", "metadata": {}, "source": [ "Now that we have a panel of data, we’d like to solve the inverse problem by assuming the theory specified above and estimating the coefficients given above." ] }, { "cell_type": "code", "execution_count": null, "id": "2d43d1fe", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# Code for the inverse problem" ] }, { "cell_type": "markdown", "id": "fbc6f005", "metadata": {}, "source": [ "**Inverse Problem:**\n", "\n", "We will solve the inverse problem by simple OLS regressions.\n", "\n", "1. estimate $E\\left[R^f\\right]$ and $\\sigma_f$ " ] }, { "cell_type": "code", "execution_count": null, "id": "515c96e5", "metadata": { "hide-output": false }, "outputs": [], "source": [ "ERf_hat, σf_hat = simple_ols(np.ones(T), Rf)" ] }, { "cell_type": "code", "execution_count": null, "id": "8ef7edc8", "metadata": { "hide-output": false }, "outputs": [], "source": [ "ERf_hat, σf_hat" ] }, { "cell_type": "markdown", "id": "87a71480", "metadata": {}, "source": [ "Let’s compare these with the *true* population parameter values." ] }, { "cell_type": "code", "execution_count": null, "id": "acb156c6", "metadata": { "hide-output": false }, "outputs": [], "source": [ "ERf, σf" ] }, { "cell_type": "markdown", "id": "7d181c40", "metadata": {}, "source": [ "1. $\\xi$ and $\\lambda$ " ] }, { "cell_type": "code", "execution_count": null, "id": "48d52c50", "metadata": { "hide-output": false }, "outputs": [], "source": [ "ξ_hat, λ_hat = simple_ols(np.ones(T), Rm - Rf)" ] }, { "cell_type": "code", "execution_count": null, "id": "e3185adb", "metadata": { "hide-output": false }, "outputs": [], "source": [ "ξ_hat, λ_hat" ] }, { "cell_type": "code", "execution_count": null, "id": "392c3817", "metadata": { "hide-output": false }, "outputs": [], "source": [ "ξ, λ" ] }, { "cell_type": "markdown", "id": "5dd826bf", "metadata": {}, "source": [ "1. $\\beta_{i, R^m}$ and $\\sigma_i$ " ] }, { "cell_type": "code", "execution_count": null, "id": "75fef47b", "metadata": { "hide-output": false }, "outputs": [], "source": [ "βi_hat = np.empty(N)\n", "σi_hat = np.empty(N)\n", "\n", "for i in range(N):\n", " βi_hat[i], σi_hat[i] = simple_ols(Rm - Rf, Ri[i, :] - Rf)" ] }, { "cell_type": "code", "execution_count": null, "id": "442bdb36", "metadata": { "hide-output": false }, "outputs": [], "source": [ "βi_hat, σi_hat" ] }, { "cell_type": "code", "execution_count": null, "id": "998fa8c7", "metadata": { "hide-output": false }, "outputs": [], "source": [ "βi, σi" ] }, { "cell_type": "markdown", "id": "7ff8c9a5", "metadata": {}, "source": [ "Q: How close did your estimates come to the parameters we specified?" ] }, { "cell_type": "markdown", "id": "b7955a4b", "metadata": {}, "source": [ "## Exercise 35.4\n", "\n", "Using the equations above, find a system of two **linear** equations that you can solve for $a$ and $b$ as functions of the parameters $(\\lambda, \\xi, E[R_f])$.\n", "\n", "Write a function that can solve these equations.\n", "\n", "Please check the **condition number** of a key matrix that must be inverted to determine a, b" ] }, { "cell_type": "markdown", "id": "b5663790", "metadata": {}, "source": [ "## Solution to[ Exercise 35.4](https://python-advanced.quantecon.org/#apl_ex4)\n", "\n", "The system of two linear equations is shown below:\n", "\n", "\n", "\\begin{aligned}\n", "a ((E(R^f) + \\xi) + b ((E(R^f) + \\xi)^2 + \\lambda^2 + \\sigma_f^2) & =1 \\cr\n", "a E(R^f) + b (E(R^f)^2 + \\xi E(R^f) + \\sigma_f ^ 2) & = 1 \n", "\\end{aligned}\n", "" ] }, { "cell_type": "code", "execution_count": null, "id": "1f45c4f0", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# Code here\n", "def solve_ab(ERf, σf, λ, ξ):\n", "\n", " M = np.empty((2, 2))\n", " M[0, 0] = ERf + ξ\n", " M[0, 1] = (ERf + ξ) ** 2 + λ ** 2 + σf ** 2\n", " M[1, 0] = ERf\n", " M[1, 1] = ERf ** 2 + ξ * ERf + σf ** 2\n", "\n", " a, b = np.linalg.solve(M, np.ones(2))\n", " condM = np.linalg.cond(M)\n", "\n", " return a, b, condM" ] }, { "cell_type": "markdown", "id": "b98704be", "metadata": {}, "source": [ "Let’s try to solve $a$ and $b$ using the actual model parameters." ] }, { "cell_type": "code", "execution_count": null, "id": "7bb0b957", "metadata": { "hide-output": false }, "outputs": [], "source": [ "a, b, condM = solve_ab(ERf, σf, λ, ξ)" ] }, { "cell_type": "code", "execution_count": null, "id": "aa1f1f49", "metadata": { "hide-output": false }, "outputs": [], "source": [ "a, b, condM" ] }, { "cell_type": "markdown", "id": "a20c7e0f", "metadata": {}, "source": [ "## Exercise 35.5\n", "\n", "Using the estimates of the parameters that you generated above, compute the implied stochastic discount factor." ] }, { "cell_type": "markdown", "id": "0c251062", "metadata": {}, "source": [ "## Solution to[ Exercise 35.5](https://python-advanced.quantecon.org/#apl_ex5)\n", "\n", "Now let’s pass $\\hat{E}(R^f), \\hat{\\sigma}^f, \\hat{\\lambda}, \\hat{\\xi}$ to the function solve_ab." ] }, { "cell_type": "code", "execution_count": null, "id": "add98a33", "metadata": { "hide-output": false }, "outputs": [], "source": [ "a_hat, b_hat, M_hat = solve_ab(ERf_hat, σf_hat, λ_hat, ξ_hat)" ] }, { "cell_type": "code", "execution_count": null, "id": "f39400e7", "metadata": { "hide-output": false }, "outputs": [], "source": [ "a_hat, b_hat, M_hat" ] } ], "metadata": { "date": 1686803694.2112303, "filename": "asset_pricing_lph.md", "kernelspec": { "display_name": "Python", "language": "python3", "name": "python3" }, "title": "Elementary Asset Pricing Theory" }, "nbformat": 4, "nbformat_minor": 5 }