def test_equality(self): sec: Security = Security( "sec", "SEC", price=10.0, buy_restricted=False ) pur: Purchase = Purchase(sec, 5) d1: Deposit = Deposit() d1.add_purchase("ac", pur) d2: Deposit = Deposit() d2.add_purchase("ac", pur) self.assertEqual(d1, d2)
def plan_deposit(self, amount: float) -> Deposit: """ Returns the optimal purchases to make with deposit added to this portfolio. """ portfolio_cash = self.get_cash() deposit_budget = amount if portfolio_cash >= amount else portfolio_cash s: datetime = datetime.now() # Compute purchases necessary to rebalance portfolio deposit: Deposit = Deposit() budgets: List[Tuple[str, float]] = sorted( self.get_asset_class_budgets(deposit_budget).items(), key=lambda x: x[1], reverse=True, ) # Rollover allocations not spent in previous classes rollover: float = 0.0 for (ac_name, budget) in budgets: ac: AssetClass = self.get_asset_class(ac_name) final_budget: float = budget + rollover if (ac_name, budget) == budgets[-1]: final_budget -= ac.get_purchase_buffer() ac_purchases: Dict[str, Purchase] = ac.plan_purchases(final_budget) ac_total: float = 0.0 for purchase in ac_purchases.values(): deposit.add_purchase(ac_name, purchase) ac_total += purchase.get_cost() rollover = final_budget - ac_total e: datetime = datetime.now() log.info("Planned deposit. ({})".format(latency_str(s, e))) return deposit
def test_add_purchase(self): d: Deposit = Deposit() sec: Security = Security("sec", "SEC", price=10.0) pur: Purchase = Purchase(sec, 5) d.add_purchase("ac", pur) self.assertEqual(d.get_total(), 50.0) self.assertEqual(d.get_num_shares(), 5) self.assertTrue(pur in d.get_purchases_for_asset_class("ac"))
def test_get_asset_class_expenditures(self): d: Deposit = Deposit() sec1: Security = Security( "sec1", "SEC1", price=10.0, buy_restricted=False ) sec2: Security = Security( "sec2", "SEC2", price=5.0, buy_restricted=False ) d.add_purchase("ac", Purchase(sec1, 5)) d.add_purchase("ac", Purchase(sec2, 10)) self.assertEqual(d.get_asset_class_expenditures("ac"), 100.0)
def make_deposit(self, deposit: Deposit, online: bool) -> None: """ Makes all the purchases in the given deposit, updating the state of this portfolio. """ if deposit.get_total() > self.get_cash(): raise Exception("Deposit total is more than cash in portfolio.") log.info("Deposit:{}".format(deposit.for_display())) acs: List[Tuple[str, float]] = [ (ac, deposit.get_asset_class_expenditures(ac)) for ac in deposit.get_involved_asset_classes() ] sorted_acs: List[Tuple[str, float]] = sorted( acs, key=lambda x: x[1], reverse=True ) for ac_name, _ in sorted_acs: ac: AssetClass = self.get_asset_class(ac_name) ps: List[Purchase] = deposit.get_purchases_for_asset_class(ac_name) purchases: List[Purchase] = sorted( ps, key=lambda x: x.get_cost(), reverse=True ) for p in purchases: state: str = ac.buy( p.get_security(), p.get_num_shares(), online ) if state != "failed": m: str = "\t- Trade Status: {}\n".format( state.capitalize() ) log.info(m) self.set_cash(self.get_cash() - p.get_cost()) else: em: str = "\t- Trade Status: {}\n".format( state.capitalize() ) log.error(em)
def test_get_purchases_for_asset_class(self): sec: Security = Security("sec", "SEC", "sec_name", 10.0, False) pur: Purchase = Purchase(sec, 5) d: Deposit = Deposit() d.add_purchase("ac", pur) self.assertEqual(d.get_purchases_for_asset_class("ac"), [pur])
def test_involves_asset_class_true(self): d: Deposit = Deposit() sec: Security = Security("sec", "SEC", "sec_name", 10.0) pur: Purchase = Purchase(sec, 5) d.add_purchase("ac", pur) self.assertTrue(d.involves_asset_class("ac"))
def test_involves_asset_class_false(self): d: Deposit = Deposit() self.assertFalse(d.involves_asset_class("ac"))
def test_inequality(self): d1: Deposit = Deposit() sec: Security = Security("sec", "SEC", price=10.0) d1.add_purchase("ac", Purchase(sec, 5)) d2: Deposit = Deposit() self.assertNotEqual(d1, d2)