Simulare un portafoglio di finanza personale in Python

Simulare un portafoglio di finanza personale in Python – Parte 1

Sommario

In questo articolo descriviamo come implementare un portafoglio o modello di finanza personale in Python per simulare l’andamento nel futuro secondo specifiche variabili di input. Usiamo le variabili per specificare l’attuale base patrimoniale investibile, lo stipendio annuale, gli afflussi e deflussi mensili previsti e una serie di altri valori rilevanti.

Questo articolo fa parte della serie di articoli relativi all’Asset Management in Python.

Simulare il reddito personale

Iniziamo, dopo aver importato le librerie necessarie, a modellare i flussi di capitale nel tempo.

				
					import pandas as pd
import numpy as np
import random
import pandas_datareader.data as web
import datetime
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (12,6)

# Importa il modello dei flussi
inflows = {'active_annual_income':50_000}
variables = {'start_date' : "01/01/2020",
             'years': 10}
income_gains_storage = []
months = variables['years'] * 12

for month in range(months):
    income = inflows['active_annual_income'] / 12
    income_gains_storage.append(income)
plt.plot(pd.Series(income_gains_storage).cumsum())
plt.show()
				
			
Simulare un portafoglio di finanza personale in Python

Sembra un risultato piuttosto semplice. Il reddito cumulativo che abbiamo guadagnato in 10 anni, con uno stipendio annuo di 50.000, corrisponde semplicemente a 10 x 50.000 = 500.000. Possiamo introdurre una logica per conteggiare le tasse e la fiscalità su almeno una parte (troppa) del reddito. Per il momento, per semplicità, ipotizziamo un’aliquota flat tax del 25%. 

Simulare le imposte sul reddito

Naturalmente la maggior parte dei paesi prevede una scala mobile di fasce di reddito soggette ad aliquote fiscali crescenti quanto più si guadagna. Possiamo tornare su questo argomento più tardi e vedere se possiamo implementare qualcosa di più realistico, ma per ora restiamo fedeli al nostro 25% fisso.

Aggiungiamo una voce al nostro dizionario “variabili” per rappresentare l’aliquota fiscale.

L’abbiamo implementata volutamente per riflettere un’imposta applicata al reddito da lavoro dipendente. Quello che abbiamo chiamato active_annual_income nel dizionario inflows. Questo è in contrasto con le tasse che potremmo dover sostenere a causa di altre fonti di reddito, come i redditi da investimenti (che introduciamo più avanti).

				
					
inflows = {'active_annual_income': 50_000}
variables = {'start_date': "01/01/2020",
             'years': 10,
             'tax_on_active_income_gains': 0.25}  # Aggiunge la % di tasse sui redditi attivi
income_gains_storage = []
months = variables['years'] * 12

for month in range(months):
    # Aggiunge l'effetto delle tasse applicate ai redditi
    income = (inflows['active_annual_income'] * (1 - variables['tax_on_active_income_gains'])) / 12
    income_gains_storage.append(income)

plt.plot(pd.Series(income_gains_storage).cumsum())
plt.xlabel('Month')
plt.ylabel('Cumulative Income')
plt.show()
				
			
Simulare un portafoglio di finanza personale in Python

In questo caso dopo 10 anni otteniamo 375.000, che è solo il 75% del reddito dopo che il fisco ha preso il 25%. Questa logica è, ovviamente, molto semplicistica in quanto non solo non teniamo conto di alcun tipo di scaglione fiscale a scala mobile, dove sono tassati diversi livelli di reddito. Inoltre non abbiamo nemmeno il concetto del valore temporale del reddito. Un dollaro di reddito preso oggi dal fisco oggi è peggio di un dollaro preso, diciamo, tra 5 anni. Se potessimo trattenerlo, non solo saremmo in grado di guadagnare interessi sul dollaro, ma potremmo anche investirlo e metterlo al lavoro alla ricerca di rendimenti più elevati.

