Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
A sample Dip Buying System - Need help with error

I am getting an error in the line no. 49. Can't figure out why.

Also, how can I implement any one of the following conditions are met and we sell
1. Stop Loss of 10%
2. Profit Target of 2%
3. 5 days past buy and sell on next day open.

Thank you,
Maji

  # For this example, we're going to write a simple Dip Buying script.  When the  
  # stock goes down below a certain level quickly, we're going to buy;  
  # We want to hold it for 5 days or a stop loss of 10% or a profit target of 2%, whichever comes first

  # To run an algorithm in Quantopian, you need two functions: initialize and  
  # handle_data.

def initialize(context):  
  # This initialize function sets any data or variables that you'll use in  
  # your algorithm.  For instance, you'll want to define the security (or  
  # securities) you want to backtest.  You'll also want to define any  
  # parameters or values you're going to use.

  # In our example, we're looking at Apple.  If you re-type this line  
  # yourself, you'll see the auto-complete that is available for the  
  # security ID.  
  context.aapl = sid(24)  
  context.invested = False  
  # In these two lines, we set the maximum and minimum we want our algorithm  
  # to go long or short our security.  You don't have to set limits like this  
  # when you write an algorithm, but it's good practice.  
  context.max_notional = 1000000.1  
  context.min_notional = -1000000.0

def handle_data(context, data):  
  # This handle_data function is where the real work is done.  Our data is  
  # minute-level tick data, and each minute is called a frame.  This function  
  # runs on each frame of the data.  
  # We've built a handful of useful data transforms for you to use.  In this  
  # line, we're computing the volume-weighted-average-price of the security  
  # defined above, in the context.aapl variable.  For this example, we're  
  # specifying a three-day average.  
  vwap = data[context.aapl].vwap(3)  
  # We need a variable for the current price of the security to compare to  
  # the average.  
  price = data[context.aapl].price  
  # Another powerful built-in feature of the Quantopian backtester is the  
  # portfolio object.  The portfolio object tracks your positions, cash,  
  # cost basis of specific holdings, and more.  In this line, we calculate  
  # how long or short our position is at this minute.  
  notional = context.portfolio.positions[context.aapl].amount * price  
  # This is the meat of the algorithm, placed in this if statement.  
  # If we have an open position, then sell. I want to add sell conditions here.  
    if context.invested:  
    order(context.aapl,-100)  
    context.invested = False

  # If the price of the security is .5% less than the 3-day volume weighted average  
  # price AND we haven't reached our maximum long, then we call the order  
  # command and buy 100 shares.       

    elif not context.invested and price < vwap * 0.995 and notional < context.max_notional:  
    order(context.aapl,100)  
    context.invested = True


23 responses

Hello Amritendu,

There was a problem with indentation, which I fixed in the attached backtest. I also added some code so that you buy/sell with all of your capital (perhaps not what you intend, but I wanted to make it easy to see if the algorithm was working).

Regarding your other conditions, it is definitely feasible to add them. I don't have time now...perhaps someone else can provide some pointers?

Grant

Hello Maji,

I used Grant's suggestion of being fully invested. Also I adjusted the Take Profit Target to 5% in classic curve-fiting style. At 2% the results are not so good!

P.

"Optimisation" results!

P.

Thank you Peter and Grant. I definitely have a steep learning curve in front of me. I have delved in dip buyers before, and I think they have the best swing trading possibilities.

Peter,
How did you output the result for optimization? Also, how can I trade this over a basket of stocks, say the Nasdaq 100 stocks? These are fairly volatile, but somewhat "safe" as one will be buying a falling knife.

Thanks again,
Maji

Hello Maji,

I ran the algo 25 times and put the numbers in Excel! Zipline is the way to perform optimisations but I have not got that far yet.

The simplest wasy to trade a basket of stocks in Quantopian might be to use the set_universe feature. See: https://www.quantopian.com/help#ide-universe

P.

Thank you Peter.

If use Google stocks, the result is not good...

Emin,
Thank you for your reply. The dip buyers are supposed to be traded as a basket/portfolio and that reduces volatility of returns. It also reduces the returns, but it does reduce the risks more. This code is just the starting point of my research in this area. I don't remember very clearly what I had done before, but I do remember, dip buying using a portfolio was one of the strategies that worked in forward testing.

Hello Amritendu,

You can list up to 100 individual securities individually in your algorithm, which is an alternative to the set_universe function Peter mentions above. So, if you were interested in the Nasdaq 100, you'd need to type in all of the sids, like this:

context.nasdaq_100 = [(list of 100 sids)]

Grant

Thanks Grant. Will see if I can make it work.

Here's an attempt with set_universe - the top 1% of the universe comprises around 83 equities.. The results are not so good! But if this really has a 59% win rate can it be made profitable?

(For simplicity this just goes long 100 shares in each equity without a check for available cash. Also, ignore the pandas import.)

P.

Thank you Peter for your help. This is the starting point of research to make it profitable. :)

One thing that I have noted is that the Nasdaq stocks are more volatile and this system thrives on volatility and needs volume. So, how can we use just the stocks of the Nasdaq100? I think we can set the universe with hard coding the SID #s of the stocks. Is that the right way?

The stocks with top volume are usually steady eddies, and that is not very helpful for this system. Also, the smaller ones that fluctuate too much will hit the stop loss more often. We do not want to optimize the portfolio, but want to keep an eye on this property.

Thanks again.
Maji

Thank you Peter very much.

Hello Maji,

I've amended to include the first 10 members of the NASDAQ 100 based on the list here. You can do the rest!

P.

What is the limit for the number of SIDs that can be listed in an algo? If it's less than 100 can Quantopian consider creating a list of the NASDAQ 100 that we could use?

P.

Thanks Peter. I think 100 is the limit.
Great idea of making the list of Nasdaq 100, and also suggest one for S&P100 and S&P500.

Thanks.

I've added 30 of the NASDAQ 100 but now I have something strange I need some help with. With the 30 equities I get this:

When I remove CELG sid(40207) I get this:

And the transaction list shows this:

Does anyone have any suggestions?

P.

This is the problem backtest.

P.

To answer my own question it seems to be caused by the slippgae model and a thinly traded security. I'm probably buying before I've finished selling all of the previous holding. In some circumstances this seems to create a kind of 'feedback loop' and an escalating holding. Disabling the slippage model is a workaround for now.

P.

This is now trading 52 of the NASDAQ 100. Performance is down because the algo was not controlling the amount of cash used and was borrowing significantly at times. This has now been curtailed but not wholly eliminated.

(Note that a more realistic benchmark of buy-and-hold SPY returns 23% over the same period.)

P.

This benchmark algo is extremely simple but I'm not getting the result I expected. Why is the 'recorded' return 13% but the algo return 23%?

P.

Peter, I think you forgot your cash. See below (and remember you can click on "cash" to make the line disappear, and see only the returns that way).

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, Dan.

P.