Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Rebalancing in Real-money Live-Trading: first sell and then buy or the other way round?

I found two ways of doing rebalancing. One straightforward way is:

for stock in data:  
        order_target_percent(stock, 1.0 / stockCount)  

Another way is first exiting all positions:

    for stock in context.portfolio.positions:  
        order_target(stock, 0)

    for stock in context.portfolio.positions:  
        order_target_percent(stock, 1.0 / stockCount)  

My guess is that, 2nd way is better and more stable as it give enough cash after exiting. Is that correct?

4 responses

Hi Han,

If you're trying to rebalance and maintain a target position in your portfolio, then your first option is better. In the second option, you'll incur unnecessary commission costs and the portfolio positions object will be empty when you loop through it.

Here's an example of a rebalance live trading algo, it's the one we're running on our Interactive Brokers account: https://www.quantopian.com/posts/rebalance-algo-9-sector-etfs

Keep in mind that the order_target methods make their calculation for the target amounts based on filled orders. They don't take into consideration open orders, so you will need to add this guard. You can use the code from the algo above or simply use:

handle_data(contexrt,data):  
  if get_open_orders:  
    return  
Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Chiming in here this is the mechanism I use to try and keep leverage <= 1.0:

eligible = []  
# perform your logic to pick the eligible securities and add them here  
for stock in data:  
    if (data[stock].SpecialEntryFactorIsTrueHere):  
        eligible.append(stock)

positions = context.portfolio.positions  
openPositions = [stock for stock in positions if positions[stock].amount > 0 and stock not in eligible]  
eligible += openPositions  
eligibleCount = float(len(eligible))  
for stock in eligible:  
    if (get_open_orders(stock)):  
        continue  
    order_target_percent(stock, 1.0 / eligibleCount)  
    if (context.portfolio.positions[stock].amount == 0.0):  
        print("  Entry Long  {0:<5} @ {1:>6.2f}".format(  
                stock.symbol, data[stock].close_price))  

@Market Tech, in the for loop it seems the sell orders can be executed the last (stocks with amount>0 are appended to eligible). I am wondering why this code keeps leverage under 1.

@Han C. Well, the intent, and maybe I've failed in my execution of the intent, was

• to perform the selection of any new long entries,
• add to this list of new entries existing long positions which were not already (re)selected for entry,
• use this composite number of open positions + new positions to determine the proper divisor for the % entries,
• perform a crude open orders test which might compound the intended position of a security.
• enter each leg or readjust an open leg given the new % for each.

It seems to work in the strats I've used it within. It's long only which is limiting. And pretty much assumes that there are no open orders, but will side with caution if there is.

One can only try it to see if my assumptions are correct or bogus.