summaryrefslogtreecommitdiff
path: root/finance
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2024-09-08 17:02:33 +0200
committerxengineering <me@xengineering.eu>2024-09-08 17:21:32 +0200
commit458a24d09f95eefb161728d9676ecdfca30e3f5e (patch)
treed3260b2531f42a6e8335661312661302b9653730 /finance
parent6973093a2b80b4fb9e216d1b3e329dd4c2badc7c (diff)
downloadfinance-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')
-rw-r--r--finance/model.py12
-rw-r--r--finance/simulate.py (renamed from finance/flow.py)41
-rw-r--r--finance/test_simulate.py (renamed from finance/test_flow.py)5
3 files changed, 32 insertions, 26 deletions
diff --git a/finance/model.py b/finance/model.py
new file mode 100644
index 0000000..8bf2e3d
--- /dev/null
+++ b/finance/model.py
@@ -0,0 +1,12 @@
+import dataclasses
+import datetime
+import decimal
+
+
+@dataclasses.dataclass(kw_only=True, frozen=True)
+class Flow:
+ """Time-discrete flow of money paid on the first day of a month"""
+
+ amount: decimal.Decimal
+ since: None | datetime.datetime
+ until: None | datetime.datetime
diff --git a/finance/flow.py b/finance/simulate.py
index c6b28c0..3f8e3ad 100644
--- a/finance/flow.py
+++ b/finance/simulate.py
@@ -1,37 +1,30 @@
-import dataclasses
from datetime import datetime
from decimal import Decimal
from typing import Generator
+from finance.model import Flow
-@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(flow: Flow, start: datetime, end: datetime) -> Decimal:
+ """Integrate the flow between two dates to an amount of money"""
- def integrate(self, start: datetime, end: datetime) -> Decimal:
- """Integrate the flow between two dates to an amount of money"""
+ payments: int = 0
- payments: int = 0
+ if flow.since is not None:
+ if start < flow.since:
+ start = flow.since
- if self.since is not None:
- if start < self.since:
- start = self.since
+ if flow.until is not None:
+ if end > flow.until:
+ end = flow.until
- 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
+ for candidate in monthly_candidates(start):
+ if start <= candidate <= end:
+ payments += 1
+ if candidate > end:
+ break
- return self.amount * Decimal(payments)
+ return flow.amount * Decimal(payments)
def monthly_candidates(start: datetime) -> Generator[datetime, None, None]:
@@ -60,7 +53,7 @@ def simulate(
for date in dates:
value = Decimal(0.0)
for flow in flows:
- value += flow.integrate(start, date)
+ value += integrate(flow, start, date)
values.append(value)
return [(date, values[index]) for index, date in enumerate(dates)]
diff --git a/finance/test_flow.py b/finance/test_simulate.py
index 91d189b..3b79c99 100644
--- a/finance/test_flow.py
+++ b/finance/test_simulate.py
@@ -1,7 +1,8 @@
from datetime import datetime
from decimal import Decimal
-from finance.flow import Flow, simulate
+from finance.model import Flow
+from finance.simulate import simulate, integrate
def test_flow_integration() -> None:
@@ -25,7 +26,7 @@ def test_flow_integration() -> None:
)
for test in tests:
- assert fl.integrate(start=test[0], end=test[1]) == test[2]
+ assert integrate(fl, start=test[0], end=test[1]) == test[2]
def test_simulate() -> None: