Back to Community
How would I check for a gap up or gap down to previous day's close

Algorithm is running minutely data.

How would I capture the previous day's close to test for a gap on the subsequent day's open?

3 responses

Chuck,

Attached, you'll find an example (hopefully bug-free). It'll only handle one security as-is. The trick is to store the most recent previous price at the end of each iteration:

context.previous_price = current_price  

Then, when a new day is detected, the opening price can be compared to the closing price from the prior day.

You might also be interested in https://www.quantopian.com/posts/trading-earnings-surprises-with-estimize-data, which inspired me to write the attached algorithm.

Grant

Clone Algorithm
703
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
hold_period = 15 # hold period in days
threshold = 5 # price difference threshold in percent

def initialize(context):
    
    context.stocks = [sid(23709)] # NFLX
    
    context.previous_price = 1
    
    context.initialize = True
    context.event_day = 0
    context.new_day = False
    context.day_counter = 0
    context.bought = False
    context.day_submitted = 0
    context.num_shares = 0
    context.hold_period = 0
  
def handle_data(context, data):
 
    current_price = data[context.stocks[0]].price
    
    num_shares = context.portfolio.cash/current_price
    
    # current_price = current_price*data[context.stocks[0]].volume
    
    event_day = data[context.stocks[0]].datetime.day
    
    if context.initialize:
        context.event_day = event_day
        context.initialize = False 
    
    if event_day != context.event_day:
        context.new_day = True
    else:
        context.new_day = False
        
    if context.new_day:
        context.day_counter = context.day_counter + 1
        price_diff = 100*(current_price/context.previous_price-1)
        
        if price_diff > 0:
            record(price_diff = price_diff)
            record(threshold = threshold)
        
        if (price_diff > threshold) and not(context.bought):
            order(context.stocks[0],num_shares)
            context.bought = True
            context.num_shares = num_shares
            print 'Bought '+str(num_shares)+' shares'
            print 'Hold period '+str(hold_period)+' days'
            context.day_submitted = context.day_counter
            context.hold_period = hold_period
        elif context.day_counter-context.day_submitted == context.hold_period and context.bought:
            order(context.stocks[0],-context.num_shares)
            context.bought = False
            print 'Sold '+str(context.num_shares)+' shares'
    
    context.previous_price = current_price
    context.event_day = event_day
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.

A trader named Scott Andrews (with whom I have no affiliation - he maintains a decent web site: "masterthegap" ) makes a living trading opening gaps in index products. I think he trades manually though he backtests in TS and Excel.

It's extremely easy and short in Excel and TS to code. This seems like absurdly long and complicated code in Quantopian for such a super simple concept like opening gaps. Anyone have any opinions on this?

Hello Francis,

The code I posted above could be cleaned up and clarified, undoubtedly...I just cobbled together an algorithm. Specifically, the collection of flags and counters is kinda ugly:

    context.previous_price = 1  
    context.initialize = True  
    context.event_day = 0  
    context.new_day = False  
    context.day_counter = 0  
    context.bought = False  
    context.day_submitted = 0  
    context.num_shares = 0  
    context.hold_period = 0  

I'll think about how to improve the code, and I'm open to suggestions.

Grant