Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Can someone help me figure out the Quantopian code needed for my first algorithm?

I am having an issue. I am trying to implement the algorithm found at:
http://www.reddit.com/r/investing/comments/1fr0z8/analysis_of_a_trading_strategy_buy_the_10_day_low/

The algorithm has as an exit signal, sell if you have been holding a stock for 10 days. I saw that context.portfolio.positions exists but it doesn't seem to include a date for any given stock. Can someone please help me find a way to keep track of how long I have held a stock for? I could maybe do something like

elif buy_signal(context, data) and notional < context.max_notional:  
    order(context.stock,+100)  
    date = #get date somehow  
    context.portfolio.positions[context.stock].date = date  

Thanks for checking this post out.

8 responses

Since posting this, I noticed a lot wrong with how I was using the series being returned when trying to get the ten day high/low so a lot of the code is incorrect. That being said, my question still stands. I can't seem to put a date into context.portfolio.positions[context.stock] so I am curious as to what I should do. I have the updated source code in this post.

Here is a way you can do it:

def initialize(context):  
    context.hold_lengths = dict()

def order_with_hold_time(sid, amount, context):  
    if sid not in context.hold_lengths:  
        context.hold_lengths.update({sid:0})  
    order(sid, amount)

def check_stocks(context, data):  
    for sid in context.portfolio.positions:  
        if context.hold_lengths[sid] >= 10:  
            order(sid, -1 * context.portfolio.positions[sid].amount)  
            context.hold_lengths[sid] = 0  
        context.hold_lenghts[sid] += 1  

So the way to use this code is that whenever you place a new order, you use the order_with_hold_time function. Once a day (which is easy since you are running in daily mode) you will execute the check_stocks function. A few things you might want to decide for yourself. I have it so that if you buy a stock on day 1 and again on day 5, you will sell the stock on day 11. Maybe you want the order on day 5 to reset the counter, so it sells on day 15. If you do, just use this:
def order_with_hold_time(sid, amount, context): context.hold_lengths.update({sid:0}) order(sid, amount)

There is more customization that you can do as well (e.g sell what you bought on day 1 on day 11, and sell what you bought on day 5 on day 15), but this should be a good foundation. This is also selling everything after you've held it for 10 trading days. I can show you how to do it will 10 calendar days as well, if you'd like.

Sam

Thank you for the help. That makes sense to put it on that level in context.

I instead store the date rather than an int to get updated

I did:

def initialize(context):  
  context.purchase_date= dict()

def sell_signal(context, data, sid, days_in_universe):  
  date = data[sid].datetime  
  purchase_date = context.purchase_date.get(sid)  
  open_for = purchase_date - date  
  if open_for.days >= 10:  
    return True  

Great, glad you figured it out!

In case anyone tries this, this code does not work:

def initialize(context):  
  context.purchase_date= dict()

def sell_signal(context, data, sid, days_in_universe):  
  date = data[sid].datetime  
  purchase_date = context.purchase_date.get(sid)  
  open_for = purchase_date - date  
  if open_for.days >= 10:  
    return True  

Correct, I had noticed a bug afterwards that I needed to swap

open_for = purchase_date - date  

with
open_for = date - purchase_date Is there another reason you think it doesn't work?

That reddit post is mine :)

Edit:

To actually add to discussion you can keep your own trade log. so something like context.log = [] and then each time you enter a trade you can append to the log or each time you exit you can delete from the log. So, for example, your log might look something like this: [[stock_x, purchase_date, purchase_price, cost_basis], [stock_y, purchase_date, purchase_price, cost_basis]]. Then under each time data is fed to you you can check your log and see if 10 days has passed by using Python's datetime and comparing your purchase date with the current date.

This is a debugged version that calculates the business days, which is what one actually wants usually:

class Thing(object):  
            def __init__(self, label=None):  
                        self.label = label  
                        self.parent = None  
                        self.children = []  
context = Thing()  
context.purchaseDate = {}  
stock = 12345  
# context.purchaseDate[stock] = pd.datetime.today()  
context.purchaseDate[stock] = datetime.datetime(2014,4,1)  
s = pd.date_range(context.purchaseDate[stock],pd.datetime.today(),freq='D')  
df = pd.DataFrame(0,index=s,columns=list('N'))  
BDayHeld = len(df.asfreq(BDay())) - 1  
BDayHeld