Back to Community
Daily Score Strategy

Hi forum,

You have been awesome. I learned so much from reading all of your stuff. It is the reason I've gotten this far in this algo. So thank you.

Day trading avoids the pitfalls of volatile seasonal adjustments. Trades are based on the right knowledge of the stock (insight and information based on reports). It has been noted that a strategy making just 1% a day on a consistent basis can mean you will beat 99% of wall street. Given the right insight, wether if it's from custom data, equations, or reports, you're trying to make the most informed decision possible. In a way, you're correcting the stock before anyone else does because of information symmetry. So you might ask, what's secret sauce? Well, you can look at analyst reports for a start, inside information is another, fast news (be it true or false), arbitrary equation and indicators, and last but not least: reasoning.

You're almost there. Now you just need market traction (saturation), mob psychology, algo building orders based on other algos, etc.
My algo tries to involve a custom data set and set out to correct stocks before traction sets in. Just don't ask me where I get the data.
====> My algo is an intraday strategy that does not forward-fill the universe; so any stocks you specify for a certain day will be unique to that day. Repeats are allowed as long as the new date has the same stock.

The strategy is extremely time sensitive, so it's based on real trading (although I've just been running backtests).

Intended steps of operation:
1.) fetch csv file/import data/populate universe
2.) approach first day of event
3.) populate stock universe of that date
4.) open long/short only 20% of the account (long if score is 1, short if score is -1)
5.) close long/short when stop loss/gain percentages reached
6.) exit all positions at the end of the day


But it has some bugs, for example, it sometimes doesn't place the appropriate order; the strategy will trade a long even if the score is a -1 seeking for a short.
Sometimes positions will close but another will be opened at the end of the day (which is closed the next day, this introduced gaps and gaps are bad). If there are conflicting scores for a single time stamp, the first one should always be executed, but sometimes this isn't the case.

Take a look, it's interesting to say the least.
- John Luo

Special thanks:
I must give credit to Alisa, Gus, and James, and countless others at Quantopian and regular members for contributing to this code (I've read so many posts).
James helped refactor a lot of the code. I took code written by Quantopian engineers straight from their posts, and also many ideas generated by any discussions I read. Thank you Quantopian for enabling us the people!

Clone Algorithm
Backtest from to with initial capital
Total Returns
Max Drawdown
Benchmark Returns
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
import pandas as pd
import datetime

def initialize(context):
    schedule_function(close_all_positions, date_rules.every_day(), time_rules.market_close())
def my_universe(context, fetcher_data):
    my_stocks = set(fetcher_data['sid'])
    context.count = len(my_stocks)
    #print 'total universe size: {c}'.format(c=context.count)
    return my_stocks

def preview(df):
    #' %s ' % df.head())
    fdates = list(pd.DatetimeIndex(df['date'].values))
    idx = pd.date_range(fdates[0], fdates[-1] + datetime.timedelta(days=1))
    missing_dates = [x for x in idx if x not in fdates]
    for date in missing_dates:
        dr = {}
        dr['date'] = date.strftime('%m/%d/%y')
        dr['symbol'] = 'AAPL'
        dr['score'] = '0'
        row = pd.DataFrame([dr])
        df = pd.concat([df, row], ignore_index=True)
    return df

def handle_data(context, data):
    exchange_time = pd.Timestamp(get_datetime()).tz_convert('US/Eastern')
    hour = exchange_time.hour
    minute = exchange_time.minute
    cash =
    for stock in data:
        if has_orders(data):
                log.warn('has open orders - doing nothing!')
        if stock.symbol != 'AAPL':
            ############################################ OPEN
            if stock not in context.portfolio.positions:
                if data[stock]['dt'].date() == and data[stock]['hour'] == hour and data[stock]['minute'] == minute:
                    if 'price' in data[stock]:
                        ## Open Long
                        if data[stock]['score'] == 1:
                            weight = data[stock]['score']
                            price = data[stock].price
                            if cash > price:
                                order_target_percent(stock, weight*.2)
                                print "Longed %s at %s" % (stock.symbol, get_datetime().tz_convert('US/Eastern'))
                        ## Open Short        
                        elif data[stock]['score'] == -1:
                            weight = data[stock]['score']
                            price= data[stock].price
                            order_target_percent(stock, weight*.2)
                            print "Shorted %s at %s" % (stock.symbol, get_datetime().tz_convert('US/Eastern'))
                        elif data[stock]['score'] == 0:
                        log.warn("No price for {s}".format(s=stock))
            ############################################ CLOSE            
            elif stock in context.portfolio.positions:
                amount = context.portfolio.positions[stock].amount
                orig_price = context.portfolio.positions[stock].cost_basis
                price = data[stock].price
                ## Closing Longs
                if amount > 0:
                    if price >= 1.01*orig_price:
                        order_target_percent(stock, 0)
              "closed (on gain) long of %s of %s at %s" % (str(amount), stock.symbol, get_datetime().tz_convert('US/Eastern')))
                    elif price <=.995*orig_price:
              "closed (on loss) long of %s of %s at %s" % (str(amount), stock.symbol, get_datetime().tz_convert('US/Eastern')))
                ## Closing Shorts        
                elif amount < 0:
                    if price <= .99*orig_price:
                        if cash > price:
                            order_target_percent(stock, 0)
                  "closed (on gain) short of %s of %s at %s" % (str(amount), stock.symbol, get_datetime().tz_convert('US/Eastern')))
                            log.warn("Not enough cash")
                    elif price >= 1.001*orig_price:
                        if cash > price:
                            order_target_percent(stock, 0)
                  "closed (on loss) short of %s of %s at %s" % (str(amount), stock.symbol, get_datetime().tz_convert('US/Eastern')))
                            log.warn("Not enough cash")
                elif amount == 0:
                # if hour == 15 and minute >= 58 and minute <= 59:
                #     cancel_everything()
                #     order_target_percent(stock, 0)
                #     print "closed %s of %s at %s" % (str(amount), stock.symbol, get_datetime().tz_convert('US/Eastern'))
def close_all_positions(context, data):
    for security in context.portfolio.positions:
        order_target_percent(security, 0)
        print "Closed %s of %s at %s" % (str(context.portfolio.positions[security].amount), security.symbol, get_datetime().tz_convert('US/Eastern'))
def has_orders(data):
    open_orders = get_open_orders()
    if open_orders:
        for sec in open_orders:  
            for oo in open_orders[sec]:
                message = 'Open order for {amount} shares in {stock}'  
                message = message.format(amount=oo.amount, stock=sec)  
        return True
    return False                  
def cancel_everything():
    Cancels all open orders for all sids.
    for security, oo_for_sid in get_open_orders().iteritems():
        for order_obj in oo_for_sid:
  "%s: Cancelling order for %s of %s created on %s" % (get_datetime(), order_obj.amount, security.symbol, order_obj.created))
There was a runtime error.