from quantopian.pipeline import CustomFactor
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
import numpy as np
from scipy import stats
class MomentumScore(CustomFactor):
"""
Computes Annualized Exponential Regression Slope * R2
Pre-declares close as default inputs and `window_length` as
125.
"""
inputs = [USEquityPricing.close]
window_length = 125
def compute(self, today, assets, out, ts):
# Make a list of consecutive numbers
x=np.arange(ts.shape[0])
# Get logs
log_ts=np.log(ts)
# Calculate regression values
statistics=np.polyfit(x,log_ts,1,full=True)
slope=statistics[0][0,:]
r_value=statistics[1]
# Annualize percent
annualized_slope=(np.power(np.exp(slope),252)-1)*100
# Adjust for fitness and return score
out[:] = np.multiply(annualized_slope,np.power(r_value,2))
momentum_score = MomentumScore()
# Pipeline imports
from quantopian.pipeline import Pipeline
from quantopian.pipeline.filters import Q3000US
from scipy import stats
import numpy as np
# Pipeline definition
def make_pipeline():
base_universe = Q3000US()
score = MomentumScore()
# Create filter for top 350 and bottom 350
# assets based on their sentiment scores
top_scores = (
score.top(300)
)
return Pipeline(
columns={
'score': score,
},
# Set screen as the intersection between our filter
# and trading universe
screen=(
base_universe
& top_scores
)
)
# Import run_pipeline method
from quantopian.research import run_pipeline
# Specify a time range to evaluate
period_start = '2003-01-01'
period_end = '2020-01-01'
# Execute pipeline over evaluation period
pipeline_output = run_pipeline(
make_pipeline(),
start_date=period_start,
end_date=period_end
)
pipeline_output
# Import prices function
from quantopian.research import prices
# Get list of unique assets from the pipeline output
asset_list = pipeline_output.index.levels[1].unique()
# Query pricing data for all assets present during
# evaluation period
asset_prices = prices(
asset_list,
start=period_start,
end=period_end
)
# Import Alphalens
import alphalens as al
# Get asset forward returns and quantile classification
# based on sentiment scores
factor_data = al.utils.get_clean_factor_and_forward_returns(
factor=pipeline_output['score'],
prices=asset_prices,
max_loss=1
)
# Display first 5 rows
factor_data.head(5)
import pandas as pd
# Calculate factor-weighted long-short portfolio returns
ls_factor_returns = al.performance.factor_returns(factor_data)
# Plot cumulative returns for 5 day holding period
al.plotting.plot_cumulative_returns(ls_factor_returns['1D'], '1D', freq=pd.tseries.offsets.BDay());
al.plotting.plot_cumulative_returns(ls_factor_returns['5D'], '5D', freq=pd.tseries.offsets.BDay());
al.plotting.plot_cumulative_returns(ls_factor_returns['10D'], '10D', freq=pd.tseries.offsets.BDay());