class LINEARREG_SLOPE(CustomFactor):
'''
Slope of Trendline
Momentum Indicator
**Default inputs** USEquityPricing.close
**Default Window Length** 14
'''
inputs = [USEquityPricing.close]
window_length = 15
def compute(self, today, assets, out, close):
# Prepare X matrix (x_is - x_bar)
X = range(self.window_length)
X_bar = np.nanmean(X)
X_vector = X - X_bar
X_matrix = np.tile(X_vector,(len(close.T), 1)).T
# Prepare Y matrix
Y_bar = np.nanmean(close, axis =0)
Y_bars = np-tile(Y_bar, (self.window_length, 1))
Y_matrix = close - Y_bars
# Prepare variance of x
X_var = np.nanvar(X)
# multiply X matrix and Y matrix and sum (dot product)
# then divide by variance of X
# this gives MLE of beta
out[:] = (np.sum((X_matrix * Y_matrix), axis = 0)/ X_var) / (self.window_length)
def make_pipeline():
base_universe = Q500US
fast_slope = LINEARREG_SLOPE(inputs = [USEquityPricing.close], window_length = 15, mask = base_universe)
slow_slope = LINEARREG_SLOPE(inputs = [USEquityPricing.close], window_length = 30, mask = base_universe)
sma_5 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length = 5, mask = base_universe)
sma_15 =SimpleMovingAverage(inputs = [USEquityPricing.close], window_length = 15, mask = base_universe)
percent_change = (sma_5 - sma_15)/sma_15
up_indicate = fast_slope>slow_slope
down_indicate = fast_slope < slow_slope
latest_price = [USEquityPricing.close.latest]
longs = ((up_indicate) & (percent_change > 0.05))
shorts = ((down_indicate) & (percent_change < -0.05))
is_tradeable = (longs|shorts)
return Pipeline(
columns = {
'longs':longs,
'shorts':shorts,
'percent_change':percent_change
},
screen = is_tradeable
)
results = run_pipeline(make_pipeline(), '2015-01-01', '2015-01-01')
results.head()