Last active
December 30, 2024 16:10
-
-
Save DiTo97/8de5b0401ee131b3effc849c17b73e55 to your computer and use it in GitHub Desktop.
Revisions
-
DiTo97 revised this gist
Dec 30, 2024 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ # savings simulation 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 savings-simulation.py --help ``` ## example ```bash python savings-simulation.py --instalment 50.0 ``` [^1]: [PostaFuturo da Grande deposit policy](https://postevita.poste.it/soluzioni-investimento-assicurativo/postafuturo-da-grande.html) -
DiTo97 renamed this gist
Dec 30, 2024 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
DiTo97 revised this gist
Sep 4, 2024 . 3 changed files with 62 additions and 40 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 ) -> tuple[float, float]: """PostaFuturo da Grande deposit policy""" netinterest = grossinterest * (1 - deduction / 100) deposit = instalment * 12 * maxyears balance = compounding(deposit, netinterest, maxyears) return balance, deposit def individual_monthly_savings( instalment: float, maxyears: int, grossinterestmap: dict[int, float], deduction: float ) -> tuple[float, float]: """Piccoli e Buoni savings plan""" 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) 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, 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" ) args, _ = parser.parse_known_args() args = vars(args) return args 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) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 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 strategy? ## usage @@ -21,10 +21,7 @@ python children-savings-simulation.py --help ## example ```bash 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) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ gekko -
DiTo97 revised this gist
Sep 4, 2024 . No changes.There are no files selected for viewing
-
DiTo97 revised this gist
Sep 4, 2024 . No changes.There are no files selected for viewing
-
DiTo97 revised this gist
Sep 4, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 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]. -
DiTo97 revised this gist
Sep 4, 2024 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 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 -
DiTo97 revised this gist
Sep 4, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 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]. -
DiTo97 revised this gist
Sep 4, 2024 . 1 changed file with 1 addition and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 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 --help ``` -
DiTo97 revised this gist
Sep 4, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 [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]. -
DiTo97 revised this gist
Sep 4, 2024 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -45,7 +45,7 @@ def compounding( 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) @@ -98,7 +98,7 @@ def individual_monthly_savings( for month in range(1, maxmonth): month = endmonth - month + 1 month = smallest_number_greater_or_equal(netinterestseq, month) netinterest = netinterestmap[month] -
DiTo97 revised this gist
Sep 4, 2024 . No changes.There are no files selected for viewing
-
DiTo97 revised this gist
Sep 4, 2024 . 2 changed files with 76 additions and 69 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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_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 of 6000 €" raise ValueError(message) maxyears = min(maxyears, 10) @@ -105,8 +107,52 @@ def individual_monthly_savings( 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) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,77 +1,38 @@ # 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 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]. ## 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 ``` ## example ```bash python children-savings-simulation.py \ --instalment 50.0 \ --cumulative-deposit-maxyears 10 \ --individual-monthly-maxyears 8 ``` [^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) -
DiTo97 revised this gist
Sep 4, 2024 . 1 changed file with 112 additions and 44 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,44 +1,112 @@ 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)) -
DiTo97 created this gist
Sep 3, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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}") This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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.