Vediamo come modellare questi rendimenti degli investimenti. Nel mondo reale sono di natura stocastica e mostrano un certo elemento di variazione casuale da un periodo a quello successivo. Non possiamo semplicemente presumere che, se i nostri rendimenti annuali attesi sugli investimenti calcolati siano del 10% all’anno, realizzeremo quegli esatti rendimenti ogni anno. Ne li otteniamo in modo lineare con 12 rate mensili di importo uniforme. 

Non è solo l’entità dei nostri rendimenti a determinare il valore finale della ricchezza accumulata. L’ordine dei rendimenti è importante, insieme alla loro volatilità. Non spenderò troppo tempo analizzando le medie geometriche rispetto alle medie aritmetiche e simili. E’ sufficiente sottolineare che maggiore è la volatilità di un insieme di rendimenti, maggiore è il rischio per il nostro capitale finale (in media). 

Ad esempio, se vedessimo rendimenti del -20% nel periodo 1 e del +20% nel periodo 2, ci ritroveremmo con 0,8 x 1,2 = 0,96, ovvero saremmo in calo del 4% rispetto a un capitale iniziale di 1, rispetto a se abbiamo visto rendimenti più volatili del -50% e +50 dove ci saremmo ritrovati con 0,5 x 1,5 = 0,75 – cioè saremmo in  calo del 25%. Questo anche se entrambi gli esempi ci danno un rendimento aritmetico dello 0% (-0,2 + 0,2 = 0) e (-0,5 + 0,5 = 0). Se interessati ad approfondire la lettura, una spiegazione più dettagliata della relazione tra medie aritmetiche e geometriche può essere trovata qui: https://brilliant.org/wiki/arithmetic-mean-geometric-mean/

Simulare l’aumento del reddito mensile

Prima di passare alla logica dell’investimento, aggiungiamo rapidamente una logica per  implementare un aumento  annuale del salario, fissato come valore percentuale dell’attuale stipendio annuale attivo. In particolare supponiamo l’aumento si verifichi una volta l’anno ed ha effetto dal giorno successivo.

Ottimizzazione-Portfolio-inflows-tax-salary
				
					
inflows = {'active_annual_income': 50_000}
variables = {'start_date': "01/01/2020",
             'years': 10,
             'tax_on_active_income_gains': 0.25,
             'avg_ann_income_raise': 0.05} # Aggiunge la % di tasse sui redditi attivi
income_gains_storage = []
months = variables['years'] * 12

for month in range(months):
    income = (inflows['active_annual_income'] * (1 - variables['tax_on_active_income_gains'])) / 12
    income_gains_storage.append(income)
    # ogni 12 mesi aumenta il salario base di una percentuale media annuale
    if (month % 12 == 0) and (month > 0):  # non applichiamo l'aumento al primo mese
        inflows['active_annual_income'] *= (1 + (variables['avg_ann_income_raise']))

plt.plot(pd.Series(income_gains_storage).cumsum())
plt.xlabel('Month')
plt.ylabel('Cumulative Income')
plt.show()
				
			

Simulare i rendimenti degli investimenti

Passiamo a modellare i rendimenti stocastici degli investimenti menzionati in precedenza. Esistono numerosi modi per effettuare questo compito. L’approccio ideale potrebbe differire in base a circostanze o convinzioni individuali, ecc. Per mantenerlo relativamente semplice a scopi illustrativi, usiamo l’indice S&P 500 Total Return come proxy per “il mercato” e usiamo i dati storici per calcolare i valori relativi dei “rendimenti medi annuali” e  dei “livelli di volatilità”. Calcoliamo questi due valori (rendimento medio e deviazione standard) e li usiamo come input per creare una distribuzione normale standard e usare i valori della distribuzione come i nostri presunti “rendimenti di mercato” nel periodo considerato.

Quindi dobbiamo prevedere di:

  1. Scaricare i prezzi storici dell’indice S&P 500.
  2. Calcolare il rendimento medio mensile e la deviazione standard di uno specifico periodo storico.
  3. Memorizzare i valori da usare in seguito come input per la nostra distribuzione normale standard

