I am attempting to write a custom factor to compute the Gain Percent of each stock's industry. I need to be able to offset the window so that I can return (for example) the 1 week gain for the industry for the previous week. I am getting the following error when I try to execute it:
TypeError: zipline.pipeline.pipeline.add() expected a value of type zipline.pipeline.term.Term for argument 'term', but got abc.ABCMeta
instead. There was a runtime error on line 68.
Any help in figuring out how to do this would be appreciated.
FYI: Line 68 is:
pipe.add(gainpctind_off0, name='gainpctind_off0')
Thanks.
# Import the libraries we will use here
import numpy as np
from numpy import ma
import pandas as pd
import talib as ta
from quantopian.pipeline.factors import SimpleMovingAverage
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline, CustomFactor
from quantopian.pipeline.data.builtin import USEquityPricing
import quantopian.pipeline.data.morningstar as ms
def GainPct(offset=0, nbars=2):
class GainPctFact(CustomFactor):
window_length = nbars + offset
inputs = [USEquityPricing.close]
def compute(self, today, assets, out, close):
out[:] = (close[-1] - close[offset]) / close[offset] * 100
return GainPctFact
def GainPctInd(offset=0, nbars=2):
class GainPctIndFact(CustomFactor):
window_length = nbars + offset
inputs = [USEquityPricing.close, ms.asset_classification.morningstar_industry_code]
def compute(self, today, assets, out, close, industries):
# For each industry, build a list of the per-stock gains over the given window
gains_by_industry = {}
for i in range(0, len(industries)):
industry = industries[i]
asset_gainpct = (close[-1] - close[offset]) / close[offset] * 100
if industry in assets_by_industry:
gains_by_industry[industry].append(asset_gainpct)
else:
gains_by_industry[industry] = [asset_gainpct]
# Loop through each stock's industry and compute a mean value for that
# industry (caching it for reuse) and return that industry mean for
# that stock
mean_cache = {}
for i in range(0, len(industries)):
industry = industries[i]
if not industry in mean_cache:
mean_cache[industry] = np.mean(gains_by_industry[industry])
out[i] = mean_cache[industry]
return GainPctIndFact
# The initialize function is the place to set your tradable universe and define any parameters.
def initialize(context):
pipe = Pipeline()
attach_pipeline(pipe, name='my_pipeline')
gainpctind_off0 = GainPctInd()
gainpctind_off1 = GainPctInd(1)
gainpctind1wk = GainPctInd(0, 5)
gainpctindprevwk = GainPctInd(5, 5)
pipe.add(gainpctind_off0, name='gainpctind_off0')
pipe.add(gainpctind_off1, name='gainpctind_off1')
pipe.add(gainpctind1wk, name='gainpctind1wk')
pipe.add(gainpctindprevwk, name='gainpctindprevwk')
def before_trading_start(context, data):
results = pipeline_output('my_pipeline')
print results.head(5)
update_universe(results.sort('gainpctind1wk').index[:10])
# The handle_data function is run every bar.
def handle_data(context,data):
# Record and plot the leverage of our portfolio over time.
record(leverage = context.account.leverage)
# We also want to monitor the number of long and short positions
# in our portfolio over time. This loop will check our positition sizes
# and add the count of longs and shorts to our plot.
longs = shorts = 0
for position in context.portfolio.positions.itervalues():
if position.amount > 0:
longs += 1
if position.amount < 0:
shorts += 1
record(long_count=longs, short_count=shorts)