Skip to content

Instantly share code, notes, and snippets.

@DiTo97
Last active December 30, 2024 16:10
Show Gist options
  • Save DiTo97/8de5b0401ee131b3effc849c17b73e55 to your computer and use it in GitHub Desktop.
Save DiTo97/8de5b0401ee131b3effc849c17b73e55 to your computer and use it in GitHub Desktop.
savings simulation on poste.it options
import argparse
import bisect
from typing import Any
cumulative_deposit_config = {
"grossinterest": 2.6,
"deduction": 3.5 + 1.5,
}
individual_monthly_config = {
"grossinterestmap": {
18: 2.5,
24: 2.5,
36: 2.5,
48: 2.5,
60: 2.5,
72: 2.75,
84: 2.75,
96: 3.0,
108: 3.0,
120: 3.0,
132: 3.0,
144: 3.0,
156: 3.0,
168: 3.0,
180: 3.0,
192: 4.0,
204: 6.0,
216: 6.0
},
"deduction": 12.5,
}
def compounding(
deposit: float, netinterest: float, maxyears: int, instalment: float = 0.0
) -> float:
"""compounding interest effect"""
for _ in range(maxyears):
deposit += instalment
deposit *= (1 + netinterest / 100)
return deposit
def smallest_number_greater_or_equal(sequence: list[int], number: int) -> int:
"""finds the smallest number in a sequence that is greater than or equal to a number"""
index = bisect.bisect_left(sequence, number)
if index < len(sequence):
return sequence[index]
message = f"sequence has no number greater than or equal to {number}"
raise ValueError(message)
def cumulative_deposit(
instalment: float, maxyears: int, grossinterest: float, deduction: float
) -> float:
"""PostaFuturo da Grande deposit policy"""
assert 0 < maxyears, "deposit policy must last more than 0 years"
if instalment * 12 > 6000:
message = "instalment exceeds annual limit of 6000 €"
raise ValueError(message)
maxyears = min(maxyears, 10)
netinterest = grossinterest * (1 - deduction / 100)
deposit = instalment * 12 * maxyears
balance = compounding(deposit, netinterest, maxyears)
return balance
def individual_monthly_savings(
instalment: float,
maxyears: int,
grossinterestmap: dict[int, float],
deduction: float
) -> float:
"""Piccoli e Buoni savings plan"""
assert 0 < maxyears, "savings plan must last more than 0 years"
netinterestmap = {
key: value * (1 - deduction / 100) for key, value in grossinterestmap.items()
}
netinterestseq = sorted(netinterestmap.keys())
endmonth = 18 * 12
maxmonth = min(maxyears * 12, endmonth - 18)
balance = 0
for month in range(1, maxmonth):
month = endmonth - month + 1
month = smallest_number_greater_or_equal(netinterestseq, month)
netinterest = netinterestmap[month]
balance += compounding(instalment, netinterest, month // 12)
return balance
def commandline() -> dict[str, Any]:
parser = argparse.ArgumentParser()
parser.add_argument(
'--instalment',
type=float,
default=50.0,
help="fixed monthly deposit amount"
)
parser.add_argument(
'--cumulative-deposit-maxyears',
type=int,
default=10,
help="max duration of cumulative deposit"
)
parser.add_argument(
'--individual-monthly-maxyears',
type=int,
default=8,
help="max duration of individual monthly savings"
)
args, _ = parser.parse_known_args()
args = vars(args)
return args
def main(
instalment: float,
cumulative_deposit_maxyears: int,
individual_monthly_maxyears: int
):
balance = cumulative_deposit(
instalment, cumulative_deposit_maxyears, **cumulative_deposit_config
)
print("cumulative deposit", balance)
balance = individual_monthly_savings(
instalment, individual_monthly_maxyears, **individual_monthly_config
)
print("individual monthly", balance)
if __name__ == "__main__":
args = commandline()
main(**args)

children savings simulation

simulates two savings options for children: cumulative deposit and individual monthly savings.

The script goal is to help parents decide the best approach to maximize net profit for their children future.

overview

The script compares two poste.it savings options:

  1. cumulative deposit: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit1;
  2. individual monthly savings: monthly deposits that mature independently with varying interest rates2.

usage

python children-savings-simulation.py \
    --instalment [X] \
    --cumulative-deposit-maxyears [Y] \
    --individual-monthly-maxyears [Z]

For more information on parameters, see:

python children-savings-simulation.py --help

example

python children-savings-simulation.py \
    --instalment 50.0 \
    --cumulative-deposit-maxyears 10 \
    --individual-monthly-maxyears 8

Footnotes

  1. PostaFuturo da Grande deposit policy

  2. Piccoli e Buoni savings plan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment