def testChainedWithdrawForcedWithdrawPreferZero(self): year_rec = utils.YearRecord() year_rec.age = 94 year_rec.growth_rate=0 rrsp = funds.RRSP() rrsp.amount = 50 rrsp.Update(year_rec) tfsa = funds.TFSA() tfsa.amount = 50 nonreg = funds.NonRegistered() nonreg.amount = 30 nonreg.unrealized_gains = 15 fund_chain = (rrsp, tfsa, nonreg) proportions = (0, 0.5, 1) withdrawn, gains, year_rec = funds.ChainedWithdraw(60, fund_chain, proportions, utils.YearRecord()) self.assertEqual(withdrawn, 60) self.assertEqual(gains, 12.5) self.assertSequenceEqual( year_rec.withdrawals, [funds.WithdrawReceipt(10, 0, funds.FUND_TYPE_RRSP), funds.WithdrawReceipt(25, 0, funds.FUND_TYPE_TFSA), funds.WithdrawReceipt(25, 12.5, funds.FUND_TYPE_NONREG)]) self.assertEqual(rrsp.amount, 40) self.assertEqual(tfsa.amount, 25) self.assertEqual(nonreg.amount, 5)
def testEIBenefitsUnemployedInsuredRetired(self): income = incomes.EI() last_year_rec = utils.YearRecord() last_year_rec.is_employed = True last_year_rec.insurable_earnings = 100 this_year_rec = utils.YearRecord() this_year_rec.is_employed = False this_year_rec.is_retired = True income.AnnualUpdate(last_year_rec) amount, taxable, year_rec = income.GiveMeMoney(this_year_rec) self.assertEqual(amount, 0) self.assertEqual(taxable, True) self.assertIn(incomes.IncomeReceipt(0, incomes.INCOME_TYPE_EI), year_rec.incomes)
def testRRSPForcedWithdrawActive(self): fund = funds.RRSP() fund.amount = 10000 year_rec = utils.YearRecord() year_rec.age = 70 fund.Update(year_rec) self.assertEqual(fund.forced_withdraw, 528)
def testRRSPRoomLimit(self): fund = funds.RRSP() year_rec = utils.YearRecord() year_rec.incomes.append(incomes.IncomeReceipt(140000, incomes.INCOME_TYPE_EARNINGS)) self.assertEqual(fund.room, world.RRSP_INITIAL_LIMIT) fund.Update(year_rec) self.assertEqual(fund.room, world.RRSP_INITIAL_LIMIT+world.RRSP_LIMIT)
def testDepositUnlimitedRoom(self): fund = funds.Fund() deposited, year_rec = fund.Deposit(15, utils.YearRecord()) self.assertEqual(deposited, 15) self.assertEqual(fund.amount, 15) self.assertIn(funds.DepositReceipt(15, funds.FUND_TYPE_NONE), year_rec.deposits)
def SetupForMeddleWithCash(self, age=30, cpi=1, retired=False, employed=True, rrsp=0, rrsp_room=0, tfsa=0, tfsa_room=0, nonreg=0): j_canuck = person.Person() year_rec = utils.YearRecord() # Set working period fund amounts (these may be split later on) j_canuck.funds["wp_rrsp"].amount = rrsp j_canuck.funds["wp_tfsa"].amount = tfsa j_canuck.funds["wp_nonreg"].amount = nonreg # The following section roughly approximates Person.AnnualSetup() j_canuck.age = age year_rec.age = age j_canuck.year = age - world.START_AGE + world.BASE_YEAR year_rec.year = age - world.START_AGE + world.BASE_YEAR j_canuck.cpi = cpi year_rec.cpi = cpi j_canuck.retired = retired if retired: j_canuck.OnRetirement() year_rec.is_retired = retired year_rec.is_employed = employed and not retired year_rec.growth_rate = world.MEAN_INVESTMENT_RETURN j_canuck.tfsa_room = tfsa_room year_rec.tfsa_room = tfsa_room j_canuck.rrsp_room = rrsp_room year_rec.rrsp_room = rrsp_room return j_canuck, year_rec
def testEarningsUnemployed(self): income = incomes.Earnings() amount, taxable, year_rec = income.GiveMeMoney(utils.YearRecord()) self.assertEqual(amount, 0) self.assertEqual(taxable, True) self.assertIn(incomes.IncomeReceipt(0, incomes.INCOME_TYPE_EARNINGS), year_rec.incomes)
def testOASUsesCPI(self): income = incomes.OAS() year_rec = utils.YearRecord() year_rec.age = 66 year_rec.cpi = 1.02 amount, _, _ = income.GiveMeMoney(year_rec) self.assertEqual(amount, world.OAS_BENEFIT * 1.02)
def testGrowthInflation(self): fund = funds.Fund() fund.amount = 20 year_rec = utils.YearRecord() year_rec.growth_rate = 0 year_rec.inflation = 1 self.assertEqual(fund.Growth(year_rec), 20)
def testChainedTransactionDifferentProportion(self): year_rec = utils.YearRecord() rrsp = funds.RRSP() rrsp.amount = 100 rrsp.forced_withdraw = 80 tfsa = funds.TFSA() tfsa.amount = 50 year_rec.tfsa_room = 100 nonreg = funds.NonRegistered() fund_chain = (rrsp, tfsa, nonreg) withdrawal_proportions = (0.5, 0.5, 1) deposit_proportions = (0.5, 0.8, 1) withdrawn, gains, year_rec = funds.ChainedTransaction( 60, fund_chain, withdrawal_proportions, deposit_proportions, year_rec) self.assertEqual(withdrawn, 60) self.assertEqual(gains, 0) self.assertSequenceEqual( year_rec.withdrawals, [funds.WithdrawReceipt(80, 0, funds.FUND_TYPE_RRSP)]) self.assertSequenceEqual( year_rec.deposits, [funds.DepositReceipt(16, funds.FUND_TYPE_TFSA), funds.DepositReceipt(4, funds.FUND_TYPE_NONREG)]) self.assertEqual(rrsp.amount, 20) self.assertEqual(tfsa.amount, 66) self.assertEqual(nonreg.amount, 4)
def testChainedWithdrawForcedWithdrawProportionalDeposit(self): year_rec = utils.YearRecord() rrsp = funds.RRSP() rrsp.amount = 100 rrsp.forced_withdraw = 80 tfsa = funds.TFSA() tfsa.amount = 50 year_rec.tfsa_room = 50 nonreg = funds.NonRegistered() nonreg.amount = 50 nonreg.unrealized_gains = 25 fund_chain = (rrsp, tfsa, nonreg) proportions = (0.1, 0.5, 1) withdrawn, gains, year_rec = funds.ChainedWithdraw(60, fund_chain, proportions, year_rec) self.assertEqual(withdrawn, 60) self.assertEqual(gains, 0) self.assertSequenceEqual( year_rec.withdrawals, [funds.WithdrawReceipt(80, 0, funds.FUND_TYPE_RRSP)]) self.assertSequenceEqual( year_rec.deposits, [funds.DepositReceipt(10, funds.FUND_TYPE_TFSA), funds.DepositReceipt(10, funds.FUND_TYPE_NONREG)]) self.assertEqual(rrsp.amount, 20) self.assertEqual(tfsa.amount, 60) self.assertEqual(nonreg.amount, 60)
def testGiveMeMoney(self): income = incomes.Income() amount, taxable, year_rec = income.GiveMeMoney(utils.YearRecord()) self.assertEqual(amount, 0) self.assertEqual(taxable, True) self.assertIn(incomes.IncomeReceipt(0, incomes.INCOME_TYPE_NONE), year_rec.incomes)
def SetupYearRecForIncomeTax( self, earnings=0, oas=0, gis=0, cpp=0, ei=0, rrsp=0, bridging=0,nonreg=0, gains=0, eoy_gains=0, unapplied_losses=0, rrsp_contributions=0, age=30, retired=False, cpi=1): """Set up a person and a year record in one go for testing income tax.""" j_canuck = person.Person(strategy=self.default_strategy) j_canuck.capital_loss_carry_forward = unapplied_losses j_canuck.age += age - world.START_AGE j_canuck.year += age - world.START_AGE j_canuck.retired = retired year_rec = utils.YearRecord() year_rec.is_retired = j_canuck.retired year_rec.year = j_canuck.year year_rec.incomes.append(incomes.IncomeReceipt(earnings, incomes.INCOME_TYPE_EARNINGS)) year_rec.incomes.append(incomes.IncomeReceipt(oas, incomes.INCOME_TYPE_OAS)) year_rec.incomes.append(incomes.IncomeReceipt(gis, incomes.INCOME_TYPE_GIS)) year_rec.incomes.append(incomes.IncomeReceipt(cpp, incomes.INCOME_TYPE_CPP)) year_rec.incomes.append(incomes.IncomeReceipt(ei, incomes.INCOME_TYPE_EI)) year_rec.withdrawals.append(funds.WithdrawReceipt(nonreg, gains, funds.FUND_TYPE_NONREG)) year_rec.withdrawals.append(funds.WithdrawReceipt(rrsp, 0, funds.FUND_TYPE_RRSP)) year_rec.withdrawals.append(funds.WithdrawReceipt(bridging, 0, funds.FUND_TYPE_BRIDGING)) year_rec.tax_receipts.append(funds.TaxReceipt(eoy_gains, funds.FUND_TYPE_NONREG)) year_rec.deposits.append(funds.DepositReceipt(rrsp_contributions, funds.FUND_TYPE_RRSP)) year_rec.cpi = cpi year_rec = j_canuck.CalcPayrollDeductions(year_rec) return (j_canuck, year_rec)
def testCPPDuringWorkingPeriod(self): income = incomes.CPP() amount, taxable, year_rec = income.GiveMeMoney(utils.YearRecord()) self.assertEqual(amount, 0) self.assertEqual(taxable, True) self.assertIn(incomes.IncomeReceipt(0, incomes.INCOME_TYPE_CPP), year_rec.incomes)
def testCPPAnnualUpdatePositiveEarnings(self): income = incomes.CPP() income.ympe_fractions = [] year_rec = utils.YearRecord() year_rec.is_retired = False year_rec.pensionable_earnings = 100 income.AnnualUpdate(year_rec) self.assertEqual(income.ympe_fractions, [100 / world.YMPE])
def testWithdrawForcedInsufficient(self): fund = funds.Fund() fund.amount = 10 fund.forced_withdraw = 15 withdrawn, gains, year_rec = fund.Withdraw(5, utils.YearRecord()) self.assertEqual(withdrawn, 10) self.assertEqual(fund.amount, 0) self.assertEqual(fund.forced_withdraw, 0)
def testWithdrawForcedActive(self): fund = funds.Fund() fund.amount = 20 fund.forced_withdraw = 15 withdrawn, gains, year_rec = fund.Withdraw(10, utils.YearRecord()) self.assertEqual(withdrawn, 15) self.assertEqual(fund.amount, 5) self.assertEqual(fund.forced_withdraw, 0)
def testNonRegisteredDeposit(self): fund = funds.NonRegistered() deposited, year_rec = fund.Deposit(15, utils.YearRecord()) self.assertEqual(deposited, 15) self.assertEqual(fund.amount, 15) self.assertIn(funds.DepositReceipt(15, funds.FUND_TYPE_NONREG), year_rec.deposits) self.assertEqual(fund.unrealized_gains, 0)
def testWithdrawInsufficientFunds(self): fund = funds.Fund() fund.amount = 5 withdrawn, gains, year_rec = fund.Withdraw(15, utils.YearRecord()) self.assertEqual(withdrawn, 5) self.assertEqual(fund.amount, 0) self.assertIn(funds.WithdrawReceipt(5, 0, funds.FUND_TYPE_NONE), year_rec.withdrawals)
def testCPPAnnualUpdateZeroEarnings(self): income = incomes.CPP() income.ympe_fractions = [] year_rec = utils.YearRecord() year_rec.is_retired = False year_rec.pensionable_earnings = 0 income.AnnualUpdate(year_rec) self.assertEqual(income.ympe_fractions, [0])
def testWithdrawZero(self): fund = funds.Fund() fund.amount = 0 withdrawn, gains, year_rec = fund.Withdraw(10, utils.YearRecord()) self.assertEqual(withdrawn, 0) self.assertEqual(gains, 0) self.assertIn(funds.WithdrawReceipt(0, 0, funds.FUND_TYPE_NONE), year_rec.withdrawals)
def testEIBenefitsUnemployedInsuredWorking(self): income = incomes.EI() last_year_rec = utils.YearRecord() last_year_rec.is_employed = True last_year_rec.insurable_earnings = 100 this_year_rec = utils.YearRecord() this_year_rec.is_employed = False this_year_rec.is_retired = False income.AnnualUpdate(last_year_rec) amount, taxable, year_rec = income.GiveMeMoney(this_year_rec) self.assertAlmostEqual(amount, 55) self.assertEqual(taxable, True) # done differently due to floating point equality checks self.assertEqual(year_rec.incomes[0].income_type, incomes.INCOME_TYPE_EI) self.assertAlmostEqual(year_rec.incomes[0].amount, 55) self.assertEqual(len(year_rec.incomes), 1)
def testRRSPBridgingDeposit(self): fund = funds.RRSPBridging() fund.amount = 30 deposited, year_rec = fund.Deposit(15, utils.YearRecord()) self.assertEqual(deposited, 0) self.assertEqual(fund.amount, 30) self.assertIn(funds.DepositReceipt(0, funds.FUND_TYPE_BRIDGING), year_rec.deposits)
def testRRSPBridgingUpdate(self): fund = funds.RRSPBridging() fund.amount = 20 year_rec = utils.YearRecord() year_rec.growth_rate = 0.2 year_rec.inflation = 1 fund.Update(year_rec) self.assertEqual(fund.amount, 48) self.assertEqual(fund.unrealized_gains, 0)
def testTFSADeposit(self): fund = funds.TFSA() year_rec = utils.YearRecord() year_rec.tfsa_room = 20 deposited, year_rec = fund.Deposit(15, year_rec) self.assertEqual(deposited, 15) self.assertEqual(fund.amount, 15) self.assertIn(funds.DepositReceipt(15, funds.FUND_TYPE_TFSA), year_rec.deposits)
def testWithdrawRoomReplenishment(self): fund = funds.Fund() fund.amount = 20 fund.GetRoom = unittest.mock.MagicMock(return_value=5) set_room = unittest.mock.MagicMock() fund.SetRoom = set_room fund.room_replenishes = True withdrawn, gains, year_rec = fund.Withdraw(10, utils.YearRecord()) set_room.assert_called_with(unittest.mock.ANY, 15)
def AnnualSetup(self): """This is responsible for beginning of year operations. Returns a partially initialized year record. """ year_rec = utils.YearRecord() year_rec.age = self.age year_rec.year = self.year year_rec.inflation = random.normalvariate(world.INFLATION_MEAN, world.INFLATION_STDDEV) if self.year == world.BASE_YEAR: self.cpi = 1 else: self.cpi = self.cpi * (1 + year_rec.inflation) self.cpi_history.append(self.cpi) year_rec.cpi = self.cpi # Reap souls if self.gender == MALE: p_mortality = world.MALE_MORTALITY[ self.age] * world.MORTALITY_MULTIPLIER elif self.gender == FEMALE: p_mortality = world.FEMALE_MORTALITY[ self.age] * world.MORTALITY_MULTIPLIER if random.random() < p_mortality: year_rec.is_dead = True return year_rec else: year_rec.is_dead = False # Retirement if not self.retired: if ((self.age == self.strategy.planned_retirement_age and self.age >= world.MINIMUM_RETIREMENT_AGE) or self.involuntary_retirement_random < (self.age - world.MINIMUM_RETIREMENT_AGE + 1) * world.INVOLUNTARY_RETIREMENT_INCREMENT or self.age == world.MAXIMUM_RETIREMENT_AGE): self.retired = True self.OnRetirement(year_rec) year_rec.is_retired = self.retired # Employment year_rec.is_employed = not self.retired and random.random( ) > world.UNEMPLOYMENT_PROBABILITY # Growth year_rec.growth_rate = random.normalvariate( world.MEAN_INVESTMENT_RETURN, world.STD_INVESTMENT_RETURN) # Fund room self.tfsa_room += world.TFSA_ANNUAL_CONTRIBUTION_LIMIT * self.cpi year_rec.tfsa_room = self.tfsa_room year_rec.rrsp_room = self.rrsp_room return year_rec
def testRRSPBridgingWithdraw(self): fund = funds.RRSPBridging() fund.amount = 20 withdrawn, gains, year_rec = fund.Withdraw(15, utils.YearRecord()) self.assertEqual(withdrawn, 15) self.assertEqual(fund.amount, 5) self.assertEqual(fund.unrealized_gains, 0) self.assertIn(funds.WithdrawReceipt(15, 0, funds.FUND_TYPE_BRIDGING), year_rec.withdrawals)
def testOASBeforeRetirement(self): income = incomes.OAS() year_rec = utils.YearRecord() year_rec.age = 60 amount, taxable, year_rec = income.GiveMeMoney(year_rec) self.assertEqual(amount, 0) self.assertEqual(taxable, True) self.assertIn(incomes.IncomeReceipt(0, incomes.INCOME_TYPE_OAS), year_rec.incomes)
def testGISCalcIncomeBaseIncomesAndPayrollDeductions(self): income = incomes.GIS() income.last_year_income_base = 10000 year_rec = utils.YearRecord() year_rec.incomes = [ incomes.IncomeReceipt(5000, incomes.INCOME_TYPE_EARNINGS) ] year_rec.ei_premium = 2000 year_rec.cpp_contribution = 2000 self.assertEqual(income._CalcIncomeBase(year_rec), 1000)