Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Setting custom behavior for an Algorithm

Is it possible to limit the algorithms in quantopian to behave in a certain way? Like- I want my algorithm to sell all the assets before it's earning report date, in that case, if I'm working with multiple symbols, how should I specify and set the date so that every time the earning report date is closer, it doesn't hold any asset of that particular one?

2 responses

One can always check the 'current' backtest date when an algo is running by using the get_datetime method. This would probably be some sort of hard coded comparison and could work for a quick check. Probably not reasonable for a large number of stocks over a large timeframe. Maybe look at this https://www.quantopian.com/posts/compare-time .

However, a much better approach is to check the actual earnings announcements and base trades on those. Check out this post for some ideas. https://www.quantopian.com/posts/how-to-use-earnings-announcements-in-your-strategies

Hi, I have looked at the links and 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 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)