# Import statements
# Need the following to run pipeline and make custom factors
from quantopian.pipeline import CustomFactor, Pipeline
from quantopian.research import run_pipeline
# Get some data
from quantopian.pipeline.data.builtin import USEquityPricing
# Import a few built in filters
from quantopian.pipeline.filters import Q1500US, StaticAssets
# Define class for a CustomFactor outputting signed gaps as %
class SignedGapPct(CustomFactor):
# Default input
inputs = [USEquityPricing.close, USEquityPricing.open]
# Need a window length of 2 because we want 2 days of data (yesterday and the day before that)
window_length = 2
def compute(self, today, asset_ids, out, close, open):
# Calculates the column-wise gaps, how to ignore NaNs?
# Take yesterdays open (-1) and divide by the previous days close (-2)
out[:] = (open[-1] - close[-2]) / close[-2]
def make_pipeline():
"""
Create our pipeline.
"""
# Base universe set to the Q1500US.
base_universe = Q1500US()
# Factor to calculate gap up/down (signed) in percent normalised to previous day close
signed_gap_pct = SignedGapPct(mask=base_universe)
open_price = USEquityPricing.open.latest
close_price = USEquityPricing.close.latest
# filter out NaN
# This isn't really necessary (though doesn't hurt) since the top and bottom
# methods don't look at NaN values
#filter_not_nan = signed_gap_pct.notnan()
# filter for top 5 gap up
filter_top_gap_up = signed_gap_pct.top(5)
# filter for bottom 5 gap down
filter_bottom_gap_down = signed_gap_pct.bottom(5)
# aggregated filter for pipeline screen
aggr_screen = filter_top_gap_up | filter_bottom_gap_down
return Pipeline(
columns={
'signed_gap_pct': signed_gap_pct,
'open_price': open_price,
'close_price': close_price,
},
screen = (aggr_screen),
)
my_pipe = make_pipeline()
result = run_pipeline(my_pipe, '2017-12-17', '2017-12-19')
result
The above checks out. Take CSX for example. The close from 12-18 (remember thats actually the close on the previous trading day 12-15) is 52.81. The open from 12-19 (again actually the 12-18 open) is 51.70. The "gap up" is (51.70/52.81)-1 which equals -0.021019. This matches the value in the dataframe above.