Outline#

1. Subcategories of Dynamic Asset Allocation#

DAA: Subcategories

2. The Basic ‘’Contrarian’’ TAA Principle as Applied to TAA#

  • Mean reversion in stock prices (negative return correlation)

3. TAA Models#

  • The General Methodology of Estimating the Equity Risk Premium (ERP)

  • Fama, French (FF) Predictive Model

  • Chen Predictive Model

4. Practical TAA Measures#

  • How to Estimate ERP directly

  • A Simple TAA Implementation

5. Summary#

  • The ERP is hard to predict

  • The ERP is related to the business cycle

Warm up#

Before we start, let’s first install the dependencies and import the libraries we need.

Please run the setup cell bellow to be able to run this notebook on your browser.

# Setup environment
from config import *

1. TAA: Definitions of SAA, TAA and IAA#

TAA: William Sharpe’s characterization of SAA, TAA and IAA#

After a market move:

For TAA: Go back to point A

Adjust expectations about asset returns.

For SAA: Rebalance to SAA weights in point B

Adjust portfolio weights.

For IAA: Go back to point C

Update preferences (e.g., risk tolerance) as a result of change in wealth.

Assume two possible investments:

  • Bonds with \(E[r_{B}]\) and \(\sigma_{B}\)

  • Stocks with \(E[r_{S}]\) and \(\sigma_{S}\)

  • Covariance between bonds and stock: \(\sigma_{BS}\)

The investor chooses \(X_{st}\) as the proportion invested in stock at date \(t\), with \(1-X_{st}\) invested in bonds, to maximize the investor’s expected utility, with a relative risk tolerance (\(RRT[W_{t}]\)), which depends upon the investor’s wealth, \(W_{t}\) at date \(t\).

\(RRT[W_{t}]\) increases with \(W_{t}\): as wealth goes up, an investor gets more aggressive, i.e., is willing to take more risk.

The portfolio choice problem for the investor:

\[\max_{X_{st}} E[R_{t}] - \frac{1}{2RRT[W_{t}]} V[R_{t}], \]

where

\[E[R_{t}] = X_{st} \cdot E[r_{S}] + (1-X_{st}) \cdot E[r_{B}], \]

and

\[V[R_{t}] = X_{st}^{2}\sigma_{S}^{2} + (1-X_{st})^{2}\sigma_{B}^{2} + 2X_{st}(1-X_{st})\sigma_{BS}.\]

Take first order condition on \(X_{st}\):

\[E[r_{S}] - E[r_{B}] -\frac{1}{2RRT[W_{t}]}\Big(2X_{st}\sigma_{S}^{2} + 2(1-X_{st})\sigma_{B}^{2} - 4X_{st}(1-X_{st})\sigma_{BS} + 2\sigma_{BS} - 2\sigma_{B}^{2}\Big) = 0\]

The solution takes the following form:

\[X_{st}=K_{0}+K_{1t} \cdot RRT[W_{t}], \]

where \(K_{0}\) and \(K_{1t}\) are constants given by

\[K_{0}=\frac{\sigma_{B}^2-\sigma_{BS}}{\sigma_{B}^2+\sigma_{S}^2-2\sigma_{BS}}\]
\[K_{1t}=\frac{E_{t} [r_{S}]-E[r_{B}]}{\sigma_{B}^2+\sigma_{S}^2-2\sigma_{BS}}\]

SAA Investing:

\(K_{0}\), \(K_{1t}\) and \(RRT[W_{t}]\) are all taken as constant and unchanging over time under SAA. This assumes:

(i) no changes in risk assessments (\(\sigma_{B},\sigma_{S},\sigma_{BS}\))

(ii) no changes in expected stock returns \(E_{t}[r_{S}]=E[r_{S}]\) is independent of \(t\), i.e., it is a long-run expectation

(iii) no change in \(RRT[W_{t}]\) because SAA assumes the investor doesn’t worry about short-run changes in wealth.

With these three assumptions, SAA is thus assuming that \(X_{st}\) is the same at each date \(t\). The Mean-Variance Efficient Frontier (MVEF) does not move, and the optimal point on that curve (determined by the investor’s \(RRT[W_{t}]\)) does not move.