I valori indicano un rendimento mensile dello 0,6% e una volatilità mensile (deviazione standard) del 4,15%.

Prima di implementare questa logica, dobbiamo creare un nuovo input nel dizionario “inflows” per rappresentare il nostro capitale iniziale, o asset iniziali. Inoltre aggiungiamo i valori calcolati del rendimento medio mensile e della volatilità al nostro dizionario “variabili”.

				
					

# Scaricare i dati storici dei prezzi dell'S&P500
start, end = "2000-12-31", "2020-01-01"
tickers = ["^SP500TR"]
sp = pd.DataFrame([yf.download(ticker, start, end).loc[:, 'Adj Close'] for ticker in tickers],
                  index=tickers).T.fillna(method='ffill')
# Calcolare i rendimenti e volatità medie mensili
sp_monthly_pct_return = sp.resample('M').last().pct_change().mean().values[0]
sp_monthly_std_dev = sp.resample('M').last().pct_change().std().values[0]

inflows = {'active_annual_income': 50_000,
           'starting_assets': 250_000}  # aggiungere il valore iniziale degli asset
variables = {'start_date': "01/01/2020",
             'years': 10,
             'tax_on_active_income_gains': 0.25,
             'avg_ann_income_raise': 0.05,
             'avg_monthly_market_returns': sp_monthly_pct_return,  # aggiunge i dati dei rendimento del mercato
             'avg_monthly_market_volatility': sp_monthly_std_dev}  # aggiunge i dati della volatilità del mercato
income_gains_storage = []
investment_gains_storage = []  # crea la lista per memorizzare i rendimenti degli investimenti
# crea la lista per memorizzare il valore degli asset all'inizio del periodo
assets_starting_list = [inflows['starting_assets']]  # imposta il primo valore della lista come asset del giorno
assets_ending_list = []  # crea la lista per memorizzare il valore degli asset alla fine del periodo
months = variables['years'] * 12

for month in range(months):

    # Verifica se è la prima volta che eseguiamo il ciclo mensile e, in caso contrario,
    # usiamo gli asset finali del periodo precedente come asset iniziali di questo periodo.
    if assets_ending_list:
        assets_starting_list.append(assets_ending_list[-1])

    income = (inflows['active_annual_income'] * (1 - variables['tax_on_active_income_gains'])) / 12
    income_gains_storage.append(income)

    if (month % 12 == 0) and (month > 0):
        inflows['active_annual_income'] *= (1 + (variables['avg_ann_income_raise']))

    # genera random un rendimento mensile del mercato da una distribuzione normale
    market_return = np.random.normal(variables['avg_monthly_market_returns'],
                                     variables['avg_monthly_market_volatility'],
                                     1)[0]

    # calcola il rendimento dell'investimento
    investment_return = assets_starting_list[-1] * market_return
    # memorizza in una lista il valore del rendimento dell'investimento
    investment_gains_storage.append(investment_return)

    # calcola il valore degli asset alla fine del periodo
    assets_ending = assets_starting_list[-1] + investment_return + income
    # memorizza il valore finale degli asset
    assets_ending_list.append(assets_ending)

plt.plot(pd.Series(investment_gains_storage).cumsum())
plt.xlabel('Month')
plt.ylabel('Cumulative Investment Returns')
plt.show()

				
			
Ottimizzazione-Portfolio-rendimenti-investimenti

Dal grafico della serie dei rendimenti degli investimenti possiamo vedere che i valori sono effettivamente di natura stocastica, con la casualità intrinseca dei rendimenti che significa che in alcuni mesi siamo in rialzo, in altri in ribasso, anche se il nostro rendimento medio mensile usato come input per la funzione Normale Standard era positivo.

Sottolineiamo che alcuni dei grafici seguenti mostrano la serie di rendimenti mensili cumulativi degli investimenti, mentre alcuni di essi mostrano la serie del valore patrimoniale finale del periodo: sono cose diverse! Forse è una cosa ovvia, ma spesso a prima vista questi grafici possono sembrare molto simili. E’ sufficiente controllare l’etichetta dell’asse y su ciascun grafico.

