Back to Community
Gap Up/Down Strategy

Hello,

I am new to Python and Quantopian, but I am not new to coding. However, I am having some trouble understanding how to implement the below pseudo-code.

  1. Get a list of S&P 500 stocks.
  2. Find the gap up/down percentage from the previous day's close.
  3. Sort the stocks in order by gap up/down percentage.
  4. For the top 5 gap up stocks (largest gainers): go long at 10 AM EST, and sell at the close of the trading day
  5. For the bottom 5 stocks (largest losers): go short at 10 AM EST, and cover at the close of the trading day

I would really appreciate guidance in how to implement this strategy.

Thanks in advance for your help

4 responses

Hi Rai,

I believe the constituents of the S&P 500 aren't available in Quantopian. You'd have to retrieve them from an external source and feed your algorithm with it using the method fetch_csv(). An alternative is to use:

set_universe(universe.DollarVolumeUniverse(95.0, 100.0))  

Which is a reasonable approximation. Here's a backtest that should help you getting started (may contain errors):

Clone Algorithm
160
Loading...
Backtest from to with initial capital
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
# Backtest ID: 559b7c3a577e3f1236b9c83b
There was a runtime error.

Rai,

You can get a rough facsimile of the S&P 500 using get_fundamentals() The S&P 500 is an index maintained by S&P Dow Jones Indices and they have a detailed process that goes into creating all of there indices. We can get pretty close using get_fundamentals() and sorting the results by market cap and limiting them to 500, which also happens to be the number of securities the Quantopian platform supports! Try this code out...

def before_trading_start(context):  
    sp_500 = get_fundamentals(  
                        query(fundamentals.valuation.market_cap)  
                        .filter(fundamentals.valuation.market_cap > 1e8)  
                        .order_by(fundamentals.valuation.market_cap.desc())  
                        .limit(500))  
    context.fundamental_df = fundamental_df  
    update_universe(context.fundamental_df.columns.values)  
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.

Thanks so much for your help Alexis and James!
I have tried to modify to modify the algorithm so that it:
1) sells the security if the current price is greater than or equal to 1 % more than the purchase price,
2)sells at market close if (1) was not triggered.
I have tried doing this using limit orders, but it just doesn't seem to work. Also, how can I output the time and date of the limit order, when and if it is filled?

 for i in range(-5, 0):  
        amount = int(size/data[gaps[i][0]].price)  
        context.buy_order_id = order(gaps[i][0], amount)  
        buy_price = data[gaps[i][0]].price  
        log.info('entry %s %s %s %s' % (get_order(context.buy_order_id).dt, gaps[i][0], amount, buy_price))  
        sell_limit_price = 1.01*buy_price  
        context.sell_order_id = order_target_value(gaps[i][0], 0, style=LimitOrder(sell_limit_price))  

Rai,

If I were you I wouldn't use a limit order, instead I would check at your desired frequency whether the current price is >= 1% and just issue a market order then. This also gives you more control over the logging capabilities. I'm not sure what your full strategy is but you could have your sell function set using schedule_function and use handle_data to do the 1% check.

James