Composite Macro ETF Weekly Analytics (8/30/2015)

COMPOSITE ETF CUMULATIVE RETURN MOMENTUM

These charts show the sum (cumulative) of the daily returns of each composite ETF over the specified period. The daily return is calculated as the log of the percent change between daily adjusted close prices.

These charts help determine asset class return momentum. This is important because momentum is arguably the strongest and most persistent market anomaly. Poorly performing asset classes are likely to continue under performing while outperforming asset classes are likely to continue their relative strength. 

last 63 trading days

Source: Yahoo Finance

last 21 trading days

Source: Yahoo Finance

last 10 trading days

Source: Yahoo Finance

last 5 trading days

Source: Yahoo Finance

COMPOSITE ETF CUMULATIVE RETURN (BEST VS WORST VS BENCHMARK)

These charts visualize the cumulative return performance of the best and worst performing asset classes over the specified period. These best and worst asset classes are then compared to a benchmark ETF composite represented by the Large Cap category. 

These charts help give investors an idea of how an actual investment in the represented asset classes would have performed over the period in percentage terms. This also helps visualize the relative strength or weakness of various asset classes as compared to the most common Large Cap benchmarks.

LAST 63 TRADING DAYS

Source: Yahoo Finance

last 21 trading days

Source: Yahoo Finance

last 10 trading days

Source: Yahoo Finance

COMPOSITE ETF Z-SCORES OF AVERAGE rolling RISK ADJUSTED RETURNS

These charts show the z-scored average of the composite ETF's rolling risk adjusted returns.  Risk adjusted returns are used to improve the robustness of the chart and the information presented. 

By examining the standardized values we can see how each asset class performed relative to the group. This adds further clarity to the relative strength (weakness) of asset class return performance. 

last 63 trading days; rolling period = 10 days

Source: Yahoo Finance

last 21 trading days; rolling Period = 5 days

Source: Yahoo Finance

last 10 trading days; rolling period = 5 days

Source: Yahoo Finance

COMPOSITE ETF Risk-adjusted return correlations heatmap clusterplots

These charts visualize the correlations of the asset class returns over the specified period. Red indicates highly correlated returns while blue indicates negatively correlated returns. 

By examining a clustered heatmap investors are able to quickly determine the intensity and grouping of asset return correlations. Generally speaking, investors should seek to diversify their portfolios by holding uncorrelated assets. Better diversification among asset classes helps to lower overall portfolio volatility with the implication of improving a portfolio's long term performance. 

last 63 trading days

Source: Yahoo Finance

last 21 trading days

Source: Yahoo Finance

last 10 trading days

Source: Yahoo Finance

Was David Woo Right; Was the Selloff Exacerbated by Risk Parity Strategies?

Today after the close Bloomberg TV had David Woo, Managing Director and Head of Global Rates and Currencies Research at Bank of America/Merrill Lynch, on to provide some insight regarding recent market action. More specifically, he addressed how Chinese and American markets are linked.

He dropped a lot of gems during his segment but one point really struck a chord with me. He said that the recent selloff has likely been exacerbated by "Risk Parity Guys". 

If you're unfamiliar with 'risk parity' here are some good working definitions:

Risk parity (or risk premia parity) is an approach to investment portfolio management which focuses on allocation of risk, usually defined as volatility, rather than allocation of capital.
— https://en.wikipedia.org/wiki/Risk_parity
A portfolio allocation strategy based on targeting risk levels across the various components of an investment portfolio. The risk parity approach to asset allocation allows investors to target specific levels of risk and to divide that risk equally across the entire investment portfolio in order to achieve optimal portfolio diversification for each individual investor.
— http://www.investopedia.com/terms/r/risk-parity.asp

Essentially, this says that risk parity strategies approach portfolio allocation based on the underlying asset's risk/volatility as opposed to traditional portfolio allocation which allocates capital based on holding some specified amount of each asset class. 

David Woo went on to elaborate that traditional asset class correlations began to break down during this selloff, implying that traditional methods of diversification were no longer viable and as a result any fund/fund manager which allocates capital on the basis of 'risk parity' or similar strategies would be forced to reduce risk across all asset classes. 

I thought this was a brilliant insight and immediately wanted to see if I could find some evidence that would support his analysis. 

To do this I used my Composite ETF model to plot rolling correlations of the 'Bonds' ETF composite vs the ETF composite of each asset class. The reason I use rolling correlation is because of the inherent link between asset correlations and volatility. Specifically, as correlations across assets/asset classes rise diversification decreases and volatility/tail risk increases.  I've selected some of the more interesting plots that lend credence to his statement.

bonds vs asia-pac equity

Data Source: Yahoo Finance

bonds vs consumer discretionary

Data Source: Yahoo Finance

bonds vs consumer staples

Data Source: Yahoo Finance

bonds vs europe equity

Data Source: Yahoo Finance

bonds vs financials

Data Source: Yahoo Finance

bonds vs global equity

Data Source: Yahoo Finance

bonds vs industrials

Data Source: Yahoo Finance

bonds vs large cap

Data Source: Yahoo Finance