Se eseguiamo il codice precedente per un certo numero di volte, ogni risultato sarà diverso. Questo ci  introduce al mondo dei metodi Monte Carlo e alla creazione di distribuzioni di valori finali. Approfondiamo questi dettagli in un paragrafo specifico.

Abbiamo quindi modellato il reddito attivo mensile (con un aumento percentuale annuo) e i rendimenti mensili sugli investimenti. Quest’ultimi sono stati calcolati con un elemento stocastico in modo da imitare il mondo reale.

Simulare i prelievi di capitale

Se visualizziamo la serie di valori finali degli asset e verifichiamo cosa abbiamo ottenuto, potremmo supporre che siamo eccessivamente ottimisti. Naturalmente avremmo ragione; in primo luogo non abbiamo applicato alcuna tassazione ai nostri guadagni sugli investimenti, e inoltre non abbiamo ancora incluso alcun tipo di “deflusso”. Ad esempio possiamo includere le rate del mutuo, le bollette da pagare e il costo della vita che dobbiamo prevedere per mangiare cibo e avere un posto dove vivere. Dopo aver iniziato ad applicare il lato “debito” dell’equazione, vediamo la situazione equilibrarsi in qualche modo.

				
					plt.plot(pd.Series(assets_ending_list))
plt.xlabel('Month')
plt.ylabel('Ending Asset Value')
plt.show()
				
			
Ottimizzazione-Portfolio-patrimonio-finale

Applichiamo innanzitutto un’aliquota fiscale ai nostri rendimenti sugli investimenti: il processo è simile a quello di applicare le tasse al reddito attivo. Aggiungiamo un’aliquota fiscale sugli investimenti al dizionario delle variabili.

				
					
start, end = "2000-12-31", "2020-01-01"
tickers = ["^SP500TR"]
sp = pd.DataFrame([yf.download(ticker, start, end).loc[:, 'Adj Close'] for ticker in tickers],
                  index=tickers).T.fillna(method='ffill')

sp_monthly_pct_return = sp.resample('M').last().pct_change().mean().values[0]
sp_monthly_std_dev = sp.resample('M').last().pct_change().std().values[0]

inflows = {'active_annual_income': 50_000,
           'starting_assets': 250_000}
variables = {'start_date': "01/01/2020",
             'years': 10,
             'tax_on_active_income_gains': 0.25,
             'avg_ann_income_raise': 0.05,
             'tax_on_investment_gains': 0.35,  # aggiugere la % di tasse seui rendimenti degli investimenti
             'avg_monthly_market_returns': sp_monthly_pct_return,
             'avg_monthly_market_volatility': sp_monthly_std_dev}
income_gains_storage = []
investment_gains_storage = []

assets_starting_list = [inflows['starting_assets']]
assets_ending_list = []
months = variables['years'] * 12

for month in range(months):

    if assets_ending_list:
        assets_starting_list.append(assets_ending_list[-1])

    income = (inflows['active_annual_income'] * (1 - variables['tax_on_active_income_gains'])) / 12
    income_gains_storage.append(income)

    if (month % 12 == 0) and (month > 0):
        inflows['active_annual_income'] *= (1 + (variables['avg_ann_income_raise']))

    market_return = np.random.normal(variables['avg_monthly_market_returns'],
                                     variables['avg_monthly_market_volatility'],
                                     1)[0]

    # applica la % di tasse ai guadagni degli investimenti
    investment_return = (assets_starting_list[-1] * market_return) * (1 - variables['tax_on_investment_gains'])
    # memorizza in una lista il valore dei rendimenti dell'investimento
    investment_gains_storage.append(investment_return)

    # calcola il valore degli asset alla fine del periodo
    assets_ending = assets_starting_list[-1] + investment_return + income
    # memorizza il valore finale degli asset
    assets_ending_list.append(assets_ending)

plt.plot(pd.Series(investment_gains_storage).cumsum())
plt.xlabel('Month')
plt.ylabel('Cumulative Investment Returns')
plt.show()
				
			
Ottimizzazione-Portfolio-patrimonio-finale-tasse

