Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Help improving this Algorithm - buying at 80% discount

I really appreciate any help I can get with making this code work (I am kind of a newbie)
Basically, I have a portfolio of about 100 positions that I intend to hold for several years. But to take advantage of short term price drops, I want an algorithm that, for any of my positions that drop by 20% below the cost basis, the algorithm will add more shares (1 share at a time) until the average price for that stock is no longer 20% blow cost basis.
For example, if I have 10 stock of CAT that I bought at $100/share. If CAT drops to $79/share (21% down), the algorithm would initiate an order to buy 1 share. Now I would have 11 shares of CAT with cost basis of 98.09 {(10 *100 + 1*79)/11}. Since $79 is about 19.5% blow $98.09, no more orders will be initiated but if CAT price drops again to $78 which is 20.5% below $98.09, the algorithm would initiate another order for 1share.

When I deployed this algorithm to live trading with Robinhood I thought it would work, but it did not add any of the stocks for the positions that met the specified criteria. I do not understand why - this is the part I need help figuring out. I have two positions in my portfolio that meet the 20% down criteria and there is enough cash in the portfolio. I kindly request help figuring out why.

Please help me figure why the algorithm did not initiating buy trades for stocks below 20% of cost basis.

4 responses

Take a look at the the debug tools that Quantopian offers when using the IDE environment https://www.quantopian.com/help#debugger. Set breakpoints so you can see what your code is doing.

Anyway, a few things....

  1. you have the initialize function defined in three places. Not good. Only define it once. In your app only the last definition ever gets executed.
  2. 'context.bought' is set to False in the initialize method. In 'handle_data' this variable is checked before executing any trades. Since it is False no trades are ever executed.
  3. 'context.stock' is set to 'context.portfolio.positions'. When the algorithm starts this is empty. Since you never add any stocks to this list it stays empty and is another reason why your algorithm never buys.

Also, the way you are using the 'data.current' method to get the stock prices, 'current_price' will only contain the last stock price (not the prices of all the stocks). Consider not looping through the stocks (not really very Pythonic anyway) and maybe using a single line something like this. (this method takes either a single stock or a list of stocks as a parameter)

current_prices = data.current(context.stocks, 'price')

You may want to simply place a limit order every day for each of the stocks in your portfolio. This also has the benefit of capturing any intraday dips.

    # Place a limit order at our target 'discount' price for all stocks in our portfolio  
    for stock in context.portfolio.positions:  
        if data.can_trade(stock):  
            limit_price = (1 - DISCOUNT_PERCENT_TO_BUY_AT) * context.portfolio.positions[stock].cost_basis  
            order(stock, 1, style=LimitOrder(limit_price))  

See attached algorithm (note that I set the buy threshold to 2% just to see more trades. set it to 20% in your case)

Dan, thank you for helping me with this.
I tried to backtest this algo but I am having trouble understanding something. Although it is executing purchases (per back test), here are two things I noticed
1: It is not executing at the specified discount. For example, when I set the discount at 10% (0.1), it buys the first share of AAPL at 23.01. The next AAPL purchase is at 21.51. This is a 6.5% drop as opposed to the the specified 10%. In testing it over a long time, there are actually instances where it purchased at a price higher that the cost-basis at that time.

2: It seems the algo is executing only 1 order per stock per day. For example, on a day that AAPL dropped around 7%, the algo made only 1 purchase. After that purchase, the day's price was still more than 10% down from cost basis, but no further order were made for that day.

I am trying to figure of why this is happening but have not succeeded yet.

@Lemuel

  1. The 'order' methods default to market orders. They will buy at whatever the next minute price is (after the minute it was entered). Even though there may have been a 10% dip one minute, the next minute after you placed your order the price went up. I'd suggest always entering a limit order. This will guarantee you never pay more than your limit price.

  2. Not sure why your algo isn't trading. Maybe attach a backtest?