Back to Community
EMA 50 vs 100

More or less, if the 50 day EMA drops below the 100 day EMA, sell. If it goes above, buy.
Uses a mix of 14 stocks that's a bit tech heavy so it uses QQQ as a benchmark.
For a better benchmark I'm going to re-run it with just buying the stock and holding the whole time.

Seems to miss out on sudden surges quite often.

Clone Algorithm
152
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
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 talib

def initialize(context):
    set_symbol_lookup_date('2003-01-01')
    context.stocks = symbols('atvi','csco','cvx','ea','ebay','hpq','ibm','intc','msft','nvda','cog', 'bp', 'ste', 'xom')
    set_benchmark(symbol('qqq'))
    context.dayCount = 0
    context.date = None
    context.shorts = 0
    context.cancelCounter=0
    
def handle_data(context, data):  
    
    todays_date = get_datetime().date()
    
    if todays_date==context.date:
        return
    
    if todays_date!=context.date:
        context.dayCount+=1
        context.cancelCounter+=1
        context.date = todays_date
        
    if context.cancelCounter==5:
        end_of_day(context, data)
        context.cancelCounter=0
        
    if has_orders(context,data) and context.dayCount>1:
        print('has open orders - doing nothing!')
        return
    
    if context.dayCount == 1:
        buyAll(context,data)
    
    for stock in context.stocks:
        
        hist100 = history(bar_count=100, frequency='1d', field='price')
        series100 = hist100[stock]
        ema_result100 = talib.EMA(series100, timeperiod=100)
        ema_result50 = talib.EMA(series100, timeperiod=50)
        ema100 = ema_result100[-1]
        ema50 = ema_result50[-1]        
            
        getCash(context,data)
            
        if ema100 > ema50 and context.portfolio.positions[stock].amount > 0 and context.dayCount>2:
            log.info('{0}:  Selling {1} shares, EMA50:  {2}, EMA100:  {3}'.format(stock.symbol,context.portfolio.positions[stock].amount,ema50,ema100))
            order_target(stock, 0, style=LimitOrder(ema50))            
        
        if has_orders(context,data) and context.dayCount>7:
            print('has open orders - doing nothing!')
            return
            
        elif ema100 < ema50 and context.portfolio.positions[stock].amount == 0 and context.dayCount>2 and data[stock].price<context.freeCash:
            getCash(context,data)
            shares = round((context.freeCash*0.95)/data[stock].price,0)
            log.info('{0}:  Buying {1} shares, EMA50:  {2}, EMA100:  {3}'.format(stock.symbol,shares,ema50,ema100))
            order_target(stock, shares, style=LimitOrder(ema50))
            
        getCash(context,data)
            
        if context.portfolio.positions[stock].amount < 0:
            context.shorts+=1
    
    getCash(context,data)        
    record(Cash=context.freeCash)
    record(Shorts=context.shorts)
    context.shorts=0   
        
def has_orders(context,data):
    # Return true if there are pending orders.
    has_orders = False
    for sec in data:
        orders = get_open_orders(sec)
        if orders:
            for oo in orders:                  
                message = 'Open order for {amount} shares in {stock}'  
                message = message.format(amount=oo.amount, stock=sec)  
                log.info(message)

            has_orders = True
    return has_orders
    
def getCash(context,data):
    if context.portfolio.cash < (context.portfolio.portfolio_value-context.portfolio.positions_value):
        context.freeCash = context.portfolio.cash
    else:
        context.freeCash = (context.portfolio.portfolio_value-context.portfolio.positions_value)
    
def end_of_day(context, data):
    #cancle any order at the end of day. Do it ourselves so we can see slow moving stocks.
    open_orders = get_open_orders()
    
    if open_orders:
        
        log.info("")
        log.info("* EOD: Stoping Orders *")
        log.info("")
    
    if open_orders:  
        
        for security, orders in open_orders.iteritems():
            for oo in orders:
                log.info("X CANCLED {0:s} with {1:,d} / {2:,d} filled"\
                                     .format(security.symbol,
                                             oo.filled,
                                             oo.amount))
                cancel_order(oo)

def buyAll(context,data):
    for stock in context.stocks:
        order_value(stock, 1000)
        log.info('{0}:  Buying {1}shares'.format(stock.symbol,round(1000/data[stock].price,0)))
There was a runtime error.
6 responses

