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.

Revisions

  1. DiTo97 revised this gist Dec 30, 2024. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions ~README.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # children savings simulation
    # savings simulation

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

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

    @@ -15,13 +15,13 @@ what's the most profitable strategy?
    ## usage

    ```bash
    python children-savings-simulation.py --help
    python savings-simulation.py --help
    ```

    ## example

    ```bash
    python children-savings-simulation.py --instalment 50.0
    python savings-simulation.py --instalment 50.0
    ```

    [^1]: [PostaFuturo da Grande deposit policy](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html)
  2. DiTo97 renamed this gist Dec 30, 2024. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. DiTo97 revised this gist Sep 4, 2024. 3 changed files with 62 additions and 40 deletions.
    92 changes: 58 additions & 34 deletions !children-savings-simulation.py
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,8 @@
    import bisect
    from typing import Any

    from gekko import GEKKO


    cumulative_deposit_config = {
    "grossinterest": 2.6,
    @@ -58,33 +60,23 @@ def smallest_number_greater_or_equal(sequence: list[int], number: int) -> int:

    def cumulative_deposit(
    instalment: float, maxyears: int, grossinterest: float, deduction: float
    ) -> float:
    ) -> tuple[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
    return balance, deposit


    def individual_monthly_savings(
    instalment: float,
    maxyears: int,
    grossinterestmap: dict[int, float],
    deduction: float
    ) -> float:
    ) -> tuple[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()
    }
    @@ -94,17 +86,58 @@ def individual_monthly_savings(
    endmonth = 18 * 12
    maxmonth = min(maxyears * 12, endmonth - 18)

    balance = 0
    deposit = 0.0
    balance = 0.0

    for month in range(1, maxmonth):
    month = endmonth - month + 1
    month = smallest_number_greater_or_equal(netinterestseq, month)

    netinterest = netinterestmap[month]

    deposit += instalment
    balance += compounding(instalment, netinterest, month // 12)

    return balance
    return balance, deposit


    def simulation(instalment: float) -> tuple[int, int, int, int]:
    model = GEKKO(remote=False)

    cumulative_deposit_maxyears = model.Var(value=5, lb=0, ub=10, integer=True)
    individual_monthly_maxyears = model.Var(value=5, lb=0, ub=8, integer=True)
    n = model.Var(value=1, lb=0, ub=2, integer=True)
    m = model.Var(value=1, lb=0, ub=1, integer=True)

    def objective() -> float:
    cumulative_deposit_X = cumulative_deposit(
    instalment, cumulative_deposit_maxyears.value.value, **cumulative_deposit_config
    )
    individual_monthly_X = individual_monthly_savings(
    instalment, individual_monthly_maxyears.value.value, **individual_monthly_config
    )

    balance = n * cumulative_deposit_X[0] + m * individual_monthly_X[0]
    deposit = n * cumulative_deposit_X[1] + m * individual_monthly_X[1]

    return balance - deposit

    model.Maximize(objective())

    model.Equation(cumulative_deposit_maxyears + individual_monthly_maxyears <= 18)
    model.Equation(n + m <= 2)
    model.Equation(n * instalment * 12 <= 6000)

    model.options.SOLVER = 1 # https://stackoverflow.com/a/71580462

    model.solve(disp=False)

    return (
    cumulative_deposit_maxyears.value.value[0],
    individual_monthly_maxyears.value.value[0],
    n.value.value[0],
    m.value.value[0],
    )


    def commandline() -> dict[str, Any]:
    @@ -117,39 +150,30 @@ def commandline() -> dict[str, Any]:
    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
    ):
    def main(instalment: float):
    (
    cumulative_deposit_maxyears,
    individual_monthly_maxyears,
    n,
    m
    ) = map(int, simulation(instalment))

    balance = cumulative_deposit(
    instalment, cumulative_deposit_maxyears, **cumulative_deposit_config
    )
    print("# of cumulative deposit", n)
    print("cumulative deposit", balance)

    balance = individual_monthly_savings(
    instalment, individual_monthly_maxyears, **individual_monthly_config
    )
    print("# of individual monthly", m)
    print("individual monthly", balance)


    9 changes: 3 additions & 6 deletions ~README.md
    Original file line number Diff line number Diff line change
    @@ -6,11 +6,11 @@ The script will help parents decide the best approach to **maximize net profit**

    ## overview

    The script compares two interesting poste.it savings options:
    The script simulates two interesting poste.it savings options:
    1. **cumulative deposit**: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit[^1];
    2. **individual monthly savings**: monthly deposits that mature independently with varying interest rates[^2].

    what's the most profitable approach? maybe a combination of the two?
    what's the most profitable strategy?

    ## usage

    @@ -21,10 +21,7 @@ python children-savings-simulation.py --help
    ## example

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

    [^1]: [PostaFuturo da Grande deposit policy](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html)
    1 change: 1 addition & 0 deletions ~requirements.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    gekko
  4. DiTo97 revised this gist Sep 4, 2024. No changes.
  5. DiTo97 revised this gist Sep 4, 2024. No changes.
  6. DiTo97 revised this gist Sep 4, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ~README.md
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ The script will help parents decide the best approach to **maximize net profit**

    ## overview

    The script compares two interesting [poste.it](poste.it) savings options:
    The script compares two interesting poste.it savings options:
    1. **cumulative deposit**: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit[^1];
    2. **individual monthly savings**: monthly deposits that mature independently with varying interest rates[^2].

  7. DiTo97 revised this gist Sep 4, 2024. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion ~README.md
    Original file line number Diff line number Diff line change
    @@ -2,14 +2,16 @@

    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.
    The script will help parents decide the best approach to **maximize net profit** for their children future.

    ## overview

    The script compares two interesting [poste.it](poste.it) savings options:
    1. **cumulative deposit**: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit[^1];
    2. **individual monthly savings**: monthly deposits that mature independently with varying interest rates[^2].

    what's the most profitable approach? maybe a combination of the two?

    ## usage

    ```bash
  8. DiTo97 revised this gist Sep 4, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ~README.md
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ The script goal is to help parents decide the best approach to **maximize net pr

    ## overview

    The script compares two different [poste.it](poste.it) savings options:
    The script compares two interesting [poste.it](poste.it) savings options:
    1. **cumulative deposit**: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit[^1];
    2. **individual monthly savings**: monthly deposits that mature independently with varying interest rates[^2].

  9. DiTo97 revised this gist Sep 4, 2024. 1 changed file with 1 addition and 10 deletions.
    11 changes: 1 addition & 10 deletions ~README.md
    Original file line number Diff line number Diff line change
    @@ -6,21 +6,12 @@ The script goal is to help parents decide the best approach to **maximize net pr

    ## overview

    The script compares two [poste.it](poste.it) savings options:
    The script compares two different [poste.it](poste.it) savings options:
    1. **cumulative deposit**: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit[^1];
    2. **individual monthly savings**: monthly deposits that mature independently with varying interest rates[^2].

    ## usage

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

    For more information on parameters, see:

    ```bash
    python children-savings-simulation.py --help
    ```
  10. DiTo97 revised this gist Sep 4, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ~README.md
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ The script goal is to help parents decide the best approach to **maximize net pr

    ## overview

    The script compares two savings options from [poste.it](poste.it):
    The script compares two [poste.it](poste.it) savings options:
    1. **cumulative deposit**: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit[^1];
    2. **individual monthly savings**: monthly deposits that mature independently with varying interest rates[^2].

  11. DiTo97 revised this gist Sep 4, 2024. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions !children-savings-simulation.py
    Original file line number Diff line number Diff line change
    @@ -45,7 +45,7 @@ def compounding(
    return deposit


    def find_smallest_number_greater_or_equal(sequence: list[int], number: int) -> int:
    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)

    @@ -98,7 +98,7 @@ def individual_monthly_savings(

    for month in range(1, maxmonth):
    month = endmonth - month + 1
    month = find_smallest_number_greater_or_equal(netinterestseq, month)
    month = smallest_number_greater_or_equal(netinterestseq, month)

    netinterest = netinterestmap[month]

  12. DiTo97 revised this gist Sep 4, 2024. No changes.
  13. DiTo97 revised this gist Sep 4, 2024. 2 changed files with 76 additions and 69 deletions.
    58 changes: 52 additions & 6 deletions !savings_simulation.py → !children-savings-simulation.py
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@
    import argparse
    import bisect
    from typing import Any


    cumulative_deposit_config = {
    @@ -7,7 +9,7 @@
    }


    individual_monthly_savings_config = {
    individual_monthly_config = {
    "grossinterestmap": {
    18: 2.5,
    24: 2.5,
    @@ -61,7 +63,7 @@ def cumulative_deposit(
    assert 0 < maxyears, "deposit policy must last more than 0 years"

    if instalment * 12 > 6000:
    message = "instalment exceeds annual limit"
    message = "instalment exceeds annual limit of 6000 €"
    raise ValueError(message)

    maxyears = min(maxyears, 10)
    @@ -105,8 +107,52 @@ def individual_monthly_savings(
    return balance


    if __name__ == "__main__":
    instalment = 50.0
    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)

    print(cumulative_deposit(instalment, 10, **cumulative_deposit_config))
    print(individual_monthly_savings(instalment, 8, **individual_monthly_savings_config))
    balance = individual_monthly_savings(
    instalment, individual_monthly_maxyears, **individual_monthly_config
    )
    print("individual monthly", balance)


    if __name__ == "__main__":
    args = commandline()
    main(**args)
    87 changes: 24 additions & 63 deletions ~README.md
    Original file line number Diff line number Diff line change
    @@ -1,77 +1,38 @@
    Here are the links to the relevant pages for the savings options you mentioned:
    # children savings simulation

    - **Piccoli e Buoni Bonuses**: [Piccoli e Buoni](https://risparmiopostale.poste.it/prodotti/piccoli-e-buoni.html)
    - **PostaFuturo da Grande Deposit Policy**: [PostaFuturo da Grande](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html) ¹
    simulates two savings options for children: **cumulative deposit** and **individual monthly savings**.

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

    ---
    ## overview

    # Children's Savings Simulation
    The script compares two savings options from [poste.it](poste.it):
    1. **cumulative deposit**: policy with a fixed monthly rate, compounded annually, with a maximum annual deposit limit[^1];
    2. **individual monthly savings**: monthly deposits that mature independently with varying interest rates[^2].

    This Python script simulates two savings options for children's future needs: cumulative deposits and individual monetary bonuses. The goal is to help parents decide the best approach to maximize net profit for their children's future expenses.

    ## Description

    The script compares two savings options:
    1. **Cumulative Deposit**: A deposit with a fixed monthly rate, compounded annually, with a maximum annual deposit limit.
    2. **Individual Monetary Bonuses**: Monthly deposits that mature independently with varying interest rates depending on the subscription period.

    ## Parameters

    - `monthly_rate`: The fixed monthly deposit amount.
    - `years_deposit_1`: Duration of the first cumulative deposit.
    - `years_deposit_2`: Duration of the second cumulative deposit.
    - `gross_interest_deposit`: Gross annual interest rate for the cumulative deposit.
    - `costs_deposit`: Annual costs as a percentage of the deposit.
    - `taxes_deposit`: Tax rate on the interest earned.
    - `interest_rates_bonuses`: List of annual gross interest rates for the individual bonuses.
    - `taxes_bonuses`: Tax rate on the interest earned from bonuses.

    ## Usage

    1. **Install Python**: Ensure you have Python installed on your system.
    2. **Run the Script**: Execute the script using a Python interpreter.
    ## usage

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

    3. **Adjust Parameters**: Modify the parameters in the script to fit your specific needs.

    ## Example

    ```python
    monthly_rate = 500 # Example monthly rate
    years_deposit_1 = 10
    years_deposit_2 = 10
    gross_interest_deposit = 2.6
    costs_deposit = 0.06
    taxes_deposit = 0.125
    For more information on parameters, see:

    interest_rates_bonuses = [2.5, 2.5, 2.5, 2.5, 2.5, 2.75, 2.75, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 6.0, 6.0]
    taxes_bonuses = 0.125
    ```bash
    python children-savings-simulation.py --help
    ```

    ## Links

    - [Piccoli e Buoni Bonuses](https://risparmiopostale.poste.it/prodotti/piccoli-e-buoni.html)
    - [PostaFuturo da Grande Deposit Policy](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html)

    ## Date

    This README was created on September 3, 2024.
    ## example

    ---

    Feel free to adjust the parameters and run the simulation to see different scenarios. Let me know if you need any further assistance!
    ```bash
    python children-savings-simulation.py \
    --instalment 50.0 \
    --cumulative-deposit-maxyears 10 \
    --individual-monthly-maxyears 8
    ```

    Source: Conversation with Copilot, 9/3/2024
    (1) Piani di risparmio postale Piccoli e Buoni. https://risparmiopostale.poste.it/prodotti/piccoli-e-buoni.html.
    (2) Risparmio per Bambini | Poste Vita. https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html.
    (3) postafuturo dagrande - Poste Italiane. https://www.poste.it/files/1476488789823/SET_PFuturo_DaGrande.pdf.
    (4) postafuturo da grande - Poste Italiane. https://www.poste.it/files/1473800562073/Fascicolo_PFdagrande_dal_25052018_al_31122018.pdf.
    (5) Buoni fruttiferi e Libretti di risparmio postale per i minori - Poste .... https://buonielibretti.poste.it/gamma/per-i-piu-piccoli.html.
    (6) Buono fruttifero postale dedicato ai minori - Poste Italiane. https://risparmiopostale.poste.it/prodotti/buono-minori.html.
    (7) Poste Italiane: cos'è "Piccoli e Buoni", il piano di risparmi dedicato .... https://www.bonificobancario.it/2022/06/08/poste-italiane-piccoli-e-buoni-piano-di-risparmi/.
    (8) github.com. https://github.com/DorskFR/async-dbnomics/tree/be4099faf152393d3de7b379f59e4a311447fac2/tests%2Fmock_api_data.py.
    [^1]: [PostaFuturo da Grande deposit policy](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html)
    [^2]: [Piccoli e Buoni savings plan](https://risparmiopostale.poste.it/prodotti/piccoli-e-buoni.html)
  14. DiTo97 revised this gist Sep 4, 2024. 1 changed file with 112 additions and 44 deletions.
    156 changes: 112 additions & 44 deletions !savings_simulation.py
    Original file line number Diff line number Diff line change
    @@ -1,44 +1,112 @@
    import numpy as np

    def cumulative_deposit(monthly_rate, years, gross_interest, costs, taxes):
    net_interest = gross_interest * (1 - taxes - costs)
    total_amount = 0
    for year in range(years):
    for month in range(12):
    total_amount += monthly_rate
    total_amount *= (1 + net_interest / 12 / 100)
    return total_amount

    def individual_bonuses(monthly_rate, years, interest_rates, taxes):
    total_amount = 0
    for year in range(years):
    for month in range(12):
    bonus_amount = monthly_rate
    for i in range(year, years):
    bonus_amount *= (1 + interest_rates[i] * (1 - taxes) / 12 / 100)
    total_amount += bonus_amount
    return total_amount

    # Parameters
    monthly_rate = 500 # Example monthly rate
    years_deposit_1 = 10
    years_deposit_2 = 10
    gross_interest_deposit = 2.6
    costs_deposit = 0.06
    taxes_deposit = 0.125

    if monthly_rate * 2 * 12 > 6000:
    raise ValueError("Monthly rate exceeds the annual limit in overlapping years.")


    interest_rates_bonuses = [2.5, 2.5, 2.5, 2.5, 2.5, 2.75, 2.75, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 6.0, 6.0]
    taxes_bonuses = 0.125

    # Simulation
    total_cumulative = cumulative_deposit(monthly_rate, years_deposit_1, gross_interest_deposit, costs_deposit, taxes_deposit)
    total_cumulative += cumulative_deposit(monthly_rate, years_deposit_2, gross_interest_deposit, costs_deposit, taxes_deposit)

    total_bonuses = individual_bonuses(monthly_rate, 18, interest_rates_bonuses, taxes_bonuses)

    print(f"Total amount with cumulative deposit: €{total_cumulative:.2f}")
    print(f"Total amount with individual bonuses: €{total_bonuses:.2f}")
    import bisect


    cumulative_deposit_config = {
    "grossinterest": 2.6,
    "deduction": 3.5 + 1.5,
    }


    individual_monthly_savings_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 find_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"
    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 = find_smallest_number_greater_or_equal(netinterestseq, month)

    netinterest = netinterestmap[month]

    balance += compounding(instalment, netinterest, month // 12)

    return balance


    if __name__ == "__main__":
    instalment = 50.0

    print(cumulative_deposit(instalment, 10, **cumulative_deposit_config))
    print(individual_monthly_savings(instalment, 8, **individual_monthly_savings_config))
  15. DiTo97 created this gist Sep 3, 2024.
    44 changes: 44 additions & 0 deletions !savings_simulation.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    import numpy as np

    def cumulative_deposit(monthly_rate, years, gross_interest, costs, taxes):
    net_interest = gross_interest * (1 - taxes - costs)
    total_amount = 0
    for year in range(years):
    for month in range(12):
    total_amount += monthly_rate
    total_amount *= (1 + net_interest / 12 / 100)
    return total_amount

    def individual_bonuses(monthly_rate, years, interest_rates, taxes):
    total_amount = 0
    for year in range(years):
    for month in range(12):
    bonus_amount = monthly_rate
    for i in range(year, years):
    bonus_amount *= (1 + interest_rates[i] * (1 - taxes) / 12 / 100)
    total_amount += bonus_amount
    return total_amount

    # Parameters
    monthly_rate = 500 # Example monthly rate
    years_deposit_1 = 10
    years_deposit_2 = 10
    gross_interest_deposit = 2.6
    costs_deposit = 0.06
    taxes_deposit = 0.125

    if monthly_rate * 2 * 12 > 6000:
    raise ValueError("Monthly rate exceeds the annual limit in overlapping years.")


    interest_rates_bonuses = [2.5, 2.5, 2.5, 2.5, 2.5, 2.75, 2.75, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 6.0, 6.0]
    taxes_bonuses = 0.125

    # Simulation
    total_cumulative = cumulative_deposit(monthly_rate, years_deposit_1, gross_interest_deposit, costs_deposit, taxes_deposit)
    total_cumulative += cumulative_deposit(monthly_rate, years_deposit_2, gross_interest_deposit, costs_deposit, taxes_deposit)

    total_bonuses = individual_bonuses(monthly_rate, 18, interest_rates_bonuses, taxes_bonuses)

    print(f"Total amount with cumulative deposit: €{total_cumulative:.2f}")
    print(f"Total amount with individual bonuses: €{total_bonuses:.2f}")
    77 changes: 77 additions & 0 deletions ~README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    Here are the links to the relevant pages for the savings options you mentioned:

    - **Piccoli e Buoni Bonuses**: [Piccoli e Buoni](https://risparmiopostale.poste.it/prodotti/piccoli-e-buoni.html)
    - **PostaFuturo da Grande Deposit Policy**: [PostaFuturo da Grande](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html) ¹

    ### README

    ---

    # Children's Savings Simulation

    This Python script simulates two savings options for children's future needs: cumulative deposits and individual monetary bonuses. The goal is to help parents decide the best approach to maximize net profit for their children's future expenses.

    ## Description

    The script compares two savings options:
    1. **Cumulative Deposit**: A deposit with a fixed monthly rate, compounded annually, with a maximum annual deposit limit.
    2. **Individual Monetary Bonuses**: Monthly deposits that mature independently with varying interest rates depending on the subscription period.

    ## Parameters

    - `monthly_rate`: The fixed monthly deposit amount.
    - `years_deposit_1`: Duration of the first cumulative deposit.
    - `years_deposit_2`: Duration of the second cumulative deposit.
    - `gross_interest_deposit`: Gross annual interest rate for the cumulative deposit.
    - `costs_deposit`: Annual costs as a percentage of the deposit.
    - `taxes_deposit`: Tax rate on the interest earned.
    - `interest_rates_bonuses`: List of annual gross interest rates for the individual bonuses.
    - `taxes_bonuses`: Tax rate on the interest earned from bonuses.

    ## Usage

    1. **Install Python**: Ensure you have Python installed on your system.
    2. **Run the Script**: Execute the script using a Python interpreter.

    ```bash
    python savings_simulation.py
    ```

    3. **Adjust Parameters**: Modify the parameters in the script to fit your specific needs.

    ## Example

    ```python
    monthly_rate = 500 # Example monthly rate
    years_deposit_1 = 10
    years_deposit_2 = 10
    gross_interest_deposit = 2.6
    costs_deposit = 0.06
    taxes_deposit = 0.125

    interest_rates_bonuses = [2.5, 2.5, 2.5, 2.5, 2.5, 2.75, 2.75, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 6.0, 6.0]
    taxes_bonuses = 0.125
    ```

    ## Links

    - [Piccoli e Buoni Bonuses](https://risparmiopostale.poste.it/prodotti/piccoli-e-buoni.html)
    - [PostaFuturo da Grande Deposit Policy](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html)

    ## Date

    This README was created on September 3, 2024.

    ---

    Feel free to adjust the parameters and run the simulation to see different scenarios. Let me know if you need any further assistance!

    Source: Conversation with Copilot, 9/3/2024
    (1) Piani di risparmio postale Piccoli e Buoni. https://risparmiopostale.poste.it/prodotti/piccoli-e-buoni.html.
    (2) Risparmio per Bambini | Poste Vita. https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html.
    (3) postafuturo dagrande - Poste Italiane. https://www.poste.it/files/1476488789823/SET_PFuturo_DaGrande.pdf.
    (4) postafuturo da grande - Poste Italiane. https://www.poste.it/files/1473800562073/Fascicolo_PFdagrande_dal_25052018_al_31122018.pdf.
    (5) Buoni fruttiferi e Libretti di risparmio postale per i minori - Poste .... https://buonielibretti.poste.it/gamma/per-i-piu-piccoli.html.
    (6) Buono fruttifero postale dedicato ai minori - Poste Italiane. https://risparmiopostale.poste.it/prodotti/buono-minori.html.
    (7) Poste Italiane: cos'è "Piccoli e Buoni", il piano di risparmi dedicato .... https://www.bonificobancario.it/2022/06/08/poste-italiane-piccoli-e-buoni-piano-di-risparmi/.
    (8) github.com. https://github.com/DorskFR/async-dbnomics/tree/be4099faf152393d3de7b379f59e4a311447fac2/tests%2Fmock_api_data.py.