Hi, I'm trying to add Earnings Announcements in the sample Pair-Trading Algorithm so that it doesn't hold or buy any asset since or close to it's earning announcements(eg. 7days). I have tried using pipeline and the method stated above but still getting some runtime error and couldn't figure it out. I'm not really sure what's wrong with my code or if I'm missing something?
Also, how can I use eventvestor data or import EarningsCalendar while using Zipline in my local environment?
Here' my code:
import numpy as np
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
# For use in your algorithms
# Using the full dataset in your pipeline algo
from quantopian.pipeline.data.eventvestor import EarningsCalendar
# To use built-in Pipeline factors for this dataset
from quantopian.pipeline.factors.eventvestor import (
BusinessDaysUntilNextEarnings,
BusinessDaysSincePreviousEarnings
)
import pandas as pd
def make_pipeline():
pipe = Pipeline()
ne = BusinessDaysUntilNextEarnings()
pe = BusinessDaysSincePreviousEarnings()
pipe.add(ne, 'next_earnings')
pipe.add(pe, 'prev_earnings')
# The number of days before/after an announcement that you want to
# avoid an earnings for.
avoid_earnings_days = 7
does_not_have_earnings = ((ne.isnan() | (ne > avoid_earnings_days)) & (pe > avoid_earnings_days))
# Before we do any other ranking, we want to throw away these assets.
pipe.set_screen(does_not_have_earnings)
return pipe
def before_trading_start(context, data):
context.results = pipeline_output('factors')
def check_earnings_proximity(context, security):
# For Option 2: Checks whether or not your security currently has
# an earnings announcement within X days. Where X is defined by
# context.avoid_earnings_days
next_earnings = context.results['next_earnings']
prev_earnings = context.results['prev_earnings']
if next_earnings <= context.avoid_earnings_days or prev_earnings <= context.avoid_earnings_days:
return True
return False
def initialize(context):
set_slippage(slippage.FixedSlippage(spread=0))
set_commission(commission.PerTrade(cost=.003))
attach_pipeline(make_pipeline(), 'factors')
#set_benchmark(sid(21774))
context.stock1 = symbol('CCE')
context.stock2 = symbol('KO')
context.security_list = [context.stock1, context.stock2]
context.threshold = 1
context.in_high = False
context.in_low = False
schedule_function(rebalance, date_rule=date_rules.every_day(), time_rule=time_rules.market_close(hours=1))
def rebalance(context, data):
canTrade = False
s1 = context.stock1
s2 = context.stock2
if len(get_open_orders()) > 0:
#return
for security in context.security_list:
if check_earnings_proximity(context, security):
canTrade = False
log.info("Earnings calendar release too close, not trading %s!" % security.symbol)
else:
canTrade = True
if not canTrade:
order_target_percent(s1, 0)
order_target_percent(s2, 0)
context.in_high = False
context.in_low = False
p60 = data.history(context.security_list, 'price', 60, '1d')
p5 = p60.iloc[-5:]
# Get the 60 day mavg
m60 = np.mean(p60[s1] - p60[s2])
# Get the std of the last 60 days
std60 = np.std(p60[s1] - p60[s2])
# Current diff = 5 day mavg
m5 = np.mean(p5[s1] - p5[s2])
# Compute z-score
if std60 > 0:
zscore = (m5 - m60)/std60
else:
zscore = 0
if zscore > context.threshold and not context.in_high and all(data.can_trade(context.security_list)):
for security in context.security_list:
if check_earnings_proximity(context, security):
canTrade = False
log.info("Earnings calendar release too close, not trading %s!" % security.symbol)
else:
canTrade = True
if canTrade:
order_target_percent(s1, -0.5) # short top
order_target_percent(s2, 0.5) # long bottom
context.in_high = True
context.in_low = False
elif zscore < -context.threshold and not context.in_low and all(data.can_trade(context.security_list)):
for security in context.security_list:
if check_earnings_proximity(context, security):
canTrade = False
log.info("Earnings calendar release too close, not trading %s!" % security.symbol)
else:
canTrade = True
if canTrade:
order_target_percent(s1, 0.5) # long top
order_target_percent(s2, -0.5) # short bottom
context.in_high = False
context.in_low = True
elif abs(zscore) < 1 and all(data.can_trade(context.security_list)):
order_target_percent(s1, 0)
order_target_percent(s2, 0)
context.in_high = False
context.in_low = False
record('zscore', zscore, lev=context.account.leverage)