TAA Investing:

We continue to assume (in all three DAA styles) that there are no changes in risk assessments (\(\sigma_{B},\sigma_{S},\sigma_{BS}\)). BUT, with TAA, the investor alters their \(E_{t}[r_{S}]\) at each date \(t\), as the investor alters the belief about upcoming stock expected returns. For simplicity, we assume \(E[r_{B}]\) does not change. Thus, \(K_{1t}\) changes at each date \(t\) so that \(X_{st}\) changes at each date \(t\). As \(E_{t}[r_{S}]-E[r_{B}]\) increases, so does \(X_{st}\). Because expected returns change, the MVEF changes, but the \(RRT[W_{t}]\) is assumed to stay constant in TAA. So, the TAA investor will change their portfolio weighting each period as their outlook for the stock market changes each period.

IAA Investing:

In IAA investing, \(RRT[W_{t}]\) changes at each date as the investor’s wealth changes: when \(W_{t}\) gets bigger, risk tolerance also increases (\(RRT\) increases) as the investor is more aggressive when she is wealthier. Thus, \(X_{st}\) changes at each date as \(RRT\) changes: higher wealth means a bigger \(RRT\) which means a bigger \(X_{st}\). The MVEF does not move, but the \(RRT\) point on the curve does, so \(X_{st}\) moves.

The following functions calculate K0, K1 and stock weight from assets volatility and returns.

# calculate K0
def K0(sigma_b,sigma_s,corr):
  K0 = (sigma_s*sigma_s - corr*sigma_b*sigma_s)/(sigma_b*sigma_b + sigma_s*sigma_s - 2*corr*sigma_b*sigma_s)
  return K0

# calculate K1
def K1(rb,rs,sigma_b,sigma_s,corr):
  K1 = (rs-rb)/(sigma_b*sigma_b + sigma_s*sigma_s - 2*corr*sigma_b*sigma_s)
  return K1

# calculate stock weight
def stock_weight(rb,rs,sigma_b,sigma_s,corr,RRT):
  denom = sigma_b**2 + sigma_s**2 - 2*corr*sigma_b*sigma_s
  sigma_bs = corr*sigma_b*sigma_s
  K0 = (sigma_b**2 - sigma_bs)/denom
  K1 = (rs - rb)/denom
  return K0+RRT*K1
# Example
rb = 0.03
rs = 0.05
sigma_b = 0.2
sigma_s = 0.30
corr = 0.1
RRT = 1/3

print("K0 is:", np.round(K0(sigma_b,sigma_s,corr),3))
print("K1 is:", np.round(K1(rb,rs,sigma_b,sigma_s,corr),3))

print(r"The stock weight X[st] chosen by the investor is:", np.round(stock_weight(rb, rs, sigma_b, sigma_s, corr, RRT), 3))
K0 is: 0.712
K1 is: 0.169
The stock weight X[st] chosen by the investor is: 0.345

Suppose that the investor becomes more risk tolerant as his/her wealth increases. What happens to the portfolio weight in stocks, \(X_{st}\)?

TAA: Mean Reversion in the Stock Index Price Level (Negative Serial Correlation in Stock Index Returns)#

The basic hypothesis of contrarian TAA investing is that the stock index price level fluctuates around its long-term trend line, overshooting too high, reverting back, and then overshooting too low and reverting back, etc. The graph on the next page (mean-reverting stock index) illustrates this viewpoint.

  • When the index is too low:

\(E[r_{S}]\) is greater than the long-term trend line. The simple theory: investors are poor (the stock index is low, so stock wealth is small) and so they demand a higher \(E[r_{S}]\) before being willing to invest in risky stocks.

  • When the index is too high:

\(E[r_{s}]\) is less than the long-term trend line (although it should never be less than the riskless rate). The simple theory: investors are rich (the stock index is high, so stock market wealth is large) and so they are willing, even at a low \(E[r_{S}]\), to invest in risky stocks.

In this contrarian TAA model, the stock index price level reverts back to its long-run trend line when it deviates too far from that trend line.

