This notebook explores some of the Morningstar fundamentals.
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from datetime import date, timedelta
from quantopian.research import run_pipeline
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
# from quantopian.pipeline.factors import CustomFactor, Returns, SimpleMovingAverage as SMA
from quantopian.pipeline.classifiers.fundamentals import Sector
from quantopian.pipeline.filters import QTradableStocksUS, Q500US
from quantopian.pipeline.data.morningstar import Fundamentals as ms
# import quantopian.optimize as opt
import alphalens as al
# Original QCU Factors
roic = ms.roic.latest.rank()
cash_return = ms.cash_return.latest.rank()
fcf_yield = ms.fcf_yield.latest.rank()
ltd_to_eq = ms.long_term_debt_equity_ratio.latest.rank(ascending=False)
# Traditional Value Factors
div_yield = ms.trailing_dividend_yield.latest.rank()
pb_ratio = ms.pb_ratio.latest.rank(ascending=False)
ps_ratio = ms.ps_ratio.latest.rank(ascending=False)
pcf_ratio = ms.pcf_ratio.latest.rank(ascending=False)
# Other Important Fundamentals
roa = ms.roa.latest.rank()
roe = ms.roe.latest.rank()
pe_ratio = ms.pe_ratio.latest.rank(ascending=False)
peg_ratio = ms.peg_ratio.latest.rank(ascending=False)
pipe = Pipeline(
columns = {
'ROIC': roic,
'Cash Return': cash_return,
'FCF Yield': fcf_yield,
'LTD/E': ltd_to_eq,
'Div Yield': div_yield,
'P/B Ratio': pb_ratio,
'P/S Ratio': ps_ratio,
'P/CF Ratio': pcf_ratio,
'ROA': roa,
'ROE': roe,
'P/E Ratio': pe_ratio,
'P/EG Ratio': peg_ratio,
'Sector': Sector()
},
screen=Q500US()
)
start = '2003-01-01'
end = str(date.today() - timedelta(days=1))
MORNINGSTAR_SECTOR_CODES = {
-1: 'Misc',
101: 'Basic Materials',
102: 'Consumer Cyclical',
103: 'Financial Services',
104: 'Real Estate',
205: 'Consumer Defensive',
206: 'Healthcare',
207: 'Utilities',
308: 'Communication Services',
309: 'Energy',
310: 'Industrials',
311: 'Technology' ,
}
data = run_pipeline(pipe, start, end)
data.head()
corrs = data.corr()
f, ax = plt.subplots(figsize=(14, 12))
mask = np.triu(np.ones_like(corrs, dtype=np.bool))
sns.heatmap(corrs, vmax=1, center = 0, mask = mask, annot = True)
asset_list = data.index.levels[1]
prices = get_pricing(asset_list, start, end, fields='open_price')
sectors = data['Sector']
periods = (5, 10, 20)
def analyze(factor_name):
factor = data[factor_name]
factor_data = al.utils.get_clean_factor_and_forward_returns(
factor=factor, prices=prices, groupby=sectors, groupby_labels=MORNINGSTAR_SECTOR_CODES,
periods=periods)
al.tears.create_full_tear_sheet(factor_data, by_group=True)
analyze('Div Yield')
# Doesn't appear to be very predictive
analyze('LTD/E')
# Doesn't appear to be very predictive
analyze('P/B Ratio')
# Doesn't appear to be very predictive
analyze('P/CF Ratio')
# Use it!
# - Has good mean period wise return by quantile
# - Good cumulative return by quantile for each return period
# - Performs poorly in communication services, energy, finance, and utilities
analyze('P/E Ratio')
# Use it!
# - has good mean period wise return by factor quantile
# - Has good cumulative returns by quantile
# - Performs poorly in consumer cylcical, energy, and real estate
# - Excels in communication, defense, industrials, tech, and utilities
analyze('P/EG Ratio')
# Don't use it. Doesn't exist in enough entries.
analyze('P/S Ratio')
# Use it!
# - Good mean period wise return by factor quantile
# - Good cumulative return by quantile
# - Struggles in basic materials, communication services, consumer cyclical, consumer defense,
# finance, real estate, tech, and utilities.
# - Excels in energy, healthcare, and industrials.
analyze('ROIC')
# Use it!
# - Strong overall returns by quantile
# - String cumulative return plots by quantile
# - Struggles in communications, consumer cyclical, energy, healthcare, industrials, real estate,
# utilities
# - Excels in basic materials, consumer defensive, finance, tech
analyze('ROE')
# Use it!
# - strong returns by quantile
# - Strong cumulative return by quantile plots
# - Struggles in communications, consumer defensive, healthcare, industrials, real estate, utilities
# - Excels in materials, energy, tech,
analyze('ROA')
# Use it!
# - strong mean returns by quantile
# - ok cumulative returns by quantile
# - Struggles in communications, consumer cyclical, energy, industrials, real estate, utilities
# - Excels in materials, consumer defensive, financial services, tech
analyze('Cash Return')
# Use it! Has to be the best factor I have so far.
# - Fantastic mean returns by quantile
# - Fantastic cumulative return plots by quantile
# - Struggles in communication services, consumer cyclical, real estate, utilities
# - Excels in materials, consumer defensive, energy, financial services, healthcare, industrials, tech
analyze('FCF Yield')
# Use it!
# - Fantastic mean returns by quantile; not quite as good as Cash Return
# - Great cumulative return plots by quantile
# - Struggles in communications, consumer cyclical, finance, real estate, utilities
# - Excels in materials, consumer defensive, energy, industrials, tech