Hi All,
I'm having a bit of an issue but I'm unsure about why this error is occurring. Could anyone help me understand and fix this error? The error is within the rebalance method where I have written moving_average = linear[stock].
Thanks,
Rohit
import numpy as np
from scipy import stats
from quantopian.pipeline import Pipeline
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import AverageDollarVolume
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.filters.morningstar import IsPrimaryShare
def initialize(context):
# Set benchmark security
set_benchmark(sid(8554))
# Sechedule ordering function to order once a day at market open
schedule_function(process_data,
date_rules.every_day(),
time_rules.market_open(hours = 0, minutes = 1))
# Sechedule selling function to sell once a day at market open
schedule_function(rebalance,
date_rules.every_day(),
time_rules.market_open(hours = 0, minutes = 1))
# Record tracking variables at the end of each day
schedule_function(plot,
date_rules.every_day(),
time_rules.market_close(hours = 0, minutes = 1))
attach_pipeline(make_pipeline(context), 'tradable_securities')
def make_pipeline(context):
# top 500 by marketcap
top_500 = morningstar.valuation.market_cap.latest.top(500)
# Not when-issued equities
not_wi = ~morningstar.share_class_reference.symbol.latest.endswith('.WI')
# Filter for primary share equities
primary_share = IsPrimaryShare()
# Equities listed as common stock
common_stock = morningstar.share_class_reference.security_type.latest.eq('ST00000001')
# Equities not trading OTC
not_otc = ~morningstar.share_class_reference.exchange_id.latest.startswith('OTC')
# Construct a 100-day average dollar volume factor and add it to the pipeline.
dollar_volume = AverageDollarVolume(window_length=1)
#Create high dollar-volume filter to be the top 1% of stocks by dollar volume.
high_dollar_volume = dollar_volume.percentile_between(99, 100)
# Set the screen on the pipelines to filter out securities.
#pipe.set_screen(high_dollar_volume)
tradable_securities = {
'top_500':top_500, # increase market cap and compare data
'not_wi':not_wi,
'primary_share':primary_share,
'common_stock':common_stock,
'not_otc':not_otc # put in OTC and compare data
}
# Create, register and name a pipeline
pipe = Pipeline(columns=tradable_securities, screen=high_dollar_volume)
return pipe
def before_trading_start(context, data):
# Pipeline_output returns the constructed dataframe
output = pipeline_output('tradable_securities')
# Assign variable to output
context.my_securities = output.index
def plot(context, data):
"""
This function is called at the end of each day and plots certain variables.
"""
# Check number of long and short positions
longs = shorts = 0
for position in context.portfolio.positions.itervalues():
if position.amount > 0:
longs += 1
if position.amount < 0:
shorts += 1
# Record and plot the leverage of our portfolio over time as well as the
# number of long and short positions. Even in minute mode, only the end-of-day
# leverage is plotted.
record(leverage = context.account.leverage, long_count=longs, short_count=shorts)
def process_data(context, data):
"""
Enter long position if price closes 2.5 standard deviations below 20 period moving average and enter short position if price closes 2.5 standard deviations above 20 period moving average
"""
linear = get_linear(context, data)
for stock in context.my_securities:
close = data.current(stock, "close")
stock_price = data.current(stock, "price")
moving_average = linear[stock]
stddev_history = data.history(stock, "price", 20, "1d")[:-1]
moving_dev = stddev_history.std()
upper_band = moving_average + 2.5*moving_dev
lower_band = moving_average - 2.5*moving_dev
if close < lower_band:
go_long(context, data, stock, stock_price)
if close > upper_band:
short(context, data, stock, stock_price)
def go_long(context, data, stock, stock_price):
long_weight = 0.6 / len(context.my_securities)
order_target_percent(stock, long_weight, style=StopOrder(stock_price - (stock_price * 0.10)))
def short(context, data, stock, stock_price):
short_weight = -0.4 / len(context.my_securities)
order_target_percent(stock, short_weight, style=StopOrder(stock_price + (stock_price * 0.10)))
def rebalance(context, data):
"""
Sell positions when price is within 0.5 standard deviations of the mean
"""
linear = get_linear(context, data)
for stock in context.portfolio.positions:
moving_average = linear[stock]
stddev_history = data.history(stock, "price", 20, "1d")[:-1]
moving_dev = stddev_history.std()
upper_band_one = moving_average + 0.5*moving_dev
lower_band_one = moving_average - 0.5*moving_dev
stock_price = data.current(stock, "price")
if stock_price >= lower_band_one and stock_price <= upper_band_one:
order_target_percent(stock, 0)
20 period moving average based on a linear regression curve
def get_linear(context, data):
days = [i for i in range(1,21)]
stocks = {}
for stock in context.my_securities:
linear = stats.linregress(days, data.history(stock, "price", 20, "1d"))[1]
stocks[stock] = linear
return stocks