Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(fetch): change credit card to negative amount #147

Merged
merged 12 commits into from
Jan 13, 2024
Merged
16 changes: 16 additions & 0 deletions finalynx/assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ def __init__(
# Initialize the simulation timeline with the initial user events
self._timeline = Timeline(simulation, self.portfolio, self.buckets) if simulation else None

# Store the portfolio renders for each simulation date (if enabled)
self._timeline_renders: List[Any] = []

def add_source(self, source: SourceBaseLine) -> None:
"""Register a source, either defined in your own config or from the available Finalynx sources
using `from finalynx.fetch.source_any import SourceAny`."""
Expand Down Expand Up @@ -190,6 +193,8 @@ def _parse_args(self) -> None:
self.active_sources = str(args["--sources"]).split(",")
if args["--future"] and self.simulation:
self.simulation.print_final = True
if args["--each-step"] and self.simulation:
self.simulation.print_each_step = True
if args["--sim-steps"] and self.simulation:
self.simulation.step_years = int(args["--sim-steps"])
if args["--theme"]:
Expand Down Expand Up @@ -234,6 +239,11 @@ def run(self) -> None:
# Add the simulation summary to the performance panel in the console
dict_panels["performance"].add(self.simulate())

# If enabled by the user, print the portfolio at each simulation date
if self.simulation.print_each_step:
for element in self._timeline_renders:
renders.append(element)

# If enabled by the user, print the final portfolio after the simulation
if self.simulation.print_final:
renders.append(f"\nYour portfolio in {self.simulation.end_date}:")
Expand Down Expand Up @@ -299,8 +309,14 @@ def append_worth(year: int, amount: float) -> None:
self._timeline.goto(date(year, 12, 31))

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

# Render each intermediate simulation step
if self.simulation.print_each_step:
title = "Your portfolio in [bold]" + str(year) + "-12-31:[/]"
self._timeline_renders.append(Panel(self.render_mainframe(), title=title))

# Run until the end date and append the final result
self._timeline.run()
append_worth(self._timeline.current_date.year, self.portfolio.get_amount())
Expand Down
17 changes: 14 additions & 3 deletions finalynx/fetch/source_finary.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ def _authenticate(self) -> Optional[Session]:
if os.path.exists(finary_uapi.constants.COOKIE_FILENAME):
os.remove(finary_uapi.constants.COOKIE_FILENAME)
if os.path.exists(finary_uapi.constants.CREDENTIAL_FILE):
if not Confirm.ask("Reuse saved credentials? Otherwise, they will also be deleted.", default=True):
if not Confirm.ask(
"Reuse saved credentials? Otherwise, they will also be deleted.",
default=True,
):
os.remove(finary_uapi.constants.CREDENTIAL_FILE)

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

# Call the API and parse the response into `FetchLine` instances
with console.status(f"[bold {TH().ACCENT}]Fetching investments from Finary...", spinner_style=TH().ACCENT):
with console.status(
f"[bold {TH().ACCENT}]Fetching investments from Finary...",
spinner_style=TH().ACCENT,
):
response = ff.get_holdings_accounts(session)
if response["message"] == "OK":
for dict_account in response["result"]:
Expand All @@ -182,12 +188,17 @@ def _process_account(self, dict_account: Dict[str, Any], tree: Tree) -> None:
node = tree.add(account_name)

for item in dict_account["fiats"]:
if dict_account["bank_account_type"]["subtype"] == "credit":
amount = -item["display_current_value"]
else:
amount = item["display_current_value"]

self._register_fetchline(
tree_node=node,
name=account_name,
id=item["id"],
account=dict_account["institution"]["name"],
amount=item["display_current_value"],
amount=amount,
currency=item["fiat"]["symbol"],
)

Expand Down
3 changes: 2 additions & 1 deletion finalynx/simulator/recurrence.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ def __init__(
months = months if months is not None else 0
years = years if years is not None else 0

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

def _next_date(self, current_date: date) -> date:
return current_date + self._delta
Expand Down
3 changes: 3 additions & 0 deletions finalynx/simulator/timeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class Simulation:
# Whether to print the final portfolio state in the console after the simulation
print_final: bool = False

# Whether to print the final portfolio state in the console after the simulation
print_each_step: bool = False

# Display the portfolio's worth in the console every `step` years
step_years: int = 5

Expand Down
1 change: 1 addition & 0 deletions finalynx/usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ def main_filter(message: str) -> str:

--sim-steps=int Display the simulated portfolio's worth every X years, defaults to 5
--future Print the portfolio after the simulation has finished
--each-step Print the portfolio for each step of the simulation

"""
Loading