TAA: A Mean-Reverting Stock Index#

Assume investors perceive the stock index behaving as shown below. We see it mean-reverting around a growth trend. At times of a high stock index level, investors are rich and they are willing to accept a lower expected return to bear the risk of the stock market. At a low stock index level, investors are poor and demand a high expected growth rate in order for them to bear risk.

TAA: A Mean-Reverting Stock Index

Thus, as investors’ attitude towards bearing risk changes, the “market price of risk / risk premium” (\(\lambda\) in the CAPM) changes. \(\lambda\) is positively related to the expected return on the stock market, \(E[r_{S}]\).

  • When price gets too high, it reverts back to the long-term trend, but usually over-shoots and goes too low.

  • When price is low, \(E[r_{S}]\) is high, and vice-versa.

A contrarian investor may take market risk as constant. Then as expected market return varies (low price means high \(E[r_{S}]\) and high price means low \(E[r_{S}]\), the reward-to-risk ratio of investing in the market varies. The contrarian investor invests when price is low, so the reward-to-risk ratio is high.

2. TAA: The General TAA Methodology#

Determining \(𝑬_{𝒕}[𝒓_{𝑺}]\)#

The TAA manager must identify predictor variables, which are economic (or behavioral) variables that can be observed at regular intervals (e.g., monthly) that the manager believes predict future asset returns. That is:

Predictor variables forecast \(E_{t} [r_{S}]\) (and/or other asset class expectations). The TAA process has two steps:

TAA Step 1. Find predictor variables and determine their relationship to \(E_{t} [r_{S}]\)

Finding predictor variables that are correlated with future stock returns is usually done with regression analysis, by regressing stock returns on predictor variables that are observable before the stock return occurs:

\[r_{sq} = a + b_{1}PV_{1q} + b_{2}PV_{2q} + e\]

Where:

  • \(PV_{1q}\) and \(PV_{2q}\) are the observations of the predictor variables at the start of quarter \(q\)

  • \(r_{sq}\) is the stock index return over quarter \(q\)

When a relationship is found, stock returns are predicted from the regression model:

\[E[r_{sq}] = a' + b_{1}'PV_{1q} + b_{2}'PV_{2q}\]

Where:

  • \(E[r_{sq}]\) is the prediction made for the upcoming quarter \(q\)

  • \(a'\), \(b_{1}'\) and \(b_{2}'\) are the coefficients from the regression above based on historical data

  • \(PV_{1q}\) and \(PV_{2q}\) are the current (at the start of quarter \(q\)) observations of the predictor variables

TAA Step 2. Convert the \(E_{t}[r_{S}]\) estimate to a stock/bond allocation in your TAA portfolio

Once the stock return is estimated, it must be converted to a TAA allocation (i.e., how much in stock and how much in other asset classes?). This is achieved by mean-variance analysis.

3. TAA: The Fama-French (FF) Predictive Model#

#

In this section, we report the original analysis from Fama-French predictive model and then followed with python code to reproduce the results.

We think of TAA as arising because the TAA investor believes in a time-varying equity risk premium (ERP). For example, in the CAPM, we say the “market price of risk” (\(𝐸RP =𝐸[𝑟_{𝑚}]−𝑟_{𝑓})\) is a constant. But, in TAA, we assume that the compensation investors want for bearing stock market risk (this is the “market price of risk”) varies through time.

FF describe a consumption smoothing story about a time-varying equity risk premium (ERP).

  • At an economic peak, investors’ income is higher than their desired consumption, so all investors seek investments: this drives prices of risky assets up and expected returns down.

  • At an economic trough, investors’ income is less than their desired consumption, so they must liquidate their investments to consume; this drives prices of risky assets down and expected returns up. This links expected returns (like the ERP) to the economic cycle: high expected returns at economic troughs and low expected returns at economic peaks.

Most simply: ERP varies inversely with price: low price <=> high ERP (and vice-versa).

FF use three predictor variables:

  • DP = dividend yield on all NYSE stocks = Dividend/Price

Since dividends on all stocks are fairly constant, DP is inversely related to the index price level. So, low prices => high DP => high expected returns.

  • DEF = AllLTYld - AaaLTYld

The yield on a portfolio of 100 (government (riskless) and corporate (risky)) long-term maturity bonds - the yield on a portfolio of long-term low-risk (Aaa rated) bonds.

Since there is default risk in the AllLTYld but none in the AaaLTYld, DEF is the default (or credit) spread. Low prices for risky bonds means high risky bond yields, which means a high DEF. But, low junk bond prices mean high expected returns on junk bonds (and, it is hypothesized, on stock returns as well).

So, high DEF => high expected returns.

  • TERM = AaaLTYld - TBillYld

The yield on a long-term riskless bond portfolio minus the yield on a short-term riskless bond portfolio.

This is called the “term spread” and represents the slope of the yield curve. Empirically, a steep yield curve (a high TERM) occurs at economic troughs; expected returns are higher at economic troughs. And, at economic peaks, the yield curve is flat or sometimes even inverted; economic peaks feature low expected returns.

Thus, high TERM => high expected returns.

An important aspect of the FF study is that they investigate if the predictor model predicts subsequent (a) monthly returns, or (b) quarterly returns or (c) annual returns or (d) 4-year returns. This helps us confirm whether the contrarian TAA hypothesis of long-term mean reversion in stock index returns applies.

FF look at predicting the returns on 4 asset classes:

  • Aaa = long-term riskless bonds

  • LG = long-term, low-grade, i.e., risky bonds

  • VW = a value-weighted stock portfolio, i.e., a big-cap stock portfolio

  • EW = an equally-weighted stock portfolio, i.e., a small-cap stock portfolio.

Thus, FF investigates if the three predictor variables, DP, DEF and TERM, have any predictive power in forecasting the future returns on 4 asset classes: Aaa, LG, VW and EW. These four asset classes have very different return profiles, so we would expect different levels of predictive acuracies among the predictor variables.

TAA: Fama-French Results#

Now we load historical data and take a look at patterns of FF risk factors. First we load packages that we need for our analysis.

Here we load data. The data includes Fama-French risk factors, factors for Chen predictive models, and asset returns

riskfactors = pd.read_csv('riskfactors_V2.csv', index_col='date', parse_dates=True)

We now take a look at the data structure.

riskfactors.head(2)
dp term def ypl tb30 CRSP_SPvwx realgnpg mktrf Rfree AAA BAA vwretx ewretx corpr
date
1941-02-28 6.821573 2.74 4.636888 NaN 0.0004 -0.012570 NaN -0.013640 -0.0001 0.0278 0.0442 -0.038958 -0.013340 0.0006
1941-03-31 6.827309 2.69 4.474293 NaN 0.0011 0.004173 NaN 0.003978 0.0001 0.0280 0.0438 -0.013024 -0.027249 -0.0022
###########################################
###An overview of variables in the dataset
###########################################

# dp: Dividend price ratio on NYSE stock index (source: Goyal's website)
# def: default yield spread: yield of BAA - AAA bond yield (source: Goyal's website)
# term: term spread: AAA yield - 30day treasury bill (source: Goyal's website & Fama-Frenc(1989))
# ypl: annual growth in industrial production (source: FRED)
# tb30: 30day treasury bill yield (source: Goyal's website)
# CRSP_SPvwx: SP500 value weighted index return (source: Goyal's website)
# realgnpg: quarterly real GNP growth (source: FRED)
# mktrf: market premium (source: Goyal's website)
# Rfree: risk free rate (source: Goyal's website)
# AAA: AAA bond yield (source: Goyal's website)
# BBB: BBB bond yield (source: Goyal's website)
# vwretx: value weighted return of all stocks (source: WRDS)
# ewretx: equal weighted return of all stocks (source: WRDS)
# corpr: corporate bond returns (source: Goyal's website)

# Goyal's website: https://sites.google.com/view/agoyal145/?redirpath=/

list(riskfactors)
['dp',
 'term',
 'def',
 'ypl',
 'tb30',
 'CRSP_SPvwx',
 'realgnpg',
 'mktrf',
 'Rfree',
 'AAA',
 'BAA',
 'vwretx',
 'ewretx',
 'corpr']

As a sanity check, let’s take a look at the dividend-price ratio over time.

# Check how the dp ratio looks like over time
plt.figure(figsize=(10, 6))   
plt.plot(riskfactors['dp'], color='black', linewidth=1.5)  

plt.title('Dividend Price Ratio Over Time', fontsize=14, fontweight='bold')   
plt.xlabel('Time', fontsize=12)   
plt.ylabel('DP Ratio', fontsize=12)   

plt.grid(False)   
plt.minorticks_on()  

# Remove the top and right spines to reduce visual clutter
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)

# Adjust tick parameters for a cleaner look
plt.tick_params(axis='both', which='both', bottom=True, top=False, left=True, right=False, labelsize=10)

plt.tight_layout()  # Adjust the layout to make sure everything fits without overlap
plt.show()  # Display the plot
_images/835661d5eb0b819205f8fefb01fd21ea957da54007077b13506ef71d8088cef0.png

We plot the FF risk factors to take a look at their distribution.

# Plot DP
fig, ax = plt.subplots()
ax.plot(riskfactors.index, riskfactors.dp, 'b-', linewidth=2, label='DP', alpha=0.6)
ax.legend()
ax.set_title("Dividend-price ratio", fontsize=14)
ax.set_xlabel("Date", fontsize=12)
ax.set_ylabel("DP", fontsize=12)
ax.grid(False)
# Format the dates on x-axis
ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
# Reference line at y=1
ax.axhline(y=1, color='black', linewidth=1)
# Plot a maximum of 10 ticks on the x-axis
ax.xaxis.set_major_locator(mdates.YearLocator(10))
plt.show()
_images/df66ab3af50017c3aae90e020e9aa761f7d90875300f043b4b5192410665a485.png
# Plot DEF
fig, ax = plt.subplots()
ax.plot(riskfactors.index, riskfactors['def'], 'g-', linewidth=2, label='DEF', alpha=0.6)
ax.legend()
ax.set_title("Default Spread", fontsize=14)
ax.set_xlabel("Date", fontsize=12)
ax.set_ylabel("DEF", fontsize=12)
ax.grid(False)
# Format the dates on x-axis
ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
# Reference line at y=0
ax.axhline(0, color='black', linewidth=1)
# Plot a maximum of 10 ticks on the x-axis
ax.xaxis.set_major_locator(mdates.YearLocator(10))
plt.show()
_images/32a0dbbd3bcd8005ce22ee3ab77392e3a10c9ca13c17bcdab74b5b3c96d13ece.png
# Plot TERM
fig, ax = plt.subplots()
ax.plot(riskfactors.index, riskfactors['term'], 'r-', linewidth=2, label='TERM', alpha=0.6)
ax.legend()
ax.set_title("Term Spread", fontsize=14)
ax.set_xlabel("Date", fontsize=12)
ax.set_ylabel("TERM", fontsize=12)
ax.grid(False)
# Format the dates on x-axis
ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
# Reference line at y=0
ax.axhline(0, color='black', lw=1)
# Plot a maximum of 10 ticks on the x-axis
ax.xaxis.set_major_locator(mdates.YearLocator(10))
plt.show()
_images/0b862f82c4f2e1609028f603e8cf6b61bf4175b58557fa3702663739e51a3f14.png

Now we use the data to understand the Fama French multi-risk factor results and asset return prediction.

Fama-French Paper Result 1#

DP and DEF are persistent, TERM is not.

  • Both DP and DEF are autocorrelated with lags. This means that \(\text{Corr}(DP_t, DP_{t+1}) > 0 \), but so is \( \text{Corr}(DP_t, DP_{t+2}) > 0 \), and so is \( \text{Corr}(DP_t, DP_{t+3}) > 0 \), etc., out to 8 annual lags.

  • Same with DEF. This means that when DP or DEF are above/below their means, they tend to stay there for quite a while.

  • TERM has positive autocorrelation, but only out to 2 annual lags.

  • Another interpretation: DP and DEF have long frequencies, TERM has a short frequency.