def OnRetirement(self, year_rec): """This deals with events happening at the point of retirement.""" # Update all incomes for income in self.incomes: income.OnRetirement(self) # Create RRSP bridging fund if needed if self.age < world.CPP_EXPECTED_RETIREMENT_AGE: requested = ( world.CPP_EXPECTED_RETIREMENT_AGE - self.age ) * world.OAS_BENEFIT * self.strategy.oas_bridging_fraction self.funds["wp_rrsp"], self.funds["bridging"] = funds.SplitFund( self.funds["wp_rrsp"], funds.RRSPBridging(), requested) if self.funds["bridging"].amount < requested: top_up_amount = min(self.rrsp_room, requested - self.funds["bridging"].amount) fund_chain = [self.funds["wp_nonreg"], self.funds["wp_tfsa"]] # Not using ChainedWithdraw because it can't express strict overflow withdrawn, _, year_rec = funds.ChainedTransaction( top_up_amount, fund_chain, (1, 1), (1, 1), year_rec) self.funds["bridging"].amount += withdrawn year_rec.deposits.append( funds.DepositReceipt(withdrawn, funds.FUND_TYPE_RRSP)) self.rrsp_room -= withdrawn self.bridging_withdrawal_table = world.GenerateCEDDrawdownTable( self.age, world.CPP_EXPECTED_RETIREMENT_AGE) # Split each fund into a CED and a CD fund self.funds["cd_rrsp"], self.funds["ced_rrsp"] = funds.SplitFund( self.funds["wp_rrsp"], funds.RRSP(), self.strategy.drawdown_ced_fraction * self.funds["wp_rrsp"].amount) del self.funds["wp_rrsp"] self.funds["cd_tfsa"], self.funds["ced_tfsa"] = funds.SplitFund( self.funds["wp_tfsa"], funds.TFSA(), self.strategy.drawdown_ced_fraction * self.funds["wp_tfsa"].amount) del self.funds["wp_tfsa"] self.funds["cd_nonreg"], self.funds["ced_nonreg"] = funds.SplitFund( self.funds["wp_nonreg"], funds.NonRegistered(), self.strategy.drawdown_ced_fraction * self.funds["wp_nonreg"].amount) del self.funds["wp_nonreg"] self.cd_drawdown_amount = sum( fund.amount for fund in (self.funds["cd_rrsp"], self.funds["cd_tfsa"], self.funds["cd_nonreg"] )) * self.strategy.initial_cd_fraction / year_rec.cpi self.assets_at_retirement = sum( fund.amount for fund in self.funds.values()) / year_rec.cpi if not self.basic_only: self.accumulators.fraction_persons_involuntarily_retired.UpdateOneValue( 1 if self.age < self.strategy.planned_retirement_age else 0)
def testSplitFundSourceHasZeroFunds(self): source = funds.Fund() source.amount = 0 source.unrealized_gains = 0 sink = funds.Fund() source, sink = funds.SplitFund(source, sink, 30) self.assertEqual(source.amount, 0) self.assertEqual(sink.amount, 0) self.assertEqual(source.unrealized_gains, 0) self.assertEqual(sink.unrealized_gains, 0)
def testSplitFundInsufficientFunds(self): source = funds.Fund() source.amount = 40 source.unrealized_gains = 20 sink = funds.Fund() source, sink = funds.SplitFund(source, sink, 50) self.assertEqual(source.amount, 0) self.assertEqual(sink.amount, 40) self.assertEqual(source.unrealized_gains, 0) self.assertEqual(sink.unrealized_gains, 20)
def testSplitFundSufficientFunds(self): source = funds.Fund() source.amount = 40 source.unrealized_gains = 20 sink = funds.Fund() source, sink = funds.SplitFund(source, sink, 30) self.assertEqual(source.amount, 10) self.assertEqual(sink.amount, 30) self.assertEqual(source.unrealized_gains, 5) self.assertEqual(sink.unrealized_gains, 15)
def testSplitFundSinkHasMoney(self): source = funds.Fund() source.amount = 40 source.unrealized_gains = 20 sink = funds.Fund() sink.amount = 20 sink.unrealized_gains = 10 source, sink = funds.SplitFund(source, sink, 30) self.assertEqual(source.amount, 10) self.assertEqual(sink.amount, 50) self.assertEqual(source.unrealized_gains, 5) self.assertEqual(sink.unrealized_gains, 25)