IBKR automated rebalancing?

Hi all
I recently wondered how I can automate the last manual part in my investment workflow: rebalancing my IBKR portfolio. In my case on a monthly basis, after my savings arrived.

Has anyone done something in this regard? What’s your experience?

I know there is an API, but so far I have not attempted to do stuff with it :slight_smile:

1 Like

TWS has a ‘Rebalance Portfolio’ feature. Not fully automated, as far as I know, but may be useful. Rebalance Portfolio | Interactive Brokers LLC

There is also https://passiv.com/ as a separate service, which is also linked by IBKR: Passiv | Interactive Brokers LLC

I haven’t looked too much into either of these options as I also take assets outside IBKR into account for rebalancing. I mainly avoid full rebalancing, though, and simply direct monthly savings to the fund with the lowest allocation compared to my investment strategy. I sell only if there is significant deviation from the strategic allocation.

3 Likes

Seems to be an elaborate “spreadsheet” with direct autoimport and email notification at free tier. Can integrate multiple brokers (including IBKR, Degiro, Binance, …). For 99 USD/year you can rebalance everything with one click. Could be somewhat interesting.

1 Like

indeed.

However I am tempted to build a python script to do this for me and put it on github :smiley:

how abut asking chatGPT for a head-start?
Disclaimer: thats the direct output with no corrections wahtsoever

given a target allocation for a passive portfolio, please provide a python script that uses the IBKR API to re-balances an account. this shall involve the following points:

  1. fetch the current allocation
  2. calculate the trade orders required to bring the account back to its target allocation
  3. execute the orders via the API
    please also consider regular cash transfers to the account and dividend distributions, which both shall be invested according to the target allocation
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.order import *
import pandas as pd

# Global variables
TARGET_ALLOCATION = {'AAPL': 0.4, 'GOOGL': 0.3, 'AMZN': 0.2, 'MSFT': 0.1}  # Example target allocation
ACCOUNT_ID = 'YOUR_ACCOUNT_ID'  # Replace with your account ID


class IBKRWrapper(EWrapper):
    def __init__(self):
        super().__init__()
        self.account_allocation = {}

    def accountSummary(self, reqId, account, tag, value, currency):
        if tag == 'NetLiquidationByCurrency' and currency == 'BASE':
            self.account_allocation['Cash'] = float(value)

    def position(self, account, contract, position, avgCost):
        symbol = contract.symbol
        self.account_allocation[symbol] = float(position)


class IBKRClient(EClient):
    def __init__(self, wrapper):
        super().__init__(wrapper)


def calculate_trade_orders(current_allocation):
    trade_orders = {}
    total_value = sum(current_allocation.values())

    for symbol, target_weight in TARGET_ALLOCATION.items():
        current_weight = current_allocation.get(symbol, 0) / total_value
        target_value = total_value * target_weight
        current_value = total_value * current_weight
        trade_orders[symbol] = target_value - current_value

    return trade_orders


def execute_trade_orders(trade_orders):
    app = IBKRClient(IBKRWrapper())
    app.connect('127.0.0.1', 7497, clientId=0)  # Adjust host and port if necessary

    app.reqAccountSummary(0, 'All', 'NetLiquidationByCurrency')

    # Wait until account summary is received
    while 'Cash' not in app.wrapper.account_allocation:
        app.run()

    cash_available = app.wrapper.account_allocation['Cash']
    total_trade_value = sum(abs(value) for value in trade_orders.values())

    if total_trade_value > cash_available:
        print("Insufficient cash to execute trades.")
        app.disconnect()
        return

    for symbol, trade_value in trade_orders.items():
        if trade_value > 0:
            order = create_order(symbol, 'BUY', trade_value)
        elif trade_value < 0:
            order = create_order(symbol, 'SELL', abs(trade_value))
        else:
            continue

        app.placeOrder(app.nextOrderId(), create_contract(symbol), order)

    app.disconnect()


def create_contract(symbol):
    contract = Contract()
    contract.symbol = symbol
    contract.secType = 'STK'
    contract.exchange = 'SMART'
    contract.currency = 'USD'
    return contract


def create_order(symbol, action, quantity):
    order = Order()
    order.action = action
    order.orderType = 'MKT'
    order.totalQuantity = quantity
    order.transmit = False  # Set to True for immediate execution
    return order


# Example usage
def main():
    # Fetch current allocation
    current_allocation = {'AAPL': 100, 'GOOGL': 50, 'AMZN': 25, 'MSFT': 75}  # Example current allocation

it continued here, but the formatting for easy copy/paste was broken :smiley:

1 Like

Currently, I’m actively investing, but in a few years, I want to switch to passive and stop thinking about my investments.

I’ve defined a target investment portfolio using only ETFs, but of course the allocations will fluctuate and cash will accumulate from distributions.

I was also wondering whether someone had already written a python script to do automated re-balancing. I was thinking of simply taking the surplus cash and buying the most under-allocated ETFs monthly and then maybe doing a full rebalancing quarterly if positions are out of whack. This way, it would be hands off and the script could send a monthly report.

Has anyone actually put in place a live automation? How did you host the script (not sure if IBKR offer some kind of native hosting) and ensure security of the machine that runs it?

Have a look at the first link in my post here: Comparing Futures Total Return to Index Total Return for S&P 500 from 1988 to 2022

The guy automates his trading on IBKR. It’s open-source.