Back to Community
DIA Trend Within Trend

I fixed an issue with the stop and I think its in better shape.

A question, is the way that I set up how I set and update stops good or is there a better way to do it?

Clone Algorithm
66
Loading...
Backtest from to with initial capital
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
# based off of rules from
# http://bigpicture.typepad.com/comments/files/turtlerules.pdf

# uses ETFs:
# http://etfdb.com/type/commodity/exposure/futures-based/no-leveraged/

# this is just a start, there additional rules that haven't yet been implemented

from collections import deque
import math

atr = ta.ATR(timeperiod=20) # used to calculate 20-period ATR

def initialize(context):
    
    # you can find other tickers at that ETF page above
    context.securities = [
                              sid(2174), # spider DIA
                              sid(4922), # MMM 3M
                              sid(6653), # T AT&T Inc
                              sid(679), # AXP American Express Co
                              sid(698), # BA Boeing Co
                              sid(1267), # CAT Caterpillar Inc
                              sid(23112), # CVX Chevron Corp
                              sid(1900), # CSCO Cisco Systems Inc
                              sid(2119), # DD Dupont E I De Nemours & Co
                              sid(8347), # XOM Exxon Mobil Corp
                              sid(3149), # GE General Electric Co
                              sid(20088), # GS Goldman Sachs Group Inc
                              sid(3496), # HD Home Depot Inc
                              sid(3951), # INTC Intel Corp
                              sid(3766), # IBM International Business Machines
                              sid(4151), # JNJ Johnson & Johnson
                              sid(25006), # JPM JPMorgan Chase and Co
                              sid(4707), # MCD McDonald's Corp
                              sid(5029), # MRK Merck & Co Inc
                              sid(5061), # MSFT Microsoft Corp
                              sid(5328), # NKE Nike Inc
                              sid(5923), # PFE Pfizer Inc
                              sid(5938), # PG Procter & Gamble Co
                              sid(4283), # KO The Coca-Cola Co
                              sid(7041), # TRV Travelers Companies Inc
                              sid(7883), # UTX United Technologies Corp
                              sid(7792), # UNH UnitedHealth Group Inc
                              sid(21839), # VZ Verizon Communications Inc
                              sid(35920), # V Visa Inc
                              sid(8229), # WMT Wal-Mart Stores Inc
                              sid(2190), # DIS Walt Disney Co
                        ]
    
    # define dict for various security values like prices, N and pyramids
    context.security_prices = dict()
    context.security_buyPrice = dict()
    context.security_direction = dict()
    context.security_N = dict()
    context.security_pyramids = dict()

    for security in context.securities:
        if security is not sid(2174):
            context.security_prices[security] = []
            context.security_buyPrice[security] = 0
            context.security_direction[security] = 0
            context.security_N[security] = 0
            context.security_pyramids[security] = 0

    # define list for dia prices
    context.dia_prices = []    
    
def addNewPrice(priceList, newPrice, pricesToKeep):
    try:
        priceList.append(newPrice)
        
        if len(priceList) > pricesToKeep:
            return priceList[1:pricesToKeep+1]
        else:
            return priceList
    except:
        return priceList

def securityHasOrders(context, security):
    if len(get_open_orders(security)) == 0:
        context.security_buyPrice[security] = 0
        context.security_direction[security] = 0
        context.security_N[security] = 0
        context.security_pyramids[security] = 0
        return False
    else:
        return True

def orderSecurity(context, data, security):
    N = context.security_N[security]
    stop = data[security].price - (context.security_direction[security]*2*N)
    trade_amt = math.ceil(context.portfolio.portfolio_value*.02/N)
    order_shares = (context.security_direction[security]*trade_amt)/data[security].price

    #loop through the current orders and update the stop
    for o in get_open_orders(security):
        log.info("updating security %s stop from %s to %s for direction %s" % (security.symbol, o.stop, stop, context.security_direction[security]))
        o.stop = stop
        
    log.info("ordering %s shares of %s at price %s with a stop of %s" % (order_shares, security.symbol, data[security].price, stop))

    order(security, order_shares, stop_price=stop)
    context.security_pyramids[security] += 1

def handle_data(context, data):
    #constant trend lengths
    diaLength = 10
    securityLength = 20
    maxPyramids = 6
    percentCash = context.portfolio.cash/(context.portfolio.cash + context.portfolio.positions_value)

    diaTrendDirection = 0

    # for each security in the list        
    for security in context.securities:
        if security not in data or data[security] is None or data[security].price is None:
            continue

        if security is sid(2174):
            context.dia_prices = addNewPrice(context.dia_prices, data[security].price, diaLength)
            
            #is high
            if data[security].price >= max(context.dia_prices):
                diaTrendDirection = 1
            #is low
            elif data[security].price <= min(context.dia_prices):
                diaTrendDirection = -1
            else:
                diaTrendDirection = 0
        
        else:
            context.security_prices[security] = addNewPrice(context.security_prices[security], data[security].price, securityLength)

            if percentCash > 0.1:
                if securityHasOrders(context, security) and (context.security_pyramids[security] < maxPyramids):
                    pyramidPrice = context.security_buyPrice[security] + (context.security_N[security] * context.security_pyramids[security])

                    #buying scenario where the direction of the price and the pyramid price are correct
                    if (context.security_direction[security] > 0 and data[security].price >= pyramidPrice) or (context.security_direction[security] < 0 and data[security].price <= pyramidPrice):
                         orderSecurity(context, data, security)

                else:   
                    if math.isnan(atr(data)[security]) is False and atr(data)[security] > 0:
                        securityTrendDirection = 0
                        # is high
                        if data[security].price >= max(context.security_prices[security]):
                            securityTrendDirection = 1
                        # is low
                        elif data[security].price <= min(context.security_prices[security]):
                            securityTrendDirection = -1

                        if (securityTrendDirection > 0 and diaTrendDirection > 0) or (securityTrendDirection < 0 and diaTrendDirection < 0):
                            # long
                            context.security_N[security] = atr(data)[security]
                            context.security_buyPrice[security] = data[security].price
                            context.security_direction[security] = securityTrendDirection
                            orderSecurity(context, data, security)
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.
1 response

I'm sorry, this is my first post and added this backtest incorrectly. Please see the original version that now includes this backtest.

https://www.quantopian.com/posts/dia-trend-within-trend