L'ipotesi è che per più è lungo il periodo di riferimento, più i rendimenti si avvicineranno alla media.
I dati sono stati prelevati a questo indirizzo:https://it.finance.yahoo.com/quote/%5EGSPC/history?period1=-1325548800&period2=1640908800&interval=1wk&filter=history&frequency=1wk&includeAdjustedClose=true
Importo le librerie e dei dati necessarie all'analisi. Il dati sono contenuti in un file .csv che è stato precedentemente ripulito.
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import datetime
data = pd.read_csv('s_p1969_2021.CSV', sep=';')
data.convert_dtypes()
data['Data'] = pd.to_datetime(data['Data'])
data.head() #visualizzazione dei dati
| Data | Apertura | Max | Min | Chiusura | Chiusura_adj | |
|---|---|---|---|---|---|---|
| 0 | 2021-12-27 | 4733.99 | 4808.93 | 4733.99 | 4778.73 | 4778.73 |
| 1 | 2021-12-20 | 4587.90 | 4740.74 | 4531.10 | 4725.79 | 4725.79 |
| 2 | 2021-12-13 | 4710.30 | 4731.99 | 4600.22 | 4620.64 | 4620.64 |
| 3 | 2021-12-06 | 4548.37 | 4713.57 | 4540.51 | 4712.02 | 4712.02 |
| 4 | 2021-11-29 | 4628.75 | 4672.95 | 4495.12 | 4538.43 | 4538.43 |
%matplotlib inline
data.plot(x='Data', y='Chiusura_adj', xlabel = 'Anno', ylabel = 'Valore', title='Indice S&P 500', label = 'Quotazione')
plt.show()
Ai fini dell'analisi non sono necessari tutti i dati settimanali, ma confronteremo i rendimenti per ogni anno solare. Si considerà come prezzo di carico dell'anno n il prezzo di chiusura dell'anno n-1.
Per ottenere un dataframe con le sole date ed i prezzi di chiusura dell'ultima settimana di ogni anno, applico al dataframe data un filtro per ottenere solo le chiusure annuali, ed elimino le colonne che non saranno utilizzate nell'analisi. Tali dati saranno copiati in un nuovo dataframe chiamato annual_close
#creazione di una maschera per filtrare i dati, in modo da includere solo l'ultimo dato di ogni anno.
mask = []
mask = data['Data'].map(lambda x: ((x.month == 12) and (24 < x.day <=31)))
#creazione di un nuovo dataframe contenente i soli dati necessari
annual_close = pd.DataFrame(data[mask]).drop(['Apertura','Max','Min','Chiusura'], axis = 1)
A questo punto verrà calcolato il rendimento annuo, secondo le regole precedentemente esposte e aggiunto al dataframe annual_close.
annual_close.insert(2, 'Rend_annuo', (round(annual_close.Chiusura_adj/ annual_close.Chiusura_adj.shift(periods = -1)-1,4)))
Iniziamo a vedere graficamente come si sono distribuiti i rendimenti a 1 anno e calcoliamo media e deviazione standard.
%matplotlib inline
annual_close.Rend_annuo.plot.hist(label = 'Frequenza') #distribuzione dei rendimenti annui
plt.axvline(annual_close.Rend_annuo.mean(), color='k', linestyle='dashed', linewidth=1, label = 'Media')
plt.legend()
plt.show()
Calcoleremo media e deviazione standard per il rendimento annuo e minimo e massimo osservato.
print('La media è di ' + str(round(np.mean(annual_close.Rend_annuo)*100, 2))\
+'%. \nLa deviazione standard campionaria è pari a ' + str(round(np.std(annual_close.Rend_annuo, ddof=1)*100,2))\
+'%.\nIl rendimento medio geometrico rispettivamente massimo e minimo rilevati per un qualsiasi quinquennio sono stati pari a: \n '\
+ str(round(max(annual_close.Rend_annuo),2)*100) + '% (rendimento massimo) \n'\
+ str(round(min(annual_close.Rend_annuo),2)*100) + '% (rendimetno minimo).')
La media è di 9.14%. La deviazione standard campionaria è pari a 16.04%. Il rendimento medio geometrico rispettivamente massimo e minimo rilevati per un qualsiasi quinquennio sono stati pari a: 34.0% (rendimento massimo) -34.0% (rendimetno minimo).
Per esaminare la distribuzione dei rendimenti medi occorre dapprima determinare il rendimento medio annuo per ogni periodo di detenzione e per farlo si utilizzerà il metodo del rendimento medio geometrico calcolato con la seguente formula:
$$r_g = \sqrt[n] {R_c+1}-1 $$dove:
Per calcolare il Rendimento cumulato $r_c$ si utilizzerà la seguente formula:
$$R_c = \frac{q_f}{q_i}-1 $$dove: $q_f$ è la quotazione alla fine del periodo di riferimento; $q_i$ è la quotazione all'inizio del periodo di riferimento
Combinando tra di loro le due precedenti formule, si otterrà:
$$ r_g = \sqrt[n]{\frac{q_f}{q_i}}-1 $$anni = 5
rend_medio_geom_5anni = ((annual_close.Chiusura_adj/annual_close.Chiusura_adj.shift(periods=-anni))**(1/anni)-1)
annual_close.insert(3,'Rend_Geom_Medio_5a', rend_medio_geom_5anni)
plt.hist(annual_close.Rend_Geom_Medio_5a , label = 'Frequenza')
plt.axvline(annual_close.Rend_Geom_Medio_5a.mean(), color='k', linestyle='dashed', linewidth=1, label = 'Media')
plt.legend()
plt.show()
Calcoleremo media e deviazione standard per il rendimento annuo e minimo e massimo osservato.
print('La media geometrica del rendimento è di ' + str(round(annual_close.Rend_Geom_Medio_5a.mean()*100, 2))\
+'%. \nLa deviazione standard campionaria è pari a ' + str(round(np.std(annual_close.Rend_Geom_Medio_5a, ddof=1)*100,2))\
+'%.\nIl rendimento medio geometrico rispettivamente massimo e minimo rilevati per un qualsiasi quinquennio sono stati pari a: \n '\
+ str(round(max(annual_close.Rend_Geom_Medio_5a),2)*100) + '% (rendimento massimo) \n'\
+ str(round(min(annual_close.Rend_Geom_Medio_5a),2)*100) + '% (rendimento minimo).')
La media geometrica del rendimento è di 7.8%. La deviazione standard campionaria è pari a 7.38%. Il rendimento medio geometrico rispettivamente massimo e minimo rilevati per un qualsiasi quinquennio sono stati pari a: 26.0% (rendimento massimo) -5.0% (rendimento minimo).
anni = 10
rend_medio_geom_10anni = ((annual_close.Chiusura_adj/annual_close.Chiusura_adj.shift(periods=-anni))**(1/anni)-1)
annual_close.insert(4,'Rend_Geom_Medio_10a', rend_medio_geom_10anni)
plt.hist(annual_close.Rend_Geom_Medio_10a, label = 'Frequenza')
plt.axvline(annual_close.Rend_Geom_Medio_10a.mean(), color='k', linestyle='dashed', linewidth=1, label = 'Media')
plt.legend()
plt.show()
Calcoleremo media e deviazione standard per il rendimento annuo e minimo e massimo osservato.
print('La media geometrica del rendimento è ' + str(round(annual_close.Rend_Geom_Medio_10a.mean()*100, 2))\
+'%. \nLa deviazione standard campionaria è pari a ' + str(round(np.std(annual_close.Rend_Geom_Medio_10a, ddof=1)*100,2))\
+'%.\nIl rendimento medio geometrico annuo rispettivamente massimo e minimo rilevati per un qualsiasi decennio sono stati pari a: \n '\
+ str(round(max(annual_close.Rend_Geom_Medio_10a),2)*100) + '% (rendimento massimo) \n'\
+ str(round(min(annual_close.Rend_Geom_Medio_10a),2)*100) + '% (rendimento minimo).')
La media geometrica del rendimento è 8.0%. La deviazione standard campionaria è pari a 4.85%. Il rendimento medio geometrico annuo rispettivamente massimo e minimo rilevati per un qualsiasi decennio sono stati pari a: 16.0% (rendimento massimo) -3.0% (rendimento minimo).
anni = 20
rend_medio_geom_20anni = ((annual_close.Chiusura_adj/annual_close.Chiusura_adj.shift(periods=-anni))**(1/anni)-1)
annual_close.insert(5,'Rend_Geom_Medio_20a', rend_medio_geom_20anni)
plt.hist(annual_close.Rend_Geom_Medio_20a, label = 'Frequenza')
plt.axvline(annual_close.Rend_Geom_Medio_20a.mean(), color='k', linestyle='dashed', linewidth=1, label = 'Media')
plt.legend()
plt.show()
Calcoleremo media e deviazione standard per il rendimento annuo e minimo e massimo osservato.
print('La media geometrica del rendimento è ' + str(round(annual_close.Rend_Geom_Medio_20a.mean()*100, 2))\
+'%. \nLa deviazione standard campionaria è pari a ' + str(round(np.std(annual_close.Rend_Geom_Medio_20a,ddof=1)*100,2))\
+'%.\nIl rendimento medio geometrico annuo rispettivamente massimo e minimo rilevati per un qualsiasi ventennio sono stati pari a: \n '\
+ str(round(max(annual_close.Rend_Geom_Medio_20a),2)*100) + '% (rendimento massimo) \n'\
+ str(round(min(annual_close.Rend_Geom_Medio_20a),2)*100) + '% (rendimento minimo).')
La media geometrica del rendimento è 8.2%. La deviazione standard campionaria è pari a 2.68%. Il rendimento medio geometrico annuo rispettivamente massimo e minimo rilevati per un qualsiasi ventennio sono stati pari a: 14.000000000000002% (rendimento massimo) 4.0% (rendimento minimo).
Esplorando il dataframe annual_close è possibile vedere per ogni data i rendimenti geometrici medi per i periodi di detenzione calcolati.
In particolare è possibile notare come per investendo in qualsiasi anno a partire dal 1970 e mantenendo l'investimento per 20 anni, in nessun caso si è avuto un rendimento negativo in termini nominali.
print(annual_close)
Data Chiusura_adj Rend_annuo Rend_Geom_Medio_5a \
0 2021-12-27 4778.73 0.2723 0.163746
52 2020-12-28 3756.07 0.1611 0.129414
104 2019-12-30 3234.85 0.2776 0.094645
156 2018-12-31 2531.94 -0.0530 0.066929
209 2017-12-25 2673.61 0.1942 0.127626
261 2016-12-26 2238.83 0.0954 0.122266
313 2015-12-28 2043.94 -0.0069 0.102002
365 2014-12-29 2058.20 0.1239 0.130407
417 2013-12-30 1831.37 0.2488 0.144697
469 2012-12-31 1466.47 0.1661 0.007652
522 2011-12-26 1257.60 -0.0000 -0.023764
574 2010-12-27 1257.64 0.1278 0.001494
626 2009-12-28 1115.10 0.1967 -0.016514
678 2008-12-29 931.80 -0.3399 -0.034129
730 2007-12-31 1411.63 -0.0047 0.092121
783 2006-12-25 1418.30 0.1362 0.038796
835 2005-12-26 1248.29 0.0300 -0.011151
887 2004-12-27 1211.92 0.0933 -0.037777
939 2003-12-29 1108.48 0.2200 -0.020467
991 2002-12-30 908.59 -0.2251 -0.014018
1043 2001-12-31 1172.51 -0.1119 0.094056
1096 2000-12-25 1320.28 -0.1014 0.164734
1148 1999-12-27 1469.25 0.1953 0.261844
1200 1998-12-28 1229.23 0.2607 0.213852
1252 1997-12-29 975.04 0.3035 0.174803
1304 1996-12-30 748.03 0.2145 0.122718
1357 1995-12-25 615.93 0.3411 0.139214
1409 1994-12-26 459.27 -0.0154 0.053805
1461 1993-12-27 466.45 0.0706 0.109276
1513 1992-12-28 435.71 0.0390 0.120139
1565 1991-12-30 419.34 0.3064 0.112161
1617 1990-12-31 321.00 -0.0917 0.087662
1670 1989-12-25 353.40 0.2725 0.166418
1722 1988-12-26 277.72 0.1240 0.109843
1774 1987-12-28 247.08 0.0026 0.119298
1826 1986-12-29 246.45 0.1687 0.149961
1878 1985-12-30 210.88 0.2884 0.091145
1930 1984-12-31 163.68 -0.0076 0.089715
1983 1983-12-26 164.93 0.1727 0.114054
2035 1982-12-27 140.64 0.1476 0.081398
2087 1981-12-28 122.55 -0.1011 0.026628
2139 1980-12-29 136.34 0.2799 0.084456
2191 1979-12-31 106.52 0.1083 0.085401
2244 1978-12-25 96.11 0.0106 -0.005707
2296 1977-12-26 95.10 -0.1150 -0.042315
2348 1976-12-27 107.46 0.1822 0.010306
2400 1975-12-29 90.90 0.2855 -0.002728
2452 1974-12-30 70.71 -0.2850 -0.053328
2504 1973-12-31 98.90 -0.1622 NaN
2557 1972-12-25 118.05 0.1563 NaN
2609 1971-12-27 102.09 0.1079 NaN
2661 1970-12-28 92.15 -0.0091 NaN
2713 1969-12-29 93.00 NaN NaN
Rend_Geom_Medio_10a Rend_Geom_Medio_20a
0 0.142818 0.072778
52 0.115624 0.053667
104 0.112382 0.040250
156 0.105129 0.036791
209 0.065952 0.051729
261 0.046707 0.056343
313 0.050546 0.061810
365 0.054390 0.077881
417 0.051489 0.070776
469 0.049036 0.062561
522 0.007030 0.056450
574 -0.004849 0.070662
626 -0.027204 0.059138
678 -0.027322 0.062394
730 0.037695 0.091049
783 0.066068 0.091445
835 0.073194 0.092985
887 0.101896 0.105284
939 0.090416 0.099946
991 0.076260 0.097774
1043 0.108294 0.119541
1096 0.151904 0.120217
1148 0.153142 0.140206
1200 0.160386 0.135908
1252 0.147145 0.123420
1304 0.117427 0.101878
1357 0.113140 0.100394
1409 0.108683 0.098068
1461 0.109559 0.080639
1513 0.119719 0.067472
1565 0.130903 0.073196
1617 0.089402 0.064389
1670 0.127414 0.069028
1722 0.111946 NaN
1774 0.100185 NaN
1826 0.086546 NaN
1878 0.087795 NaN
1930 0.087556 NaN
1983 0.052471 NaN
2035 0.017664 NaN
2087 0.018434 NaN
2139 0.039951 NaN
2191 0.013666 NaN
2244 NaN NaN
2296 NaN NaN
2348 NaN NaN
2400 NaN NaN
2452 NaN NaN
2504 NaN NaN
2557 NaN NaN
2609 NaN NaN
2661 NaN NaN
2713 NaN NaN