by Max Margenot
This is a quick notebook meant to provide a snapshot of the performance of common risk factors over the past year, using whatever today is as a reference point.
This notebook is more useful for getting a sense of the behavior of the market over the past year than it is for algorithm development, but it's always important to keep in mind that algorithms run within the context of the market. As market regimes shift, the way your strategy behaves may change, so keeping an eye on the market should prove useful, even if you are designing a strategy with neutrality to common factor risk in mind.
For more information on the common risk factors used in this notebook, check out the Quantopian Risk Model.
from quantopian.research.experimental import get_factor_returns
import matplotlib.pyplot as plt
import datetime as dt
import qgrid
today = dt.datetime.today() - dt.timedelta(days=1)
last_year = dt.datetime.today() - dt.timedelta(weeks=52)
factor_returns = get_factor_returns(start=last_year, end=today)
Here is a quick use-case of qgrid. Try examining the performance of style risk factors when you filter the sector risk factor returns to within $r_{factor} < |0.2|$, or try examining how momentum performs on days where size is small.
qgrid_widget = qgrid.show_grid(factor_returns, show_toolbar=False)
qgrid_widget
Here we calculate the summary statistics of sector and style risk factors over the past year.
summary_stats = factor_returns.describe()
summary_stats[[
'basic_materials',
'consumer_cyclical',
'financial_services',
'real_estate',
'consumer_defensive',
'health_care',
'utilities',
'communication_services',
'energy',
'industrials',
'technology'
]]
summary_stats[[
'momentum',
'size',
'value',
'short_term_reversal',
'volatility'
]]
Here we plot the mean return of each common risk factor and the volatility of the returns of each risk factor. It seems like the volatility of each style factor is generally lower than the volatility of each sector factor, though more observations should be accumulated before stating that with confidence.
summary_stats.loc['mean'].plot(kind='bar',
title='Mean of Common Risk Factor Returns');
summary_stats.loc['std'].plot(kind='bar',
title='Volatility of Common Risk Factor Returns');
Choose which risk factor you'd like to examine in more detail. The following plot will show it alongside bars for one, two, and three standard deviations away from the mean return. The idea here is to get a sense of the outliers in the returns of risk factors over the past year.
selected_risk_factor = 'momentum'
factor_returns[selected_risk_factor].plot(title='{0} Risk Factor Returns'.format(selected_risk_factor))
# First standard deviation
plt.axhline(summary_stats[selected_risk_factor].loc['mean'] + \
summary_stats[selected_risk_factor].loc['std'],
linestyle='--',
color='purple',
alpha=1.0,
label='1 Standard Deviation of {0} Returns'.format(selected_risk_factor))
plt.axhline(summary_stats[selected_risk_factor].loc['mean'] - \
summary_stats[selected_risk_factor].loc['std'], linestyle='--', color='purple', alpha=1.0)
# Second standard deviation
plt.axhline(summary_stats[selected_risk_factor].loc['mean'] + \
2 * summary_stats[selected_risk_factor].loc['std'],
linestyle='--',
color='orange',
alpha=1.0,
label='2 Standard Deviations of {0} Returns'.format(selected_risk_factor))
plt.axhline(summary_stats[selected_risk_factor].loc['mean'] - \
2 * summary_stats[selected_risk_factor].loc['std'], linestyle='--', color='orange', alpha=1.0)
# Third standard deviation
plt.axhline(summary_stats[selected_risk_factor].loc['mean'] + \
3 * summary_stats[selected_risk_factor].loc['std'],
linestyle='--',
color='r',
alpha=1.0,
label='3 Standard Deviations of {0} Returns'.format(selected_risk_factor))
plt.axhline(summary_stats[selected_risk_factor].loc['mean'] - \
3 * summary_stats[selected_risk_factor].loc['std'], linestyle='--', color='r', alpha=1.0)
plt.legend();
And, finally, here we examine the cumulative returns of each common risk factor. Sector factors seem to be collectively impacted by significant market shifts, while style factors each react differently.
((1 + factor_returns[[
'basic_materials',
'consumer_cyclical',
'financial_services',
'real_estate',
'consumer_defensive',
'health_care',
'utilities',
'communication_services',
'energy',
'industrials',
'technology'
]]).cumprod() - 1).plot(title='Cumulative Sector Factor Returns');
((1 + factor_returns[[
'momentum',
'size',
'value',
'short_term_reversal',
'volatility'
]]).cumprod() - 1).plot(title='Cumulative Style Factor Returns');