Skip to content

Commit

Permalink
fix(simulation): add salary income & expense growth
Browse files Browse the repository at this point in the history
  • Loading branch information
MadeInPierre committed Aug 10, 2023
1 parent c29a80a commit 84e6524
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion finalynx/simulator/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ def __init__(
recurrence: Optional[RecurrenceBase] = None,
name: Optional[str] = None,
) -> None:
"""An event associates a date to an action."""
"""An event associates a date to an action.
:param action: `Action` instance to execute.
:param planned_date: Date when the action should be executed.
:param recurrence: Optional recurrence to repeat the action every month/year/other.
:param name: Optional name of the event, defaults to the action's name.
"""
self.name = name if name else action.name
self.planned_date = planned_date if planned_date is not None else date.today()
self.recurrence = recurrence
Expand Down Expand Up @@ -54,8 +59,34 @@ def __init__(
day_of_the_month: int = 1,
start_date: Optional[date] = None,
end_date: Optional[date] = None,
income_growth: float = 0,
expenses_follow: float = 0,
name: str = "Salary",
) -> None:
"""Add your salary to your account every month (nicer shortcut). The salary amount can
grow with a fixed percentage every year. The expenses can follow the income gains with a
fixed percentage every year (0 means every new gain is invested, 100 means every gain is
used to increase your way of life).
:param target_line: `Line` reference in the portfolio to add the salary to.
:param income: Monthly salary amount.
:param expenses: Monthly expenses amount.
:param day_of_the_month: Day of the month to add the salary to the portfolio.
:param start_date: When to start adding the salary to the portfolio, defaults to today's next month.
:param end_date: When to stop adding the salary to the portfolio, defaults to no end date.
:param income_growth: Annual salary growth rate.
:param expenses_follow: Annual expenses growth rate (percentage of income gains reinvested).
:param name: Name of the event.
"""
self.target_line = target_line
self.day_of_the_month = day_of_the_month
self.start_date = start_date

self.income = income
self.expenses = expenses
self.income_growth = income_growth
self.expenses_follow = expenses_follow

super().__init__(
AddLineAmount(target_line, income - expenses),
start_date
Expand All @@ -65,6 +96,29 @@ def __init__(
name,
)

def apply(self, portfolio: Portfolio) -> List["Event"]:
"""Update the salary amount with the growth rates. Creates a new salary
with the updated income/expense amounts depending on the growth rates."""
self.action.apply(portfolio)

assert self.recurrence is not None # Needed for mypy
if next_date := self.recurrence.next(self.planned_date):
income_gains = self.income * self.income_growth / (12 * 100)
return [
Salary(
target_line=self.target_line,
income=self.income + income_gains,
expenses=self.expenses + income_gains * self.expenses_follow / 100,
day_of_the_month=self.day_of_the_month,
start_date=next_date,
end_date=self.recurrence.until,
income_growth=self.income_growth,
expenses_follow=self.expenses_follow,
name=self.name,
)
]
return []


class YearlyPerformance(Event):
"""Earn your investments' interests at the end of each year."""
Expand Down

0 comments on commit 84e6524

Please sign in to comment.