from quantopian.pipeline import Pipeline, CustomFactor
from quantopian.research import run_pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
import quantopian.pipeline.data.morningstar as morningstar
class CAGR(CustomFactor):
# Define inputs and outputs
inputs = [USEquityPricing.close]
outputs = ['start', 'end', 'cagr']
# Set default window_length
# This can also be set/over-ridden whem the class is instantiated as shown below:
# my_cagr = CAGR(window_length = 250)
window_length = 750 # approx 3 years
def compute(self, today, assets, out, close):
# The input 'close' is a Numpy array with close prices as axis 0 (total rows = window length)
# and axis 1 are all the assets (ie stocks and securities).
trade_days = len(close)
years = trade_days / 250.0 # approximation to get years. decimal forces years to be real.
start = close[0]
end = close[-1]
out.start[:] = start # start and end aren't required
out.end[:] = end # these though can be used to manually check the output
out.cagr[:] = ((end / start) ** (1/years)) - 1 # annualized CAGR formula
def create_pipeline():
"""
Function to create a pipeline with our CAGR custom factor and sample fundamental filter
"""
# Instantiate a factor from the custom factor CAGR and set desired look-back window length
factor = CAGR(window_length = 500)
start = factor.start
end = factor.end
cagr = factor.cagr
# Instantiate a sample fundamental factor and create a filter from it
financial_health_grade = morningstar.asset_classification.financial_health_grade.latest
grade_a = financial_health_grade.eq('A')
# Create a pipeline and add the factors to it
p = Pipeline()
p.add(cagr, 'cagr')
p.add(start, 'start')
p.add(end, 'end')
p.add(financial_health_grade, 'financial_health_grade')
# Set a screen for our pipeline (in this case on Morningstar grade A equities)
p.set_screen(grade_a)
return p
# Run the pipeline with desired date(s)
# The pipeline filters results by "financial_health_grade" equal to A (as an example fiter)
# Results (which is a Pandas dataset) is then sorted by cagr from high to low
# Note that Close can return NaaN which results in a NaaN cagr
results = run_pipeline(create_pipeline(), '10-13-2016', '10-13-2016')
results.sort('cagr', ascending = False)