bonds vs materials

Data Source: Yahoo Finance

bonds vs mid cap

Data Source: Yahoo Finance

bonds vs precious metals

Data Source: Yahoo Finance

bonds vs real estate

Data Source: Yahoo Finance

bonds vs small cap

Data Source: Yahoo Finance

bonds vs telecom

Data Source: Yahoo Finance

After reviewing some of the evidence I would say David Woo is on to something.  To be fair however, rising correlations among this many asset classes over a short time period is likely to cause multiple types of fund strategies to reduce risk exposures quickly. 

If you haven't seen his segment I'd recommend trying to find it. Either way I'll be on the lookout for his analysis going forward. 

COMPOSITE MACRO ETF CUMULATIVE RETURN MOMENTUM (08.23.2015)

Here is the updated list of composite ETF components.


# ================================================================== #
# symbol management

cat = {
       'Large Cap'             :['SPY','IVV','VOO','IWB'],
       'Mid Cap'               :['MDY','IJH','VO','IWR'], 
       'Small Cap'             :['IWM','IJR','VB'],
       'Global Equity'         :['VEU','ACWI','VXUS','DGT'],
       'AsiaPac Equity'        :['EWT','EWY','EWA','EWS','AAXJ','FXI','EWH','EWM','EPI'\
       ,'INDA','RSX'],
       'Europe Equity'         :['FEZ','EZU','VGK','HEDJ','EWU','EWI','EWP','EWQ'\
       ,'EWL','EWD'],
       'Emerging | Frontier'   :['EWZ','EWW','ECH','GAF','FM','EEM','VWO'],
       'Real Estate'           :['RWO','RWX','RWR','IYR','VNQ'],
       'Consumer Discretionary':['XLY','XRT','FXD','VCR','RTH','IYC'],
       'Consumer Staples'      :['XLP','FXG','VDC','ECON','IYK'],           
       'Energy'                :['XLE','IPW','XOP','VDE','IYE','XC','OIH'],  
       
       'Financials'            :['XLF','KBE','KIE','IYG','KRE'],
       'Healthcare'            :['XLV','XBI','IBB'],
       'Industrial'            :['XLI','IYT','VIS','IYJ'],
       'Materials'             :['XLB','XHB','XME','IGE','MOO','GDX','GDXJ'],
       'Technology'            :['XLK','SMH','HACK','FDN'],
       'Telecom'               :['IYZ','IXP','VOX'],                        
       'Utilities'             :['IDU','XLU','VPU'],
       'Oil | Gas'             :['UNG','BNO','OIL'],
       'Precious Metals'       :['GLD','SLV','IAU'],
       'Technology'            :['XLK','SMH','HACK','FDN'],  
       'Bonds'                 :['TLT','AGG','JNK','LQD'],
       'T-Bond Yields'         :['^TYX','^TNX','^FVX']
        }  

LAST 1260 TRADING DAYS (5 YEARS)

Source: Yahoo Finance

LAST 504 TRADING DAYS (2 YEARS)

Source: Yahoo Finance

LAST 252 TRADING DAYS (1 YEAR)

Source: Yahoo Finance

LAST 126 TRADING DAYS (6 MONTHS)

Source: Yahoo Finance

LAST 63 TRADING DAYS (3 MONTHS)

Source: Yahoo Finance

LAST 21 TRADING DAYS (1 MONTH)

Source: Yahoo Finance

LAST 10 TRADING DAYS

Source: Yahoo Finance

Get Free Financial Data w/ Python (State street ETF Holdings - SPY)

One issue I frequently encounter during my research is the need to compare an individual stock, or collection of stocks vs its ETF benchmark. To do this I need accurate ETF holdings data. 

Generally this information is located on the ETF provider's website. However,  this information is often inconvenient to access. Most websites including the ETF provider will do something like the following, where they only show the top 10 holdings, when what we really need is accessible only by clicking the highlighted download link.

SPY ETF Holdings Page

This isn't a major issue until you need to access multiple ETF holdings pages. State Street Global Advisors is the ETF provider and this is the structure they use most frequently, therefore I figured it would be a major time saver to write a script to automate this important yet redundant task. 

This code requires the following third-party modules to execute: 

  • Selenium
  • Google Chromedriver (allows Python to open Chrome browser)

Before we get to the code, you must have Chromedriver downloaded and unzipped. Make sure to grab the filepath as we will need it. 


# ----- import modules -----
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os
import time
from pprint import pprint as pp

Next you will need to grab the correct xpath's from the webpages of interest. I use xpath in this situation because the python script was able to find the correct clickable links every time without issue. 


"""
When you first open the State Street Website you will need to navigate to the 'Holdings' tab and then to the .xls
"""

# ----- webpage xpath -----
holdings_xpath = r"//*[@id='tabs']/a[3]"
xls_xpath = r"//*[@id='FUND_TOP_HOLDINGS']/a"

Next you need to construct a reusable generalized url string which can be used for any of the State Street ETF's. In this example we will be using SPY only.  Additionally I recommend creating a generalized filepath string for the actual downloaded file. This is so we can confirm that the download has completed correctly before exiting the browser in a later step. 


