Real Estate: Is It Time to Unload? Hands-On Market Analysis with Python
Introduction
Indicators are pointing to a bubble once again. Let's roll up our sleeves and find out what is going on.
Code
from IPython.display import Image
Image(filename='viralml-book.png')
Fundamental and Technical Indicators - Hands-On Market Analysis¶
Companion book: "The Little Book of Fundamental Market Indicators":
More at:
Data¶
S&P 500 (^GSPC) https://finance.yahoo.com/quote/%5EGSPC/history?p=%5EGSPC
S&P/Case-Shiller U.S. National Home Price Index (CSUSHPINSA) https://fred.stlouisfed.org/series/CSUSHPINSA
Average Hourly Earnings of Production and Nonsupervisory Employees: Total Private https://fred.stlouisfed.org/series/AHETPI
Consumer Price Index for All Urban Consumers: Owners' equivalent rent of residences https://fred.stlouisfed.org/series/CUSR0000SEHC
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import io, base64, os, json, re
import pandas as pd
import numpy as np
import datetime
import warnings
warnings.filterwarnings('ignore')
path_to_market_data = '/Users/manuel/Documents/financial-research/market-data/2019-07-20/'
# create an MACD indicators
def MACD(df, feature, fast=9, medium=12, long=26):
# WARNING - Feed data in ascending order only (i.e. first row should be your oldest print)
tmp_df = df.copy()
tmp_df['EXP1'] = tmp_df[feature].ewm(span=medium, adjust=False).mean()
tmp_df['EXP2'] = tmp_df[feature].ewm(span=long, adjust=False).mean()
tmp_df['MACD'] = tmp_df['EXP1']-tmp_df['EXP2']
tmp_df['EXP3'] = tmp_df['MACD'].ewm(span=fast, adjust=False).mean()
tmp_df['MACD_Hist'] = tmp_df['MACD'] - tmp_df['EXP3']
return tmp_df
Data¶
# S&P 500
sp500_df = pd.read_csv(path_to_market_data + '^GSPC.csv')
sp500_df['Date'] = pd.to_datetime(sp500_df['Date'])
sp500_df = sp500_df[['Date','Adj Close']]
sp500_df.columns = ['Date', 'SP500_Close']
print(np.min(sp500_df['Date'] ),np.max(sp500_df['Date'] ))
sp500_df = sp500_df.sort_values('Date', ascending=True) # sort in ascending date order
sp500_df.tail()
# Case-Shiller
caseshill_df = pd.read_csv(path_to_market_data + 'CSUSHPINSA.csv')
caseshill_df['DATE'] = pd.to_datetime(caseshill_df['DATE'])
caseshill_df.columns = ['Date', 'Case-Shiller']
caseshill_df = caseshill_df.sort_values('Date')
print('caseshill_df:', np.min(caseshill_df['Date']), np.max(caseshill_df['Date']))
caseshill_df.tail()
# Average Hourly Earnings of Production and Nonsupervisory Employees
avghourly_df = pd.read_csv(path_to_market_data + 'AHETPI.csv')
avghourly_df['DATE'] = pd.to_datetime(avghourly_df['DATE'])
avghourly_df.columns = ['Date', 'AHETPI']
avghourly_df = avghourly_df.sort_values('Date')
print('avghourly_df:', np.min(avghourly_df['Date']), np.max(avghourly_df['Date']))
avghourly_df.tail()
# Consumer Price Index for All Urban Consumers
cpi_df = pd.read_csv(path_to_market_data + 'CUSR0000SEHC.csv')
cpi_df['DATE'] = pd.to_datetime(cpi_df['DATE'])
cpi_df.columns = ['Date', 'CPI']
cpi_df = cpi_df.sort_values('Date')
print('cpi_df:', np.min(cpi_df['Date']), np.max(cpi_df['Date']))
cpi_df.tail()
Let's Plot it All¶
cut_off_date = '1988-01-01'
sp500_df_tmp = sp500_df.copy()
caseshill_df_tmp = caseshill_df.copy()
avghourly_df_tmp = avghourly_df.copy()
cpi_df_tmp = cpi_df.copy()
sp500_df_tmp = sp500_df_tmp[sp500_df_tmp['Date'] >= cut_off_date]
caseshill_df_tmp = caseshill_df_tmp[caseshill_df_tmp['Date'] >= cut_off_date]
avghourly_df_tmp = avghourly_df_tmp[avghourly_df_tmp['Date'] >= cut_off_date]
cpi_df_tmp = cpi_df_tmp[cpi_df_tmp['Date'] >= cut_off_date]
# join both datasets together
fig, ax = plt.subplots(figsize=(16, 8))
plt.plot(sp500_df_tmp['Date'], sp500_df_tmp['SP500_Close'] , color='blue', label='SP500_Close')
plt.title('SP500, Case-Shiller, AHETPI, CPI')
plt.grid()
# Get new axis
ax2 = ax.twinx()
plt.plot(caseshill_df_tmp['Date'], caseshill_df_tmp['Case-Shiller'] , color='red', label='Case-Shiller')
# Get new axis
ax3 = ax.twinx()
plt.plot(avghourly_df_tmp['Date'], avghourly_df_tmp['AHETPI'] , color='green', label='AHETPI')
# Get new axis
ax4 = ax.twinx()
plt.plot(cpi_df_tmp['Date'], cpi_df_tmp['CPI'] , color='brown', label='CPI')
plt.show()
Adjustting for 2012 = 100¶
sp500_df_tmp[sp500_df_tmp['Date'] == '2012-01-03']
print(100/1277.060059)
sp500_df_tmp['SP500_Close-adj'] = sp500_df_tmp['SP500_Close'] * 0.07830485284952445
caseshill_df_tmp[caseshill_df_tmp['Date'] == '2012-01-01']
print(100/134.164)
caseshill_df_tmp['Case-Shiller-adj'] = caseshill_df_tmp['Case-Shiller'] * 0.7453564294445605
avghourly_df[avghourly_df['Date'] == '2012-01-01']
print(100/19.58)
avghourly_df_tmp['AHETPI-adj'] = avghourly_df_tmp['AHETPI'] * 5.107252298263535
cpi_df[cpi_df['Date'] == '2012-01-01']
print(100/262.366)
cpi_df_tmp['CPI-adj'] = cpi_df_tmp['CPI'] * 0.3811469473940983
# join both datasets together
fig, ax = plt.subplots(figsize=(16, 8))
plt.plot(sp500_df_tmp['Date'], sp500_df_tmp['SP500_Close-adj'] , color='blue', label='SP500_Close')
plt.title('SP500, Case-Shiller, AHETPI, CPI - Ajusted to 2012=100')
plt.plot(caseshill_df_tmp['Date'], caseshill_df_tmp['Case-Shiller-adj'] , color='red', label='Case-Shiller')
plt.plot(avghourly_df_tmp['Date'], avghourly_df_tmp['AHETPI-adj'] , color='green', label='AHETPI')
plt.plot(cpi_df_tmp['Date'], cpi_df_tmp['CPI-adj'] , color='brown', label='CPI')
plt.grid()
plt.show()
# VNQ
vnq_df = pd.read_csv(path_to_market_data + 'VNQ.csv')
vnq_df['Date'] = pd.to_datetime(vnq_df['Date'])
vnq_df = vnq_df[['Date','Adj Close']]
vnq_df.columns = ['Date', 'VNQ_Close']
print(np.min(vnq_df['Date'] ),np.max(vnq_df['Date'] ))
vnq_df = vnq_df.sort_values('Date', ascending=True) # sort in ascending date order
vnq_df.tail()
vnq_df[vnq_df['Date'] == '2012-01-03']
print(100/42.986839)
vnq_df['VNQ_Close-adj'] = vnq_df['VNQ_Close'] * 2.326293403429826
# join both datasets together
fig, ax = plt.subplots(figsize=(16, 8))
plt.plot(vnq_df['Date'], vnq_df['VNQ_Close-adj'] , color='blue', label='VNQ_Close-adj')
plt.title('SP500, Case-Shiller, AHETPI, CPI - Ajusted to 2012=100')
plt.plot(caseshill_df_tmp['Date'], caseshill_df_tmp['Case-Shiller-adj'] , color='red', label='Case-Shiller')
plt.plot(avghourly_df_tmp['Date'], avghourly_df_tmp['AHETPI-adj'] , color='green', label='AHETPI')
plt.plot(cpi_df_tmp['Date'], cpi_df_tmp['CPI-adj'] , color='brown', label='CPI')
plt.grid()
plt.show()
Show Notes
(pardon typos and formatting -these are the notes I use to make the videos)
Indicators are pointing to a bubble once again. Let's roll up our sleeves and find out what is going on.