Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Modifying a simple day trading algorithm

Hi all,

I have been enjoying testing out and playing with the existing framework in Quantopian. It seems to suit my needs well, but I am having some difficulties implementing simple tasks (adjusting to the source code is a bit tricky).

Anyway, I have a day trading algorithm that allows me to read in from a properly formatted csv file and execute trades. The algorithm was working very well for me, except recently I changed how I populate my backlog of stocks. Now there is infrequent spacing between listed stocks (I.E. there might only be a stock every 3 days). I do not want to hold my last stock until the next trade, but I could not find a way access dates outside of this list of stocks that corresponds to my universe.

How can the code be tweaked such that I may read in from a properly formatted CSV, buy the stock at the following days opening price (as I am currently doing) and sell at that days close?

Thanks!

import pandas as pd

def initialize(context):  
    # import the custom CSV data file  
    fetch_csv("ProperlyFormatted.csv",  
              pre_func=preview,  
              post_func=preview,  
              date_column='date',  
              universe_func=my_universe)  
        # Create a variable to track the date change  
    context.yesterday = None  
    context.holdingStock = None

# my_universe returns a set of securities that define your universe.  
def my_universe(context, fetcher_data):  
    my_stocks = set(fetcher_data['sid'])  
    context.count = len(my_stocks)  
    return my_stocks

# see a snapshot of your CSV for debugging  
def preview(df):  
    log.info(' %s ' % df.head())  
    return df

def handle_data(context,data):  
    # bam. copied someone else's code and it uses closing price  
    # out of the box!  
    if get_datetime().date() == context.yesterday: return  
    context.yesterday = get_datetime().date()  
    # basic idea, for each day, find out which stock we need to buy from the csv, then buy it. on the next day, sell everything we have and try to buy that day's stock. in this way, we only hold on to a stock for a day at most  
    print "Holding %s" % context.holdingStock  
    # if we're holding something, try to sell all of it  
    if(context.holdingStock is not None):  
        try:  
            # sell 100% of this stock  
            order_target_percent(context.holdingStock, 0)  
            print "Sold %s" % context.holdingStock.symbol  
        except:  
            pass  
    for stock in data:  
        print "%s %s" % (str(data[stock]['day']), str(get_datetime().date()))  
        # if the stock in the loop isn't to be traded for the day, skip  
        if str(data[stock]['day']) != str(get_datetime().date()):  
            continue  
        try:  
            # use 100% of our money to buy the stock  
            order_target_percent(stock, 1)  
            context.holdingStock = stock  
            print "Bought %s" % stock.symbol  
            break # ordered one for today, that's enough  
        except:  
            print "Couldn't order %s" % stock.symbol  

P.S. ~~ ProperlyFormatted is a csv containing a list of stock names and dates.

3 responses

I'm not sure I'm following your entire desired workflow, or how your fetcher change made for different experience. However, if you're trying to close out all positions at the end of every day, that one is pretty easy to do.

The attached algo will try to close out your positions at the end of the day. It's worth pointing out that it doesn't always succeed because one of the stocks is pretty low volume. That's always a risk.

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.

This would be much easier I think if you shared the whole backtest =)

It looks like you're running your algo in daily mode. Check out the FAQ on how orders are placed and filled. What's happening is that you're placing the order to buy in Day 0, and that order is then being filled in Day 1. That is expected.

Since you want to get in and out of your position on the same day, you need to run in minute mode. The code, as you've written it, will place the orders to buy in minute 5 of the day, and then fill it the next bar. It will place the orders to sell with 10 minutes left in the day, and fill in the next bar.

I think you need to look a bit closer at how you are defining your tradeable universe. Check out the fetcher documentation, and particularly you need to read the section titled "Using Fetcher to create a custom universe" and study the examples there.

Given that sample data you shared, I don't think your string match is really doing much of anything. Your universe is already being defined each day by your file. That string match is essentially only verifying something that you already know - the stock was added that day.

I think you should consider restructuring your data file. Think of each day as defining what your tradeable universe. What you actually do with the stock on a given day is a different parameter that you should also pass in - whether it's buy, hold, or sell.

Put differently, on Day 1 you can define Universe A, and then on Day 2 define Universe B, but you can't touch universe A on Day 2 - that universe is gone. What you need to do is define Universe (A+B) and load it on both Day 1 and Day 2, and then you can buy universe A on Day 1, and sell it on Day 2.