1
0
fin-depo/fin_depo/data.py

72 lines
1.9 KiB
Python
Raw Permalink Normal View History

2024-06-02 15:24:53 +00:00
import abc
2024-05-29 20:29:15 +00:00
import dataclasses
2024-06-02 14:14:46 +00:00
import datetime
2024-06-02 15:24:53 +00:00
from collections.abc import Iterable, Mapping
2024-06-02 14:14:46 +00:00
from decimal import Decimal
import enforce_typing
2024-05-29 20:29:15 +00:00
from fin_defs import Asset
2024-06-02 14:14:46 +00:00
2024-05-29 20:29:15 +00:00
@enforce_typing.enforce_types
@dataclasses.dataclass
2024-06-02 15:24:53 +00:00
class Depo(abc.ABC):
2024-06-20 21:43:45 +00:00
"""A depository tracking some amount of assets.
Depo can either be DepoSingle, which is the base layer of the depository
structure, or nested in DepoGroup, which allows for a complex hierarcy of
depositories.
The depository structure exposed by each backend depends upon the logical
structure of the relevant service and the API of this service.
"""
2024-05-29 20:29:15 +00:00
name: str
updated_time: datetime.datetime
2024-06-02 15:24:53 +00:00
@abc.abstractmethod
def assets(self) -> Iterable[Asset]:
"""Returns the different assets managed by this depo."""
@abc.abstractmethod
def get_amount_of_asset(self, asset: Asset) -> Decimal:
"""Returns the amount of owned assets for all nested depos.
Must return 0 if depo does not contain the given asset.
"""
2024-06-02 14:14:46 +00:00
2024-05-29 20:29:15 +00:00
@enforce_typing.enforce_types
@dataclasses.dataclass
class DepoSingle(Depo):
2024-06-20 21:43:45 +00:00
"""Base level of depository."""
2024-06-02 15:24:53 +00:00
_assets: Mapping[Asset, Decimal]
def assets(self) -> Iterable[Asset]:
return self._assets
def get_amount_of_asset(self, asset: Asset) -> Decimal:
return self._assets.get(asset, Decimal(0))
2024-05-29 20:29:15 +00:00
2024-06-02 14:14:46 +00:00
2024-05-29 20:29:15 +00:00
@enforce_typing.enforce_types
@dataclasses.dataclass
class DepoGroup(Depo):
2024-06-20 21:43:45 +00:00
"""Nested depository."""
2024-05-29 20:29:15 +00:00
nested: list[Depo]
2024-06-02 15:24:53 +00:00
def assets(self) -> Iterable[Asset]:
assets: list[Asset] = []
for nested_depo in self.nested:
assets.extend(nested_depo.assets())
return assets
def get_amount_of_asset(self, asset: Asset) -> Decimal:
summed: Decimal = Decimal(0)
for nested_depo in self.nested:
summed += nested_depo.get_amount_of_asset(asset)
del nested_depo
return summed