def test_rebalance_reinvest(self): portfolio = Portfolio({CCC: Decimal(2000), DDD: Decimal(8000)}) orders = portfolio.rebalance(self.model_portfolio) self.assertEqual(orders, [(SELL, CCC, Decimal(2000)), (SELL, DDD, Decimal(8000)), (BUY, AAA, Decimal(4000)), (BUY, BBB, Decimal(5000))])
def test_rebalancing2(self): """ Test rebalancing algorithm. Part 2. Cash is not in the same currency as the assets. """ p = Portfolio() p.add_cash(200., "USD") p.add_cash(250., "GBP") tickers = ["VCN.TO", "XAW.TO", "ZAG.TO"] quantities = [5, 12, 20] p.easy_add_assets(tickers=tickers, quantities=quantities) target_asset_alloc = { "VCN.TO": 40.0, "ZAG.TO": 40.0, "XAW.TO": 20.0, } initial_value = p.value("CAD") p.selling_allowed = False (_, prices, _, _) = p.rebalance(target_asset_alloc, verbose=True) final_value = p.value("CAD") self.assertAlmostEqual(initial_value, final_value, -1) # The prices should be in the tickers' currency for ticker in tickers: self.assertEqual(prices[ticker][1], "CAD") # Since there was no CAD to start off with, # there should be none after rebalacing either # (i.e. amount converted to CAD should be the amount used to purchase CAD assets) self.assertAlmostEqual(p.cash["CAD"].amount, 0., 1)
def test_rebalance_balanced(self): portfolio = Portfolio({ CASH: Decimal(500), AAA: Decimal(2000), BBB: Decimal(2500) }) orders = portfolio.rebalance(self.model_portfolio) self.assertEqual(orders, [])
def test_rebalancing(self): """ Test rebalancing algorithm. This might break over time as prices increase. If we have enough cash though, the optimizer should ideally be able to match the target asset allocation pretty closely """ p = Portfolio() tickers = ["XBB.TO", "XIC.TO", "ITOT", "IEFA", "IEMG"] quantities = [36, 64, 32, 8, 7] p.easy_add_assets(tickers=tickers, quantities=quantities) p.add_cash(3000, "USD") p.add_cash(515.21, "CAD") p.add_cash(5.00, "GBP") p.selling_allowed = True self.assertTrue(p.selling_allowed) # different order than tickers. # rebalance method should be able to handle such a case target_asset_alloc = { "XBB.TO": 20, "XIC.TO": 20, "IEFA": 20, "ITOT": 36, "IEMG": 4 } initial_value = p.value("CAD") (_, _, _, max_diff) = p.rebalance(target_asset_alloc, verbose=True) final_value = p.value("CAD") self.assertAlmostEqual(initial_value, final_value, 1) self.assertLessEqual(max_diff, 2.) # Error handling with self.assertRaises(Exception): target_asset_alloc = { "XBB.TO": 20, "XIC.TO": 20, "IEFA": 20, } p.rebalance(target_asset_alloc)
def test_rebalance_unbalanced(self): portfolio = Portfolio({AAA: Decimal(2000), BBB: Decimal(8000)}) orders = portfolio.rebalance(self.model_portfolio) self.assertEqual(orders, [(SELL, BBB, Decimal(3000)), (BUY, AAA, Decimal(2000))])
def test_rebalance_cash(self): portfolio = Portfolio({CASH: Decimal(5000)}) orders = portfolio.rebalance(self.model_portfolio) self.assertEqual(orders, [(BUY, AAA, Decimal(2000)), (BUY, BBB, Decimal(2500))])
from rebalance import Portfolio # My portfolio p = Portfolio() # Cash in portfolio cash_amounts = [5000] cash_currency = ["CAD"] p.easy_add_cash(amounts=cash_amounts, currencies=cash_currency) # Assets in portfolio # The price will be retrieved automatically tickers = ["XIC.TO", "VCN.TO", "TSLA"] quantities = [20, 20, 10] p.easy_add_assets(tickers=tickers, quantities=quantities) # Target asset allocation (in %) target_asset_alloc = {"XIC.TO": 20, "VCN.TO": 30, "TSLA": 50} # rebalance p.selling_allowed = True # Don't allow selling while rebalancing p.rebalance(target_asset_alloc, verbose=True)
from rebalance import Portfolio p = Portfolio() tickers = ["XBB.TO", "XIC.TO", "ITOT", "IEFA", "IEMG"] quantities = [36, 64, 32, 8, 7] p.easy_add_assets(tickers=tickers, quantities = quantities) p.add_cash(5000.00, "GBP") p.add_cash(1000.00, "EUR") target_asset_alloc = { "XBB.TO": 20, "XIC.TO": 20, "IEFA": 20, "ITOT": 36, "IEMG": 4 } initial_value = p.value("CAD") p.selling_allowed = False (_, _, exchange_rates, _) = p.rebalance(target_asset_alloc, verbose=True) final_value = p.value("CAD")