Back to Community
Need help for basic DOW 30 stock rotation strategy

I'm new to Quantopian and to Python, so am in need of assistance. I'm piecing this together from help documents and examples and am really stuck.

The goal is to have a monthly rotational strategy using just the Dow 30 stocks, using momentum of 3 and 12 month returns to rank them, and owning the top group equally of that rank.

Seems simple enough but can't get farther.

""" 1. Use the Dow 30 stocks
2. Find the top group of stocks with positive momentum with 3 and 12 month returns
3. Every month own the top group of stocks
4. Log the positions that we need
"""

import pandas as pd
import numpy as np

def initialize(context):
# Dictionary of stocks and their respective weights
context.stock_weights = {}
# Count of days before rebalancing
context.days = 0
# Number of stocks to go long in
context.stock_numb = 7

set_symbol_lookup_date('2015-01-01')  
# DJI 30 stocks from March 19 2015 - now  
context.stocks = symbols('MMM', 'AXP', 'AAPL', 'BA', 'CAT', 'CVX', 'CSCO', 'KO', 'DD', 'XOM', 'GE', 'GS', 'HD', 'INTC', 'IBM', 'JNJ', 'JPM', 'MCD', 'MRK', 'MSFT', 'NKE', 'PFE', 'PG', 'TRV', 'UNH', 'UTX', 'VZ', 'V', 'WMT', 'DIS')  

# Rebalance monthly on the first day of the month at market open  
schedule_function(rebalance,  
                  date_rule=date_rules.month_start(),  
                  time_rule=time_rules.market_open())  

def rebalance(context, data):
# Exit all positions before starting new ones
for stock in context.portfolio.positions:
if stock in data:
order_target_percent(stock, 0)

log.info("The stocks we are ordering today are %r" % context.stocks)

# Create weights for each stock  
weight = create_weights(context, context.stocks)

# Rebalance all stocks to target weights  
for stock in context.stocks:  
    if stock in data:  
      if weight != 0:  
          log.info("Ordering %0.0f%% percent of %s in %s"  
                   % (weight * 100,  
                      stock.symbol, )  

      order_target_percent(stock, weight)  

def before_trading_start(context):
# Sort in ascending order
sectors = sorted(sector_pe_dict, key=lambda x: sector_pe_dict[x], reverse=True)[:context.sect_numb]

# Filter out only stocks with that particular sector  
context.stocks = [stock for stock in fundamental_df  
                  if fundamental_df[stock]['morningstar_sector_code'] in sectors]  

# Initialize a context.sectors variable  
context.sectors = [context.sector_mappings[sect] for sect in sectors]

# Update context.fundamental_df with the securities (and pe_ratio) that we need  
context.fundamental_df = fundamental_df[context.stocks]  

def create_weights(context, stocks):
"""
Takes in a list of securities and weights them all equally
"""
if len(stocks) == 0:
return 0
else:
weight = 1.0/len(stocks)
return weight

def handle_data(context, data):
"""
Code logic to run during the trading day.
handle_data() gets called every bar.
"""

# track how many positions we're holding  
record(num_positions = len(context.portfolio.positions))

Thoughts?

thanks!

2 responses

Never mind the code the theory is flawed if you use just those stocks in the index at the present day.

Hi Anthony,

I don't think the theory is flawed, let me explain a little more and perhaps you can help me understand why you think it is.

I'm using the DOW as my fundamental filter, then using momentum to rank them, and later add a hedge of some kind.

My plan is to not own the worse performing group of the dow, and in theory that should outperform the DOW most of the time. Since quantopian cannot handle different groups of stocks with specific timeframes in the same backtest (not from what I could find in the help) , then I plan on creating a backtest for each time the DOW components change. If you look at my comment at the symbol list this is only from March 19 - current. So going back to 2002 I'll be duplicating the algo and just changing the components and the start/end time for the backtest to account for each component change.

thoughts?