Possiamo ora aggiungere alcuni deflussi mensili regolari e il costo della vita per pareggiare il saldo. Abbiamo creato un nuovo dizionario outflows come mostrato di seguito. Abbiamo anche introdotto una variabile per riflettere il livello generale di inflazione su base annuale che applichiamo ai costi (proprio come se aumentiamo il nostro stipendio di una certa percentuale una volta all’anno). Naturalmente potremmo gestire il livello di inflazione annuale in modo stocastico, così come abbiamo fatto con i rendimenti degli investimenti, ma per semplicità la applichiamo in modo deterministico.

				
					
start, end = "2000-12-31", "2020-01-01"
tickers = ["^SP500TR"]
sp = pd.DataFrame([yf.download(ticker, start, end).loc[:, 'Adj Close'] for ticker in tickers],
                  index=tickers).T.fillna(method='ffill')

sp_monthly_pct_return = sp.resample('M').last().pct_change().mean().values[0]
sp_monthly_std_dev = sp.resample('M').last().pct_change().std().values[0]

inflows = {'active_annual_income': 50_000,
           'starting_assets': 250_000}
# aggiungere il dizionario outflows
outflows = {'rent': 1500,
            'credit_card_payment': 750,
            'medical_insurance': 250,
            'pension_contribution': 500,
            'misc': 1500}

variables = {'start_date': "01/01/2020",
             'years': 10,
             'tax_on_active_income_gains': 0.25,
             'avg_ann_income_raise': 0.05,
             'avg_ann_inflation': 0.02,  # add annual inflation rate
             'tax_on_investment_gains': 0.35,
             'avg_monthly_market_returns': sp_monthly_pct_return,
             'avg_monthly_market_volatility': sp_monthly_std_dev}
income_gains_storage = []
investment_gains_storage = []

assets_starting_list = [inflows['starting_assets']]
assets_ending_list = []
months = variables['years'] * 12

for month in range(months):

    if assets_ending_list:
        assets_starting_list.append(assets_ending_list[-1])

    # crea una varibiale per memorizzare il valore degli asset
    assets = assets_starting_list[-1]
    # sottrae il costo mensile dal capitale degli asset
    assets -= (outflows['rent'] + outflows['credit_card_payment'] + \
               outflows['medical_insurance'] + outflows['pension_contribution'] + \
               outflows['misc'])

    # sposta il calcolo dei rendimenti degli investimenti al di sopra di quello 
    # del reddito e usa la nuova variabile "assets" come base di investimento
    market_return = np.random.normal(variables['avg_monthly_market_returns'],
                                     variables['avg_monthly_market_volatility'],
                                     1)[0]

    investment_return = (assets * market_return) * (1 - variables['tax_on_investment_gains'])

    investment_gains_storage.append(investment_return)

    # aggiunge i rendimenti degli investimenti alla variabile "assets"
    assets += investment_return

    income = (inflows['active_annual_income'] * (1 - variables['tax_on_active_income_gains'])) / 12
    income_gains_storage.append(income)

    if (month % 12 == 0):
        inflows['active_annual_income'] *= (1 + (variables['avg_ann_income_raise']))

        # incrementa i flussi di uscita dell'inflazione annuale
        outflows['rent'] *= (1 + (variables['avg_ann_inflation']))
        outflows['credit_card_payment'] *= (1 + (variables['avg_ann_inflation']))
        outflows['medical_insurance'] *= (1 + (variables['avg_ann_inflation']))
        outflows['pension_contribution'] *= (1 + (variables['avg_ann_inflation']))
        outflows['misc'] *= (1 + (variables['avg_ann_inflation']))

    # aggiunge il guadagno del reddito alla variabile "assets"
    assets += income

    # calcolare il valore degli asset alla fine del periodo
    assets_ending = assets
    # memorizza il valore finale degli asset
    assets_ending_list.append(assets_ending)

plt.plot(pd.Series(assets_ending_list))
plt.xlabel('Month')
plt.ylabel('Ending Asset Value')
plt.show()
				
			
Ottimizzazione-Portfolio-valore-finale-asset

