Before moving to a backtest, we can stay in a notebook a little longer and develop our code for identifying gaps.
To start with, we import and re-run our pipeline from the previous notebook:
from codeload.sell_gap.pipeline import make_pipeline
from zipline.research import run_pipeline
pipeline = make_pipeline()
candidates = run_pipeline(pipeline, start_date="2020-01-01", end_date="2020-08-15")
Then we select a particular day to look at in more detail:
candidates = candidates.xs("2020-08-13")
And we load the corresponding data object as of 9:31 that day:
Note that in Zipline, bars contain data from the previous minute. The 9:31 bar contains the 09:30:00-09:30:59 OHLCV data. Thus, this bar contains the day's opening price.
from zipline.research import get_data
data = get_data("2020-08-13 09:31:00")
We are looking for gaps where the opening price is at least 1 standard deviation below the prior day's low and is also below the 20-day moving average. Using the pipeline output and the data object, we identify the gaps:
today_opens = data.current(candidates.index, 'open')
prior_lows = candidates["prior_low"]
stds = candidates["std"]
# find stocks that opened sufficiently below the prior day's low...
gapped_down = today_opens < (prior_lows - stds)
# ...and are now below their moving averages
are_below_mavg = (today_opens < candidates["mavg"])
assets_to_short = candidates[
gapped_down
& are_below_mavg
]
print(assets_to_short)
mavg prior_low std Equity(FIBBG000C3J3C9 [CSCO]) 47.0665 47.27 1.127427
On this particular day, CSCO gapped down. We can check the opening price and validate it against other sources to make sure our logic was correct:
print(today_opens[assets_to_short.index])
Equity(FIBBG000C3J3C9 [CSCO]) 43.79 Name: open, dtype: float64