Just testing translating some code from iPython to Quantopian. I'm trying to calculate the linear regression slope for 5-day price movement for each security by creating a custom factor in a pipeline, but keep getting "error: "all the input array dimensions except for the concatenation axis must match exactly"" when I try to call pipeline_output.
Does anyone know how to fix this? Thank you!
This is how I'm computing the slope:
# Create custom factor #1: 5-day price movement slope
class Momentum(CustomFactor):
inputs = [USEquityPricing.close]
window_length = 5
def compute(self, today, assets, out, close):
slope, intercept, r_value, p_value, std_err = stats.linregress(list(range(0,4)),close[0:4])
out[:] = slope
This is the full code:
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline import CustomFactor
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
from scipy import stats
import pandas as pd
# Create custom factor #1: 5-day price movement slope
class Momentum(CustomFactor):
inputs = [USEquityPricing.close]
window_length = 5
def compute(self, today, assets, out, close):
slope, intercept, r_value, p_value, std_err = stats.linregress(list(range(0,4)),close[0:4])
out[:] = slope
# initialize pipeline and add any custom factors
def initialize(context):
pipe = Pipeline()
attach_pipeline(pipe, 'ranked_momentum')
# Add the custom factor to the pipeline
momentum = Momentum()
pipe.add(momentum, 'momentum')
#Rank momentum factor and add the rank to our pipeline
momentum_rank = momentum.rank(ascending=False)
pipe.add(momentum_rank, 'mom_rank')
# Schedule my rebalance function
schedule_function(func=rebalance,
date_rule=date_rules.every_day(),
time_rule=time_rules.market_open(hours=0,minutes=30),
half_days=True)
# set my leverage
context.long_leverage = 0.50
context.short_leverage = -0.50
def before_trading_start(context, data):
# Call pipeline_output to get the output
context.output = pipeline_output('ranked_momentum')
# Narrow down the securities to only the top 100 and bottom 100 & update my universe
context.long_list = context.output.sort(
['mom_rank'],
ascending=True
).iloc[:100]
context.short_list = context.output.sort(
['mom_rank'],
ascending=True
).iloc[-100:]
update_universe(context.long_list.index.union(context.short_list.index))
def handle_data(context, data):
# Record and plot the leverage of our portfolio over time.
record(leverage=context.account.leverage)
print "Long List"
log.info("\n" + str(context.long_list.sort(['mom_rank'], ascending=True).head(10)))
print "Short List"
log.info("\n" + str(context.short_list.sort(['mom_rank'], ascending=True).head(10)))
# This rebalancing is called according to our schedule_function settings.
def rebalance(context,data):
long_weight = context.long_leverage / float(len(context.long_list))
short_weight = context.short_leverage / float(len(context.short_list))
for long_stock in context.long_list.index:
if long_stock in data:
#log.info("ordering longs")
#log.info("weight is %s" % (long_weight))
order_target_percent(long_stock, long_weight)
for short_stock in context.short_list.index:
if short_stock in data:
#log.info("ordering shorts")
#log.info("weight is %s" % (short_weight))
order_target_percent(short_stock, short_weight)
for stock in context.portfolio.positions:
if stock not in context.long_list.index and stock not in context.short_list.index:
order_target(stock, 0)