# ----- generalized URL string -----
symbol = 'SPY'
url = r"https://www.spdrs.com/product/fund.seam?ticker={}".format(symbol)
'''
The default naming convention for the holdings file is 'holdings-spy.xls' where the ETF label is lowercase
'''
file_string = my_etf_data_dir + 'holdings-{}.xls'.format(symbol.lower())

Now it's time to setup our chromedriver preferences via the 'ChromeOptions' method. You must define a default directory for this to work properly. During this step I also define my chromedriver filepath for convenience. 


# ----- Chromedriver options/preferences -----
chromeOptions = webdriver.ChromeOptions()
prefs = {'download.default_directory':insert_my_default_dir}
chromeOptions.add_experimental_option('prefs', prefs)
chromedriver_path = insert_my_chromedriver_filepath

Now for the 'money' code. In this step we will instantiate the webdriver (fancy word for automated browser), tell it to navigate to our previously defined URL, tell it to wait until the 'Holdings' tab is visible, click the tab link, then wait again until the 'Download All Holdings .xls' link is visible, click it, confirm the file has downloaded and finally exit the browser. 


"""
I often use prettyprint functions to tell me what's happening with the code, feel free to delete them if you like they are not required.
"""
pp('{} running holdings download..[start]'.format(symbol)) 
driver = webdriver.Chrome(executable_path=chromedriver_path, chrome_options=chromeOptions)
driver.set_page_load_timeout(90) # avoid hanging browser
try:
	driver.get(url)
    holdings_element = WebDriverWait(driver, 30) \
		.until(EC.presence_of_element_located((By.XPATH, holdings_xpath)))
    holdings_element.click()
    csv_element = WebDriverWait(driver, 30) \
		.until(EC.presence_of_element_located((By.XPATH, csv_xpath)))
    csv_element.click() # start download
    # the code below checks the file exists before exiting the browser
    for i in range(1,10,2):
    	time.sleep(i/20)
        if os.path.isfile(file_string)==True:
        	break
except Exception as e:
	print(e)
finally:
	driver.quit()
    pp('{} running holdings download..[complete]'.format(symbol))            

That's it. Now you should have the SPY holdings .xls file on your local hard drive.  If you want to get fancy you can throw this code into a function or class structure like I have. This allows you to run the code in a loop if, for example, you have 10 different State Street ETFs whose holdings data you need.

Composite Macro ETF Cumulative Return Momentum (08.16.2015)

Here are the updated ETF components I'm using to construct the ETF composites. 


’Large Cap’ :[‘SPY’],
‘Mid Cap’ :[‘MDY’],
‘Small Cap’ :[‘IWM’],
‘Global Equity’ :[‘VEU’,’ACWI’,’VXUS’,’DGT’],
‘AsiaPac Equity’ :[‘EWT’,’EWY’,’EWA’,’EWS’,’AAXJ’,’FXI’,’EWH’,’EWM’,’EPI’,’INDA’,’RSX’],
‘Europe Equity’ :[‘FEZ’,’EZU’,’VGK’,’HEDJ’,’EWU’,’EWI’,’EWP’,’EWQ’,’EWL’,’EWD’],
‘Emerging | Frontier’ :[‘EWZ’,’EWW’,’ECH’,’GAF’,’FM’,’EEM’,’VWO’],
‘Real Estate’ :[‘RWO’,’RWX’,’RWR’,’IYR’,’VNQ’],
‘Consumer Discretionary’:[‘XLY’,’XRT’],
‘Consumer Staples’ :[‘XLP’,’FXG’],
‘Energy’ :[‘XLE’,’IPW’,’XOP’],
‘Financials’ :[‘XLF’,’KBE’,’KIE’,’IYG’,’KRE’],
‘Healthcare’ :[‘XLV’,’XBI’,’IBB’],
‘Industrial’ :[‘XLI’,’IYT’],
‘Materials’ :[‘XLB’,’XHB’,’XME’,’IGE’,’MOO’,’GDX’,’GDXJ’],
‘Technology’ :[‘XLK’,’SMH’,’HACK’,’FDN’],
‘Telecom’ :[‘IYZ’],
‘Utilities’ :[‘IDU’,’XLU’],
‘Oil | Gas’ :[‘UNG’,’BNO’,’OIL’],
‘Precious Metals’ :[‘GLD’,’SLV’,’IAU’],
‘Technology’ :[‘XLK’,’SMH’,’HACK’,’FDN’],
‘Bonds’ :[‘TLT’,’AGG’,’JNK’,’LQD’],
‘T-Bond Yields’ :[‘^TYX’,’^TNX’,’^FVX’]
— blackarbsCEO

Last 504 Trading Days

Composite ETF Cumulative Returns

Last 252 Trading Days

Composite ETF Cumulative Returns

Last 126 Trading Days

Composite ETF Cumulative Returns

Last 63 Trading Days

Composite ETF Cumulative Returns

last 21 Trading days

Composite ETF Cumulative Returns

Last 10 Trading days

Composite ETF Cumulative Returns