Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Replicate Buy-on-Gap strategy in the book Algorithmic Trading

I replicate the rule of the strategy in Ernest Chan's book. I want to implement it on Quantopian, but there seems to be many problems, like no "open" in USEquityPricing, some error in constructing standard deviation of close price in CustomFactor. So depressed...

The rules for the strategy are:
1. Select all stocks near the market open whose returns from their
previous day’s lows to today’s opens are lower than one standard
deviation. The standard deviation is computed using the daily closeto-
close returns of the last 90 days. These are the stocks that “gapped
down.”
2. Narrow down this list of stocks by requiring their open prices to be
higher than the 20-day moving average of the closing prices.
3. Buy the 10 stocks within this list that have the lowest returns from their
previous day’s lows. If the list has fewer than 10 stocks, then buy the
entire list.
4. Liquidate all positions at the market close.

6 responses
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.factors import SimpleMovingAverage

# define standard deviation of past close price  
class StandardDev(CustomFactor):  
    # pre-declared inputs and window length  
    inputs = [USEquityPricing.close]  
    window_length = 90  
    # compute standard deviation  
    def compute(self, today, assets, out, close):  
        out[:] = close[-window_length:].diff().std()


# initialization  
def initialize(context):  
    # set commission and slippage  
    set_commission(commission.PerShare(cost=0.0075, min_trade_cost=1))  
    set_slippage(slippage.VolumeShareSlippage(volume_limit=0.1, price_impact=0.1))  
    # Create and attach an empty Pipeline.  
    pipe = Pipeline()  
    pipe = attach_pipeline(pipe, name='my_pipeline')

    # Construct Factors  
    std_90 = StandardDev()  
    sma_20 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=20)  
    open_low = USEquityPricing.open - USEquityPricing.low

    # Construct Filter.  
    open_lt_std = (open_low < std_90)  
    open_gt_sma = (USEquityPricing.open > sma_20)  
    # Register outputs.  
    pipe.add(open_low, 'open-low')

    # Remove rows for which the Filter returns False.  
    pipe.set_screen(open_lt_std and open_gt_sma)


def before_trading_start(context, data):  
    # output result  
    results = pipeline_output('my_pipeline')  
    print results.head(5)

    # Define a universe with the results of a Pipeline.  
    # Take the first ten assets by open minus low.  
    update_universe(results.sort('open_low').index[:10])  

Hi Mingda,

It is a known issue that access to USEquityPricing.open is broken on Quantopian due to conflicts with our security sandbox. This will be fixed in an upcoming release. Regarding the error message raised in the code you shared, the problem was in the comparison between USEquityPricing.low data and your custom factor. Check out the code I shared for how to make it work. The logic isn't the same but I wanted to share it just so you could see what the code should look like.

I hope this helps.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Thank you so much! The main problem is still USEquityPricing.open. Maybe I would try some other methods.

Really...
USEquityPricing.open is broken?
Any idea when that might be fixed?

Note that this will not solve your problem at all, since USEquityPricing.open is, or will be, yesterday's open. There is no way to screen the universe on today's open, since the Pipeline runs at 8:45am or something like that.

Hello Jamie,

Once USEquityPricing.open is fixed, would the Q research platform allow for overnight gap screening? It seems that one could establish the securities list of gainers/losers before running a backtest. One could not go live with the strategy, but at least the feasibility could be studied.

Grant