Nel codice precedente abbiamo implementato l’applicazione dei  flussi in uscita del capitale prima dell’applicazione del reddito o il calcolo dei rendimenti degli investimenti. Questo approccio  consiste nel assicurarsi di pagare  le bollette il prima possibile, o almeno tenere da parte i soldi per il mese in modo da essere certo di avere liquidità quando necessario. Non vogliamo investire e rischiare di non avere abbastanza liquidità quando arriva il momento di pagare. Prevediamo inoltre che gli stipendi sono pagati alla fine del mese, o comunque non abbastanza presto da essere depositati sul tuo conto bancario, in attesa di essere investiti o di poter essere utilizzati per pagare le bollette per quel mese (meglio prevenire che curare).

Simulare la perdita dell’investimento

C’è un’altra logica che vogliamo applicare prima andare avanti. Attualmente il codice consente di simulare uno scenario di fallimento, perdendo tutto ciò che abbiamo in termini di asset investibili e continuando a “investire” un importo negativo.  Questo è ovviamente privo di senso dato che non è possibile ottenere rendimenti positivi da una base patrimoniale negativa perché i rendimenti di mercato sono negativi. Aggiungiamo un flag di controllo per assicurarci che la base patrimoniale sia in territorio positivo prima di iniziare a calcolare e applicare i rendimenti degli investimenti. Se la base patrimoniale è negativa, possiamo adottare i seguenti approcci:

  1. Consideriamo la situazione “inaccettabile”, ci classifichiamo come “rovinati/falliti” e terminiamo la simulazione con un’etichetta di “fallimento”.
  2. Consentire alla simulazione di continuare e raccogliere il reddito salariale ogni mese. Ogni mese in cui gli asset non sono positivi, impostiamo i guadagni degli investimenti a zero  di default.
  3. Implementare una logica non banale che applica interessi e penalità, consente di prendere prestiti e reinvestire, ecc.

A mio avviso, l’ultima opzione non è realistica e non è nemmeno lo scopo di questo articolo. Consideriamo le opzioni tra 1 e 2. Qualunque opzioni tu scelga, dipende da te: io tendo a optare per l’opzione 1, considerando una risorsa base zero come inaccettabile e un segno di fallimento per quanto riguarda la gestione del denaro e simili. Si potrebbe anche prevedere che sia inaccettabile anche solo avvicinarsi a una base patrimoniale di valore zero e quindi fissare una soglia di “fallimento” leggermente superiore allo zero.

Gestiamo una simulazione fallita registrando un “flag di fallimento”. In altre parole contrassegniamo l’esecuzione come fallita per una successiva analisi. Questo ragionamento diventerà più chiaro in seguito, quando iniziamo ad applicare i metodi Monte Carlo al nostro modello, eseguendo centinaia, migliaia o più simulazioni per ogni “esperimento”. Affronteremo  e spiegheremo l’algoritmo Monte Carlo a tempo debito.

Applichiamo la logica per fermare la simulazione se perdiamo l’intera base patrimoniale e diventiamo effettivamente “rovinati” dal punto di vista finanziario.

				
					
start, end = "2000-12-31", "2020-01-01"
tickers = ["^SP500TR"]
sp = pd.DataFrame([yf.download(ticker, start, end).loc[:, 'Adj Close'] for ticker in tickers],
                  index=tickers).T.fillna(method='ffill')

sp_monthly_pct_return = sp.resample('M').last().pct_change().mean().values[0]
sp_monthly_std_dev = sp.resample('M').last().pct_change().std().values[0]

inflows = {'active_annual_income': 50_000,
           'starting_assets': 75_000}
# aggiungere il dizionario outflows
outflows = {'rent': 1500,
            'credit_card_payment': 750,
            'medical_insurance': 1250,
            'pension_contribution': 500,
            'misc': 1500}