Here's the real benchmark. Performs initial purchase then sits on it.

Clone Algorithm
152
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
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 talib

def initialize(context):
    set_symbol_lookup_date('2003-01-01')
    context.stocks = symbols('atvi','csco','cvx','ea','ebay','hpq','ibm','intc','msft','nvda','cog', 'bp', 'ste', 'xom')
    set_benchmark(symbol('qqq'))
    context.dayCount = 0
    context.date = None
    context.shorts = 0
    context.cancelCounter=0
    
def handle_data(context, data):  
    
    todays_date = get_datetime().date()
    
    if todays_date==context.date:
        return
    
    if todays_date!=context.date:
        context.dayCount+=1
        context.cancelCounter+=1
        context.date = todays_date
        
    if context.cancelCounter==5:
        end_of_day(context, data)
        context.cancelCounter=0
        
    if has_orders(context,data) and context.dayCount>1:
        print('has open orders - doing nothing!')
        return
    
    if context.dayCount == 1:
        buyAll(context,data)
    
#    for stock in context.stocks:
#        
#        hist100 = history(bar_count=100, frequency='1d', field='price')
#        series100 = hist100[stock]
#        ema_result100 = talib.EMA(series100, timeperiod=100)
#        ema_result50 = talib.EMA(series100, timeperiod=50)
#        ema100 = ema_result100[-1]
#        ema50 = ema_result50[-1]        
#            
#        getCash(context,data)
#            
#        if ema100 > ema50 and context.portfolio.positions[stock].amount > 0 and #context.dayCount>2:
#            log.info('{0}:  Selling {1} shares, EMA50:  {2}, EMA100:  {3}'.format(stock.symbol,context.portfolio.positions[stock].amount,ema50,ema100))
#            order_target(stock, 0, style=LimitOrder(ema50))            
#        
#        if has_orders(context,data) and context.dayCount>7:
#            print('has open orders - doing nothing!')
#            return
#            
#        elif ema100 < ema50 and context.portfolio.positions[stock].amount == 0 and context.dayCount>2 and data[stock].price<context.freeCash:
#            getCash(context,data)
#            shares = round((context.freeCash*0.95)/data[stock].price,0)
#            log.info('{0}:  Buying {1} shares, EMA50:  {2}, EMA100:  {3}'.format(stock.symbol,shares,ema50,ema100))
#            order_target(stock, shares, style=LimitOrder(ema50))
#            
#        getCash(context,data)
#            
#        if context.portfolio.positions[stock].amount < 0:
#            context.shorts+=1
#    
#    getCash(context,data)        
#    record(Cash=context.freeCash)
#    record(Shorts=context.shorts)
#    context.shorts=0   
        
def has_orders(context,data):
    # Return true if there are pending orders.
    has_orders = False
    for sec in data:
        orders = get_open_orders(sec)
        if orders:
            for oo in orders:                  
                message = 'Open order for {amount} shares in {stock}'  
                message = message.format(amount=oo.amount, stock=sec)  
                log.info(message)

            has_orders = True
    return has_orders
    
def getCash(context,data):
    if context.portfolio.cash < (context.portfolio.portfolio_value-context.portfolio.positions_value):
        context.freeCash = context.portfolio.cash
    else:
        context.freeCash = (context.portfolio.portfolio_value-context.portfolio.positions_value)
    
def end_of_day(context, data):
    #cancle any order at the end of day. Do it ourselves so we can see slow moving stocks.
    open_orders = get_open_orders()
    
    if open_orders:
        
        log.info("")
        log.info("* EOD: Stoping Orders *")
        log.info("")
    
    if open_orders:  
        
        for security, orders in open_orders.iteritems():
            for oo in orders:
                log.info("X CANCLED {0:s} with {1:,d} / {2:,d} filled"\
                                     .format(security.symbol,
                                             oo.filled,
                                             oo.amount))
                cancel_order(oo)

def buyAll(context,data):
    for stock in context.stocks:
        order_value(stock, 1000)
        log.info('{0}:  Buying {1}shares'.format(stock.symbol,round(1000/data[stock].price,0)))
There was a runtime error.

Nice! Comparing those 2 is not accurate though, as I don't see that you've accounted for broking fees. At a guess, the first script will have more buy/sells than the second, which is buy and hold only. I think there are other examples of how to add in fees and costs to the mix. Well done! Looking forward to seeing your next one :-)

