diff options
author | xengineering <me@xengineering.eu> | 2024-09-08 17:02:33 +0200 |
---|---|---|
committer | xengineering <me@xengineering.eu> | 2024-09-08 17:21:32 +0200 |
commit | 458a24d09f95eefb161728d9676ecdfca30e3f5e (patch) | |
tree | d3260b2531f42a6e8335661312661302b9653730 /finance/flow.py | |
parent | 6973093a2b80b4fb9e216d1b3e329dd4c2badc7c (diff) | |
download | finance-py-458a24d09f95eefb161728d9676ecdfca30e3f5e.tar finance-py-458a24d09f95eefb161728d9676ecdfca30e3f5e.tar.zst finance-py-458a24d09f95eefb161728d9676ecdfca30e3f5e.zip |
Split flow.py to simulate.py and model.py
model.py should be a file containing only dataclasses to model finance.
simulate.py should take care of the simulation of that finance data to
create a financial forecast.
Diffstat (limited to 'finance/flow.py')
-rw-r--r-- | finance/flow.py | 66 |
1 files changed, 0 insertions, 66 deletions
diff --git a/finance/flow.py b/finance/flow.py deleted file mode 100644 index c6b28c0..0000000 --- a/finance/flow.py +++ /dev/null @@ -1,66 +0,0 @@ -import dataclasses -from datetime import datetime -from decimal import Decimal -from typing import Generator - - -@dataclasses.dataclass(kw_only=True, frozen=True) -class Flow: - """Time-discrete flow of money paid on the first day of a month""" - - amount: Decimal - since: None | datetime - until: None | datetime - - def integrate(self, start: datetime, end: datetime) -> Decimal: - """Integrate the flow between two dates to an amount of money""" - - payments: int = 0 - - if self.since is not None: - if start < self.since: - start = self.since - - if self.until is not None: - if end > self.until: - end = self.until - - for candidate in monthly_candidates(start): - if start <= candidate <= end: - payments += 1 - if candidate > end: - break - - return self.amount * Decimal(payments) - - -def monthly_candidates(start: datetime) -> Generator[datetime, None, None]: - current = datetime(start.year, start.month, 1) - while True: - yield current - if current.month == 12: - current = datetime(current.year + 1, 1, 1) - else: - current = datetime(current.year, current.month + 1, 1) - - -def simulate( - start: datetime, end: datetime, flows: tuple[Flow, ...] -) -> list[tuple[datetime, Decimal]]: - dates: list[datetime] = [] - values: list[Decimal] = [] - - for candidate in monthly_candidates(start): - if start <= candidate <= end: - dates.append(candidate) - - if candidate > end: - break - - for date in dates: - value = Decimal(0.0) - for flow in flows: - value += flow.integrate(start, date) - values.append(value) - - return [(date, values[index]) for index, date in enumerate(dates)] |