variables = {'start_date': "01/01/2020",
             'years': 10,
             'tax_on_active_income_gains': 0.25,
             'avg_ann_income_raise': 0.05,
             'avg_ann_inflation': 0.02,
             'tax_on_investment_gains': 0.35,
             'avg_monthly_market_returns': sp_monthly_pct_return,
             'avg_monthly_market_volatility': sp_monthly_std_dev}
income_gains_storage = []
investment_gains_storage = []

assets_starting_list = [inflows['starting_assets']]
assets_ending_list = []
months = variables['years'] * 12
# crea una variabile per segnalare se siamo diventati finanziariamente "rovinati"
ruined = False

for month in range(months):

    if assets_ending_list:
        assets_starting_list.append(assets_ending_list[-1])

    assets = assets_starting_list[-1]
    assets -= (outflows['rent'] + outflows['credit_card_payment'] + \
               outflows['medical_insurance'] + outflows['pension_contribution'] + \
               outflows['misc'])

    # controlla se la base patrimoniale ha valore positivo. Se negativo 
    # si imposta il flag "ruined" a 1 e si termina la simulazione
    if assets <= 0:
        inv_gain = 0
        ruined = True
        break
    market_return = np.random.normal(variables['avg_monthly_market_returns'],
                                     variables['avg_monthly_market_volatility'],
                                     1)[0]

    investment_return = (assets * market_return) * (1 - variables['tax_on_investment_gains'])

    investment_gains_storage.append(investment_return)

    assets += investment_return

    income = (inflows['active_annual_income'] * (1 - variables['tax_on_active_income_gains'])) / 12
    income_gains_storage.append(income)

    if (month % 12 == 0):
        inflows['active_annual_income'] *= (1 + (variables['avg_ann_income_raise']))
        outflows['rent'] *= (1 + (variables['avg_ann_inflation']))
        outflows['credit_card_payment'] *= (1 + (variables['avg_ann_inflation']))
        outflows['medical_insurance'] *= (1 + (variables['avg_ann_inflation']))
        outflows['pension_contribution'] *= (1 + (variables['avg_ann_inflation']))
        outflows['misc'] *= (1 + (variables['avg_ann_inflation']))

    assets += income
    assets_ending = assets
    assets_ending_list.append(assets_ending)

plt.plot(pd.Series(assets_ending_list))
plt.xlabel('Month')
plt.ylabel('Ending Asset Value')
plt.show()
				
			
Ottimizzazione-Portfolio-valore-finale-asset-fallimento
Abbiamo modificato i valori nei dizionari di inflow e outflow per ottenere una simulazione che termina con la “rovina” finanziaria prima del termine del periodo di simulazione (10 anni). A tale scopo abbiamo ridotto starting_assets nel dizionario inflow e aumentato il pagamento dell’assicurazione medica nel dizionario outflow. Possiamo vedere che l’asse x arriva solo a circa 36 mesi invece che l’intero periodo di simulazione di 120 mesi (10 anni) indicato nel dizionario delle variabili. Nella seconda parte di questo articolo vediamo come applicare i metodi Monte Carlo e le successive stime di probabilità, introducendo “scenari” con vari “fattori di shock”, come ad esempio una riduzione/perdita una tantum della base patrimoniale, perdita inaspettata del posto di lavoro e di reddito, aumento delle previsioni dei costi dell’inflazione.

Codice completo

In questo articolo abbiamo descritto come implementare un portafoglio o modello di finanza personale in Python. Per il codice completo riportato in questo articolo, si può consultare il seguente repository di github:
https://github.com/datatrading-info/Asset_Management

Benvenuto su DataTrading!

Sono Gianluca, ingegnere software e data scientist. Sono appassionato di coding, finanza e trading. Leggi la mia storia.

Ho creato DataTrading per aiutare le altre persone ad utilizzare nuovi approcci e nuovi strumenti, ed applicarli correttamente al mondo del trading.

DataTrading vuole essere un punto di ritrovo per scambiare esperienze, opinioni ed idee.

SCRIVIMI SU TELEGRAM

Per informazioni, suggerimenti, collaborazioni...

Torna in alto
Scroll to Top