I believe since I didn't set a custom commission it uses $0.03/share as a default rate.So the first one definitely got hit with more since its the only one with any activity. I'll try it again with commission set to $4.75/trade.

How did your algo perform after setting the the commission to the higher commission of $4.75/trade?

Not much change.

Clone Algorithm
152
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
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 talib

def initialize(context):
    set_symbol_lookup_date('2003-01-01')
    context.stocks = symbols('atvi','csco','cvx','ea','ebay','hpq','ibm','intc','msft','nvda','cog', 'bp', 'ste', 'xom')
    set_benchmark(symbol('qqq'))
    set_commission(commission.PerTrade(cost=4.75))
    context.dayCount = 0
    context.date = None
    context.shorts = 0
    context.cancelCounter=0
    
def handle_data(context, data):  
    
    todays_date = get_datetime().date()
    
    if todays_date==context.date:
        return
    
    if todays_date!=context.date:
        context.dayCount+=1
        context.cancelCounter+=1
        context.date = todays_date
        
    if context.cancelCounter==5:
        end_of_day(context, data)
        context.cancelCounter=0
        
    if has_orders(context,data) and context.dayCount>1:
        print('has open orders - doing nothing!')
        return
    
    if context.dayCount == 1:
        buyAll(context,data)
    
    for stock in context.stocks:
        
        hist100 = history(bar_count=100, frequency='1d', field='price')
        series100 = hist100[stock]
        ema_result100 = talib.EMA(series100, timeperiod=100)
        ema_result50 = talib.EMA(series100, timeperiod=50)
        ema100 = ema_result100[-1]
        ema50 = ema_result50[-1]        
            
        getCash(context,data)
            
        if ema100 > ema50 and context.portfolio.positions[stock].amount > 0 and context.dayCount>2:
            log.info('{0}:  Selling {1} shares, EMA50:  {2}, EMA100:  {3}'.format(stock.symbol,context.portfolio.positions[stock].amount,ema50,ema100))
            order_target(stock, 0, style=LimitOrder(ema50))            
        
        if has_orders(context,data) and context.dayCount>7:
            print('has open orders - doing nothing!')
            return
            
        elif ema100 < ema50 and context.portfolio.positions[stock].amount == 0 and context.dayCount>2 and data[stock].price<context.freeCash:
            getCash(context,data)
            shares = round((context.freeCash*0.95)/data[stock].price,0)
            log.info('{0}:  Buying {1} shares, EMA50:  {2}, EMA100:  {3}'.format(stock.symbol,shares,ema50,ema100))
            order_target(stock, shares, style=LimitOrder(ema50))
            
        getCash(context,data)
            
        if context.portfolio.positions[stock].amount < 0:
            context.shorts+=1
    
    getCash(context,data)        
    record(Cash=context.freeCash)
    record(Shorts=context.shorts)
    context.shorts=0   
        
def has_orders(context,data):
    # Return true if there are pending orders.
    has_orders = False
    for sec in data:
        orders = get_open_orders(sec)
        if orders:
            for oo in orders:                  
                message = 'Open order for {amount} shares in {stock}'  
                message = message.format(amount=oo.amount, stock=sec)  
                log.info(message)

            has_orders = True
    return has_orders
    
def getCash(context,data):
    if context.portfolio.cash < (context.portfolio.portfolio_value-context.portfolio.positions_value):
        context.freeCash = context.portfolio.cash-5
    else:
        context.freeCash = (context.portfolio.portfolio_value-context.portfolio.positions_value)-5
    
def end_of_day(context, data):
    #cancle any order at the end of day. Do it ourselves so we can see slow moving stocks.
    open_orders = get_open_orders()
    
    if open_orders:
        
        log.info("")
        log.info("* EOD: Stoping Orders *")
        log.info("")
    
    if open_orders:  
        
        for security, orders in open_orders.iteritems():
            for oo in orders:
                log.info("X CANCLED {0:s} with {1:,d} / {2:,d} filled"\
                                     .format(security.symbol,
                                             oo.filled,
                                             oo.amount))
                cancel_order(oo)

def buyAll(context,data):
    for stock in context.stocks:
        order_value(stock, 1000)
        log.info('{0}:  Buying {1}shares'.format(stock.symbol,round(1000/data[stock].price,0)))
There was a runtime error.

it doesnt work......