Wow, it feels great to finally figure something out! I couldn't have done it without the help of others. (Lots of thanks to Alan!)
I have attached a working backtest that uses Pipeline and a few CustomFactor classes. I have modified these classes so that they can be used for different input types (lows, highs, close, volume, etc).
class PercentChange(CustomFactor):
# Tristan Rhodes
# https://www.quantopian.com/posts/my-first-pipeline-how-to-find-stocks-with-consecutive-higher-lows-low-4-low-3-low-2-low-1
#
# PercentChange will calculate the percent change of an input over the n-most recent days, where n = window_length.
# This can by used for price inputs (low, high, close, open), volume, or even fundamentals (set window length for desired period)
# Set the default list of inputs as well as the default window_length.
# Default values are used if the optional parameters are not specified.
inputs = [USEquityPricing.close]
window_length = 10
def compute(self, today, assets, out, input1):
out[:] = (input1[-1] - input1[0]) / input1[0]
class ConsecutiveHigherValues(CustomFactor):
# Tristan Rhodes
# https://www.quantopian.com/posts/my-first-pipeline-how-to-find-stocks-with-consecutive-higher-lows-low-4-low-3-low-2-low-1
#
# ConsecutiveHigherValues will return the number of periods that the value has consecutively increased, leading up to the current period.
# This can by used for price inputs (low, high, close, open) or volume. (Fundamentals don't usually change on a daily basis, right?)
#
# Set the default list of inputs as well as the default window_length.
# Default values are used if the optional parameters are not specified.
window_length = 10
inputs = [USEquityPricing.low]
def compute(self, today, assets, out, input1):
for a in range(len(assets)):
consecutive = 0
for i in range(-1,-self.window_length,-1):
if input1[i-1,a] < input1[i,a]:
consecutive = abs(i)
else:
break
out[a] = consecutive