Does anyone know how to combine the following two strategies into one algo (with adjustable weights for each)? Is this even possible?
The pasted code contains the two algos I want to combine, and the attached backtest is of a multi-strategy example taken from the forums.
I tried modeling a new algo base on the multi-strategy example, but I was unable to produce anything that would trade properly.
I know this is a rather complex problem, but I'd love to hear what you guys think. Thanks for any help in advance!
Paired Switching Algo:
import math
import pandas
def initialize(context):
context.stocks = {
3921: sid(23921), #20 Year T Bond
12915: sid(12915), #MDY (SPY Midcap)
24705: sid(24705), #EEM (Emerging Markets)
}
#number of stocks to buy
context.buy_count = 1
context.buy_percent = 1.45/context.buy_count
# Date of last rebalancing
context.rebalancing_date = None
# Rebalancing period in calendar days
context.period = 31
# The order ID of the sell order currently being filled
context.oid = None
# The next stock that needs to get purchased (once the sell order
# on the current stock is filled
context.next_stocks = []
# The 3-month lookback period. Calculated based on there being
# an average of 21 trading days in a month
context.lookback = 63
def getbeststock(prices, context):
#gets rolling 60 day return
pct_change = prices.pct_change()
rolling_returns = pandas.rolling_apply((1+pct_change),context.lookback,lambda x : x.prod())-1
#get last 60 day return
returns_last = rolling_returns.iloc[-1]
#gets percentile return... essentially distributing returns between 0 and 1
returns_rank = returns_last.rank(pct=True)
#sorts by returns rank
returns_rank.sort()
return returns_rank.index[-context.buy_count:] #Returns highest stocks
def sellholdings(context):
"""Sell all the currently held positions in the context's portfolio."""
positions = context.portfolio.positions
for pos in positions.values():
log.info('Selling shares of %s' % (pos.sid.symbol))
order_target_percent(pos.sid,0)
def handle_data(context, data):
prices = history(84, '1d', 'price')
prices = prices.dropna(axis=1)
current_date = pandas.Period(get_datetime(),freq='D')
if len(context.next_stocks) > 0 :
if not get_open_orders():
for stock in context.next_stocks:
mavg_50 = data[stock].mavg(50)
mavg_200 = data[stock].mavg(200)
if mavg_50 > mavg_200:
order_target_percent(stock,context.buy_percent)
log.info(("Purchased shares of %s") % stock.symbol)
context.next_stocks = []
context.rebalancing_date = current_date
else:
print "mavg_50 was below mavg_200 for %s" % stock.symbol
print context.portfolio.positions
if context.rebalancing_date is None or current_date >= context.rebalancing_date + context.period:
# Determine which stocks should be used for the next month
best = getbeststock(prices, context)
if len(best)>0:
sellholdings(context)
context.next_stocks = best
else:
return #do nothing
record(Leverage = context.account.leverage)
Seasonal Algo:
def initialize(context):
context.tlt = sid(23921)
context.qqq = sid(19920)
context.monthly_ports = { 1: {context.tlt: 1.0, context.qqq: 0.0},
2: {context.tlt: 1.0, context.qqq: 0.0},
3: {context.qqq: 1.0, context.tlt: 0.0},
4: {context.qqq: 1.0, context.tlt: 0.0},
5: {context.tlt: 1.0, context.qqq: 0.0},
6: {context.tlt: 1.0, context.qqq: 0.0},
7: {context.tlt: 1.0, context.qqq: 0.0},
8: {context.tlt: 1.0, context.qqq: 0.0},
9: {context.tlt: 1.0, context.qqq: 0.0},
10: {context.qqq: 1.0, context.tlt: 0.0},
11: {context.qqq: 1.0, context.tlt: 0.0},
12: {context.qqq: 1.0, context.tlt: 0.0}
}
schedule_function(func=do_allocation,
date_rule=date_rules.month_start(days_offset=1),
time_rule=time_rules.market_open(),
half_days=True
)
def handle_data(context, data):
record(qqq=context.portfolio.positions[context.qqq].amount)
record(tlt=context.portfolio.positions[context.tlt].amount)
record(Leverage = context.account.leverage)
def do_allocation(context, data):
month = get_datetime().month
port = context.monthly_ports[month]
for (sid, weight) in port.iteritems():
if sid in data:
order_target_percent(sid, weight)
Attached backtest of a multi-strategy example from a different Q thread (thanks @Peter Bakker):