@Jacob,
Thanks for the compliments.
Here is my version of what you are trying to do.
First I replaced 4 Vanguard ETFs with similar ones with a longer history.
Changed the start date to 01-01-2005.
Added BOND = symbol('IEF') to be in position when all ASSETS are in downtrend.
For ALL WHETER portfolio may be sufficient annual rebalancing, but as you added a tactical element (momentum) to my mind,
it should be rebalanced more often.
Therefore, I set up a quarterly rebalancing.
# Tactical rebalancing of All Weather Portfolio by Vladimir
# --------------------------------------------------------------------------------------------
ASSETS = symbols('VTI', 'EEM', 'TLT', 'IYR', 'GLD'); WEIGHTS = [0.40, 0.20, 0.30, 0.05, 0.05]
BOND = symbol('IEF'); MA_F = 20; MA_S = 120; LEV = 1.0; MONTHES = [1, 4, 7, 10]
# --------------------------------------------------------------------------------------------
def initialize(context):
schedule_function(rebalance, date_rules.month_start(), time_rules.market_open(minutes = 65))
def rebalance(context, data):
if get_datetime().month not in MONTHES or get_open_orders(): return
sma_f = data.history(ASSETS, 'price', MA_F, '1d').mean()
sma_s = data.history(ASSETS, 'price', MA_S, '1d').mean()
picks = sma_f[ sma_f > sma_s ].index
weights = {}; adj_weights = {}; denom = 0;
for i, sec in enumerate(ASSETS):
if data.can_trade(sec) and sec in picks: weights[sec] = WEIGHTS[i]; denom += WEIGHTS[i]
else: weights[sec] = 0.0
for sec in weights:
if sec in picks: adj_weights[sec] = weights[sec]/denom
else: adj_weights[sec] = 0.0
adj_weights[BOND] = 0 if len(picks) > 0 else LEV
for sec, wt in adj_weights.items(): order_target_percent(sec, LEV*wt)
def before_trading_start(context, data):
record(leverage = context.account.leverage, pos_count = len(context.portfolio.positions))