Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Dual Moving Average Crossing

Hello,

I'm a complete newbie, so please excuse my beginner's question.

I'm trying to implement the Dual Moving Average Crossing Trend-Following Method on Quantopian. I've got this code:

def initialize(context):  
    # Define which stocks we want to work with. I'm starting with just one, but you can add up to 10.  
    context.sids = [sid(24)]  
    context.N = len(context.sids)

    # This section initializes a dictionary that will later track whether we invested in a particular stock  
    context.invested = {}  
    for cur_sid in context.sids:  
        context.invested[cur_sid] = False  
def handle_data(context, data):  
    # Uncomment the line below if you want to log the sids that you're testing. Be careful, it's a lot of  
    # log lines if you're doing a full backtest!  
    # log.info(data.keys())  
    # allocate part of our portfolio for each sid in our list  
    cash_per_sid = context.portfolio.starting_cash / context.N  
    # This loop goes over the specified sids  
    for cur_sid in context.sids:  
        # skip sids that have no data (like Facebook pre-IPO)  
        if not (cur_sid) in data:  
            continue  
        # buy if short moving average crossed long moving average going up  
        if (data[cur_sid].mavg(10) > data[cur_sid].mavg(50)) and not context.invested[cur_sid]:  
            order_in_cash(data, cur_sid, cash_per_sid)  
            context.invested[cur_sid] = True  
        # sell if short moving average crossed long moving average going down  
        elif (data[cur_sid].mavg(10) < data[cur_sid].mavg(50)) and context.invested[cur_sid]:  
            # log the fact that we're closing our position, and the conditions that triggered it  
            log.info('Selling SID %i by %i shares. mavg(10) is %i, mavg(50) is %i' %(cur_sid, context.portfolio.positions[cur_sid].amount, data[cur_sid].mavg(10), data[cur_sid].mavg(50)))  
            # sell the amount we invested  
            order(cur_sid, -context.portfolio.positions[cur_sid].amount)  
            context.invested[cur_sid] = False  
def order_in_cash(data, security, cash):  
    # This function calculates how many shares to buy given the price and cash available  
    shares = cash // data[security].price  
    # log.debug("security: %i, cash: %f, shares: %i"% (security, cash, shares))  
    if shares < 0:  
        shares += 1  
    # to fix python's flooring of negative integer division.  
    # log the fact that we're going long, and the conditions that triggered it  
    log.info('Ordering %i shares of sid %i. mavg(10) is %i, mavg(50) is %i' %(shares, security, data[security].mavg(10), data[security].mavg(50)))  
    order(security, shares)  

The code works, but when the short MA goes below the long MA, the position is just eliminated, but I would like to initiate a short position. How do I do that?

Kind regards
Florian

1 response

Florian,

Try this:

# MAC 10-50

def initialize(context):  
    schedule_function(trade, date_rules.every_day(), time_rules.market_close(minutes = 60))

def trade(context, data):  
    stock = symbol('AAPL')  
    if get_open_orders(): return

    mavg_fast = data.history(stock, 'price',  10, '1d').mean()  
    mavg_slow = data.history(stock, 'price',  50, '1d').mean()  

    if data.can_trade(stock):  
        if mavg_fast > mavg_slow:  
            order_target_percent(stock, 1.0)  
        elif mavg_fast < mavg_slow:  
            order_target_percent(stock, -1.0)  

Make sure that long-short version of the strategy will be less productive and more volatile than long-exit version.