def update_holding( self, security_id: str, num_shares: int, average_buy_price: float, dividends: float, ) -> None: """ Updates this asset class with new holding data. """ if self.contains_holding(security_id): # Already have a holding for this security -> update state hol: Holding = self.get_holding(security_id) hol.set_num_shares(num_shares) hol.set_average_buy_price(average_buy_price) hol.set_dividends(dividends) elif self.contains_security(security_id): # Don't have holding for this security yet -> add as a new holding sec: Security = self.get_security(security_id) self.add_holding( Holding(sec, num_shares, average_buy_price, dividends)) else: raise Exception("update_holding(): {} is not in the '{}' asset " "class's securities.".format( security_id, self.get_name()))
def test_buy_new(self): ac: AssetClass = AssetClass("ac", target_percentage=1.0) sec: Security = Security("sec", "SEC", price=5.0) ac.add_security(sec) ac.buy(sec, 3, False) self.assertEqual(ac.get_holding("sec"), Holding(sec, 3, 5.0)) self.assertEqual(ac.get_value(), 15.0)
def test_add_holding_hs_hh(self): ac: AssetClass = AssetClass("ac", target_percentage=1.0) sec: Security = Security("sec", "SEC", price=10.0) ac.add_security(sec) ac.buy(sec, 3, False) hol: Holding = Holding(sec, 3, 10.0) self.assertRaises(Exception, ac.add_holding, hol)
def test_add_holding_hs_not_hh(self): ac: AssetClass = AssetClass("ac", target_percentage=1.0) sec: Security = Security("sec", "SEC", price=10.0) ac.add_security(sec) ac.add_holding(Holding(sec, 3, 10.0)) holding: Holding = ac.get_holding("sec") self.assertEqual(holding.get_value(), 30.0) self.assertEqual(holding.get_num_shares(), 3) self.assertEqual(holding.get_average_buy_price(), 10.0)
def test_get_return_with_dividends(self): sec: Security = Security("sec", "SEC", price=11.0) # Value: $33 # Dividends: $7 # Cost: $30 # Return = (Value + Dividends - Cost) / Cost # = (33 + 7 - 30) / 30 # = 10 / 30 = 0.33 hol: Holding = Holding(sec, 3, 10.0, 7.0) self.assertEqual(hol.get_return(), 1.0 / 3.0)
def add_holding(self, holding: Holding) -> None: """ Adds the given holding to this asset class. Possible cases (HS: has security, HH: has holding): 1) HS, HH: user already added holding and security, raise error 2) !HS, HH: impossible in theory, raise error 3) HS, !HH: good use case 4) !HS, !HH: user needs to add security first, raise error """ sec_id: str = holding.get_security().get_id() has_security: bool = self.contains_security(sec_id) has_holding: bool = self.contains_holding(sec_id) if has_security and not has_holding: self.__holdings[sec_id] = holding elif not has_security: raise Exception("add_holding(): Must add {} to '{}' before adding" " it as a holding.".format(sec_id, self.get_name())) else: raise Exception("add_holding(): A holding for {} was already added" " to the '{}' asset class.".format( sec_id, self.get_name()))
def test_get_holding_exists(self): ac: AssetClass = AssetClass("ac", target_percentage=1.0) sec: Security = Security("sec", "SEC", "sec_name", 15.0) ac.add_security(sec) ac.buy(sec, 3, False) self.assertEqual(ac.get_holding("sec"), Holding(sec, 3, 15.0))
def test_get_return(self): sec: Security = Security("sec", "SEC", price=11.0) hol: Holding = Holding(sec, 3, 10.0) self.assertEqual(hol.get_return(), 0.1)
def test_get_cost(self): sec: Security = Security("sec", "SEC", price=10.0) hol: Holding = Holding(sec, 3, 10.0) self.assertEqual(hol.get_cost(), 30.0)
def test_get_dividends(self): sec: Security = Security("sec", "SEC", price=10.0) hol: Holding = Holding(sec, 3, 10.0) self.assertEqual(hol.get_dividends(), 0.0) hol.set_dividends(5.0) self.assertEqual(hol.get_dividends(), 5.0)
def test_equality(self): sec1: Security = Security("sec1", "SEC1", price=10.0) sec2: Security = Security("sec2", "SEC2", price=10.0) h1: Holding = Holding(sec1, 1, 10.0) h2: Holding = Holding(sec2, 1, 10.0) self.assertNotEqual(h1, h2)
from src.holdings_publish_service import * from src.holding import Holding from src.holding_schema import HoldingSchema import src.sns_client from decimal import Decimal import json holdings_url = 'https://www.xyz.com/bla?foo=bar' topic_arn = 'arn:dummy-sns-topic' holding1 = Holding( **{ "name": "Commonwealth Bank of Australia", "symbol": "CBA", "sector": "Diversified Banks", "market_val_percent": Decimal('8.25647'), "market_value": Decimal('1041683340.81'), "number_of_shares": Decimal('14389879') }) holding2 = Holding( **{ "name": "BHP Group Ltd.", "symbol": "BHP", "sector": "Diversified Metals & Mining", "market_val_percent": Decimal('6.52946'), "market_value": Decimal('823793522.37'), "number_of_shares": Decimal('24066419') }) holdings = [holding1, holding2] message1 = HoldingSchema().dumps(holding1) message2 = HoldingSchema().dumps(holding2)