Back to Community
Rebalancing less frequently than 1 month (HELP)

Hi,

how can I do my rebalancing less frequently than 1 month (e.g. yearly)? For now I've tried to do it like this in before_trading_start:

def before_trading_start(context, data):  
    now = get_datetime('US/Eastern')  
    if now.month==rebalancing_month:  
        pass  
    else:  
        return  

Thanks for help.

5 responses

maybe it's not an elegant solution, but i usually do it with a simple counter:, for example to trade every 3 months:

def initialize(context):  
    context.counter = 0  
    schedule_function(  
    trade,  
    date_rules.month_end(),  
    time_rules.market_open(minutes=15))  
def trade(context, data):  
    context.counter += 1  
    if context.counter == 3:  
        trade()  
    cotext.counter = 0  

Could you send some specific working example?

shure, as you can see in the logs the trade function runs every 3 months

Clone Algorithm
18
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
import numpy as np
import pandas as pd


def initialize(context):
    context.counter = 0
    '''
    schedule_function(
    start_dates_check,
    date_rules.every_day(),
    time_rules.market_open())
    '''
    
    schedule_function(
    rebalance,
    date_rules.month_end(),
    time_rules.market_open(minutes=15))
    
    schedule_function(
    plots,
    date_rules.every_day(),
    time_rules.market_close(minutes=1))

    context.equities = [
                    sid(26669), # VNQ Vanguard REIT
                    sid(19656), # XLF Financial
                    sid(19661), # XLV Healt Care
                    sid(19658), # XLK Technology
                    sid(19655), # XLE Energy
                    sid(19662), # XLY Consumer Discretionary
                    sid(19659), # XLP Consumer Staples
                    sid(19660), # XLU Utilities
                    sid(19657) # XLI Industrial
                  ]


    context.s = context.equities    
    


def rebalance(context, data):
    context.counter += 1
    if context.counter == 3:
        trade(context, data)
        context.counter = 0
    else:
        pass

            
def trade(context, data):
    print 'REBALANCE'
    context.buys = []
    context.shorts = []
    
    ################################
    # SELECTION CRITERIA
    ################################
    
    for s in context.s:
        
        px = data[s].close_price
        mavg = data[s].mavg(200)
        if px >= mavg:
            context.buys.append(s)
        else:
            context.shorts.append(s)
    oo = get_open_orders()
    
    longs = context.buys
    shorts = context.shorts
    
    to_trade = longs + shorts
    if len(longs) == 0:
        w_s = .95/len(shorts)
    elif len(shorts) == 0:
        w_l = .95/len(longs)
    else:
        w_l  =.5/len(longs)
        w_s = .5/len(shorts)
        
    ################################
    # ORDERS
    ################################
    for s in context.s:
        if s in oo.keys():
            continue
        elif s in longs:
            order_target_percent(s, w_l)
        elif s in shorts: 
            order_target_percent(s, -w_s)
        elif s not in to_trade and context.portfolio.positions[s].amount != 0:
            order_target(s, 0)
    context.counter = 0

def plots(context, data):
    longs = [s for s in context.s if context.portfolio.positions[s].amount > 0.0]
    shorts = [s for s in context.s if context.portfolio.positions[s].amount < 0.0]
    record(
           exposure=context.account.net_leverage, 
           leverage=context.account.leverage,
           longs = len(longs),
           shorts = len(shorts))
            
def handle_data(context, data):
    pass

             
def start_dates_check(context, data):
    for s in context.s:
        if s.start_date.tz_convert(None) > context.backtest_start_date:
            print 'symbol {0} have not enough lookback data.\nStart date for {0} is {1}'.format(s.symbol, s.start_date)             
             
             
             
There was a runtime error.

Sanning

Try this example.

Clone Algorithm
28
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
# Plain vanilla fixed ratio stock-bond portfolio rebalanced quarterly

def initialize(context):    
    context.assets = [symbol('XLP'), symbol('TLT')]   
    context.weights = {context.assets[0]: 0.55, context.assets[1]: 0.45} 
    context.counter = 0
    schedule_function(rebalance,date_rules.month_end(),time_rules.market_close(minutes=5))   
 
def rebalance(context, data):
    freq_month = 3
    context.counter += 1  
    if context.counter == freq_month:  
        trade(context, data) 
        context.counter = 0       
    
def trade(context, data):
    for asset in context.assets:
        if get_open_orders(asset): return
        order_target_percent(asset, context.weights[asset])
        
def handle_data(context, data):    
    record(leverage = context.account.leverage)        
There was a runtime error.

Add the following to 'my_rebalance' function:

def my_rebalance(context,data):
# Schedule our rebalance function to run at the start of each quarter.
today = get_datetime('US/Eastern')
if today.month in [1,4,7,10]: #rebalance quarterly
your_rebalance_method

You can customize the frequency in 'today.month in [frequency]'.