Skip to content

Commit d9478db

Browse files
authored
fix(fetch): change credit card to negative amount (#147)
* Change credit card to negative amount * Rollback source_finary.py * Change credit card to negative amount * [pre-commit.ci lite] apply automatic fixes * Add a flag to allow the potfolio restitution for each simulation step * Add a flag to allow the potfolio restitution for each simulation step * fix: correct the recurrence function to be more precise on Yearly recurrence * [pre-commit.ci lite] apply automatic fixes * style: minor refactoring
1 parent c2d7d82 commit d9478db

5 files changed

Lines changed: 36 additions & 4 deletions

File tree

finalynx/assistant.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ def __init__(
125125
# Initialize the simulation timeline with the initial user events
126126
self._timeline = Timeline(simulation, self.portfolio, self.buckets) if simulation else None
127127

128+
# Store the portfolio renders for each simulation date (if enabled)
129+
self._timeline_renders: List[Any] = []
130+
128131
def add_source(self, source: SourceBaseLine) -> None:
129132
"""Register a source, either defined in your own config or from the available Finalynx sources
130133
using `from finalynx.fetch.source_any import SourceAny`."""
@@ -190,6 +193,8 @@ def _parse_args(self) -> None:
190193
self.active_sources = str(args["--sources"]).split(",")
191194
if args["--future"] and self.simulation:
192195
self.simulation.print_final = True
196+
if args["--each-step"] and self.simulation:
197+
self.simulation.print_each_step = True
193198
if args["--sim-steps"] and self.simulation:
194199
self.simulation.step_years = int(args["--sim-steps"])
195200
if args["--theme"]:
@@ -234,6 +239,11 @@ def run(self) -> None:
234239
# Add the simulation summary to the performance panel in the console
235240
dict_panels["performance"].add(self.simulate())
236241

242+
# If enabled by the user, print the portfolio at each simulation date
243+
if self.simulation.print_each_step:
244+
for element in self._timeline_renders:
245+
renders.append(element)
246+
237247
# If enabled by the user, print the final portfolio after the simulation
238248
if self.simulation.print_final:
239249
renders.append(f"\nYour portfolio in {self.simulation.end_date}:")
@@ -299,8 +309,14 @@ def append_worth(year: int, amount: float) -> None:
299309
self._timeline.goto(date(year, 12, 31))
300310

301311
if (year - date.today().year) % self.simulation.step_years == 0:
312+
# Append the portfolio's worth to the Worth tree
302313
append_worth(year, self.portfolio.get_amount())
303314

315+
# Render each intermediate simulation step
316+
if self.simulation.print_each_step:
317+
title = "Your portfolio in [bold]" + str(year) + "-12-31:[/]"
318+
self._timeline_renders.append(Panel(self.render_mainframe(), title=title))
319+
304320
# Run until the end date and append the final result
305321
self._timeline.run()
306322
append_worth(self._timeline.current_date.year, self.portfolio.get_amount())

finalynx/fetch/source_finary.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ def _authenticate(self) -> Optional[Session]:
8484
if os.path.exists(finary_uapi.constants.COOKIE_FILENAME):
8585
os.remove(finary_uapi.constants.COOKIE_FILENAME)
8686
if os.path.exists(finary_uapi.constants.CREDENTIAL_FILE):
87-
if not Confirm.ask("Reuse saved credentials? Otherwise, they will also be deleted.", default=True):
87+
if not Confirm.ask(
88+
"Reuse saved credentials? Otherwise, they will also be deleted.",
89+
default=True,
90+
):
8891
os.remove(finary_uapi.constants.CREDENTIAL_FILE)
8992

9093
# Get the user credentials if there's no session yet (through environment variables or manual input)
@@ -171,7 +174,10 @@ def _fetch_data(self, tree: Tree) -> None:
171174
raise ValueError("Finary signin failed.")
172175

173176
# Call the API and parse the response into `FetchLine` instances
174-
with console.status(f"[bold {TH().ACCENT}]Fetching investments from Finary...", spinner_style=TH().ACCENT):
177+
with console.status(
178+
f"[bold {TH().ACCENT}]Fetching investments from Finary...",
179+
spinner_style=TH().ACCENT,
180+
):
175181
response = ff.get_holdings_accounts(session)
176182
if response["message"] == "OK":
177183
for dict_account in response["result"]:
@@ -182,12 +188,17 @@ def _process_account(self, dict_account: Dict[str, Any], tree: Tree) -> None:
182188
node = tree.add(account_name if not dict_account["fiats"] else dict_account["institution"]["name"])
183189

184190
for item in dict_account["fiats"]:
191+
if dict_account["bank_account_type"]["subtype"] == "credit":
192+
amount = -item["display_current_value"]
193+
else:
194+
amount = item["display_current_value"]
195+
185196
self._register_fetchline(
186197
tree_node=node,
187198
name=account_name,
188199
id=item["id"],
189200
account=dict_account["institution"]["name"],
190-
amount=item["display_current_value"],
201+
amount=amount,
191202
currency=item["fiat"]["symbol"],
192203
)
193204

finalynx/simulator/recurrence.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ def __init__(
3636
months = months if months is not None else 0
3737
years = years if years is not None else 0
3838

39-
self._delta = timedelta(days, weeks=4 * months + 52 * years)
39+
# Add decimals to stay on the same day (otherwise Yearly goes to 30/12)
40+
self._delta = timedelta(days, weeks=4.3452 * months + 52.1429 * years + 0.1429)
4041

4142
def _next_date(self, current_date: date) -> date:
4243
return current_date + self._delta

finalynx/simulator/timeline.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class Simulation:
3535
# Whether to print the final portfolio state in the console after the simulation
3636
print_final: bool = False
3737

38+
# Whether to print the final portfolio state in the console after the simulation
39+
print_each_step: bool = False
40+
3841
# Display the portfolio's worth in the console every `step` years
3942
step_years: int = 5
4043

finalynx/usage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,6 @@ def main_filter(message: str) -> str:
5656
5757
--sim-steps=int Display the simulated portfolio's worth every X years, defaults to 5
5858
--future Print the portfolio after the simulation has finished
59+
--each-step Print the portfolio for each step of the simulation
5960
6061
"""

0 commit comments

Comments
 (0)