Ho analizzato il comportamento di un paniere di titoli per vederne il comportamento complessivo nel tempo. In particolare già in passato avevo analizzato la strategia buy & hold verificando che è difficile trovare una strategia di trading migliore di quella B&H.
Con l’occasione ho voluto sperimentare backtesting alternativi rispetto a Backtrader. Credo che Backtrader sia una delle piattaforme migliori sul mercato, in grado di simulare in odo molto fedele il comportamento dei broker e anche di agganciarsi a broker reali per algotrading direttamente a mercato. Per fare però delle semplici simulazioni occorre qualcosa di più snello, una volta verificata la bontà di una strategia attraverso un sistema snello si può implementare su backtrader che aggiunge tutti gli orpelli onerosi quali slippage, tobin tax, commissioni e vincoli su ordini in base alla disponibilità economica.
Per implementare un metodo snello ci sono tre framework che ci aiutano:
- ta-lib: una collezione di funzione per l’analisi tecnica, comprende anche l’identificazione di candlestick e numerosi indicatori
- pandas-ta, estende in modo semplice le funzioni di pandas aggiungendo diverse funzioni per applciare sul set di dati gli indicatori ta-lib
- vector-bt: una libreria semplice di backtesting che consente di definire gli entry e exit point di una strategia. In base a questi elementi
Tornando alla strategia B&H, le prime prove fatte coinvolgono la librerie pandas-ta e, dato l’insieme dei titoli, calcolo in guadagno nel tempo per ciascun titolo. Il codice è molto semplice, per prima cosa carico i dati:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pandas_ta as ta
df = pd.DataFrame() # Empty DataFrame
assets =["A2A.MI", "AMP.MI", "ATL.MI", "AZM.MI", "BGN.MI", "BMED.MI", "BAMI.MI", "BPE.MI", "BZU.MI",
"CPR.MI", "CNHI.MI", "DIA.MI", "ENEL.MI", "ENI.MI", "EXO.MI", "RACE.MI", "FBK.MI", "G.MI",
"HER.MI", "IP.MI", "ISP.MI", "INW.MI", "IG.MI", "LDO.MI", "MB.MI", "MONC.MI", "NEXI.MI",
"PIRC.MI", "PST.MI", "PRY.MI", "REC.MI", "SPM.MI", "SRG.MI", "STLA.MI", "STM.MI", "TIT.MI",
"TEN.MI", "TRN.MI", "UCG.MI", "UNI.MI"]
dfs = {}
for name in assets:
dfs[name]=pd.read_json(f"{name}_reg_5-60")
dfs[name].set_index(pd.DatetimeIndex(dfs[name]["Date"]), inplace=True)
I dati lì ho in locale per comodità, ma volendoli caricare con pandas-ta è sufficiente sostituire con questo:
dfs[name]=df.ta.ticker(name)
A questo punto calcolo il guadagno nel tempo per ciascun asset e creo una tabella di sintesi:
assets =["A2A.MI", "AMP.MI", "ATL.MI", "AZM.MI", "BGN.MI", "BMED.MI", "BAMI.MI", "BPE.MI", "BZU.MI",
"CPR.MI", "CNHI.MI", "DIA.MI", "ENEL.MI", "ENI.MI", "EXO.MI", "RACE.MI", "FBK.MI", "G.MI",
"HER.MI", "IP.MI", "ISP.MI", "INW.MI", "IG.MI", "LDO.MI", "MB.MI", "MONC.MI", "NEXI.MI",
"PIRC.MI", "PST.MI", "PRY.MI", "REC.MI", "SPM.MI", "SRG.MI", "STLA.MI", "STM.MI", "TIT.MI",
"TEN.MI", "TRN.MI", "UCG.MI", "UNI.MI"]
gains = {}
res = pd.DataFrame(columns=["start","end","initial","final","percret","logret"])
total = 0
for name in assets:
df =dfs[name].copy()
df.ta.log_return(cumulative=True, append=True)
df.ta.percent_return(cumulative=True, append=True)
gains[name] = df["CUMPCTRET_1"][len(df)-1]
total +=gains[name]
print(f"Guadagno {name} dal {df.index[0]:%m/%d/%Y} al {df.index[-1]:%m/%d/%Y} di {gains[name]*100:.02f} %")
p = pd.DataFrame([[df.index[0],df.index[-1],df["Close"][0],df["Close"][len(df)-1],
df["CUMPCTRET_1"][len(df)-1],df["CUMLOGRET_1"][len(df)-1]]],
columns=["start","end","initial","final","percret","logret"],
index=[name])
res = pd.concat([res,p])
print(f"Guadagno medio {total*100/len(gains)} %")
Il risultato mostra come alcuni titoli hanno performato molto, altri molto male:
Guadagno A2A.MI dal 01/03/2000 al 05/05/2022 di -56.15 % Guadagno AMP.MI dal 10/01/2001 al 05/05/2022 di 2256.41 % Guadagno ATL.MI dal 09/22/2003 al 05/05/2022 di 88.79 % Guadagno AZM.MI dal 07/07/2004 al 10/27/2021 di 634.51 % Guadagno BGN.MI dal 11/15/2006 al 05/05/2022 di 244.51 % Guadagno BMED.MI dal 01/03/2000 al 05/05/2022 di -45.43 % Guadagno BAMI.MI dal 01/03/2000 al 05/05/2022 di -97.02 % Guadagno BPE.MI dal 01/03/2000 al 05/05/2022 di -88.98 % Guadagno BZU.MI dal 01/03/2000 al 05/05/2022 di 62.49 % Guadagno CPR.MI dal 07/06/2001 al 05/05/2022 di 6961.02 % Guadagno CNHI.MI dal 09/30/2013 al 05/05/2022 di 44.78 % Guadagno DIA.MI dal 07/19/2007 al 05/05/2022 di 868.90 % Guadagno ENEL.MI dal 01/03/2000 al 05/05/2022 di 1.35 % Guadagno ENI.MI dal 01/03/2000 al 05/05/2022 di 28.91 % Guadagno EXO.MI dal 01/03/2000 al 05/05/2022 di 81.08 % Guadagno RACE.MI dal 01/04/2016 al 05/05/2022 di 339.43 % Guadagno FBK.MI dal 07/02/2014 al 05/05/2022 di 223.87 % Guadagno G.MI dal 01/03/2000 al 05/05/2022 di -36.47 % Guadagno HER.MI dal 03/28/2003 al 05/05/2022 di 95.84 % Guadagno IP.MI dal 01/03/2000 al 05/05/2022 di 746.27 % Guadagno ISP.MI dal 01/03/2000 al 05/05/2022 di -44.43 % Guadagno INW.MI dal 06/22/2015 al 05/05/2022 di 151.35 % Guadagno IG.MI dal 11/07/2016 al 05/05/2022 di 54.03 % Guadagno LDO.MI dal 07/18/2005 al 05/05/2022 di -29.44 % Guadagno MB.MI dal 01/03/2000 al 05/05/2022 di 8.58 % Guadagno MONC.MI dal 12/16/2013 al 05/05/2022 di 197.93 % Guadagno NEXI.MI dal 04/18/2019 al 05/05/2022 di 12.75 % Guadagno PIRC.MI dal 10/04/2017 al 05/05/2022 di -31.25 % Guadagno PST.MI dal 10/27/2015 al 05/05/2022 di 36.39 % Guadagno PRY.MI dal 05/03/2007 al 05/05/2022 di 98.21 % Guadagno REC.MI dal 01/03/2000 al 05/05/2022 di 4034.14 % Guadagno SPM.MI dal 01/03/2000 al 05/05/2022 di -75.09 % Guadagno SRG.MI dal 12/06/2001 al 05/05/2022 di 119.76 % Guadagno STLA.MI dal 01/03/2000 al 05/05/2022 di 58.00 % Guadagno STM.MI dal 01/03/2000 al 05/05/2022 di -30.69 % Guadagno TIT.MI dal 01/03/2000 al 05/05/2022 di -93.51 % Guadagno TEN.MI dal 12/17/2002 al 05/05/2022 di 704.95 % Guadagno TRN.MI dal 06/23/2004 al 05/05/2022 di 337.61 % Guadagno UCG.MI dal 01/03/2000 al 05/05/2022 di -93.24 % Guadagno UNI.MI dal 01/03/2000 al 05/05/2022 di -90.98 % Guadagno medio 441.97885234421864 %
Il peggiore è stato BAMI con una perdita del 97.02% mentre il migliore è stato CPR con un guadagno del 6961.02%. Per capire l’entità dei due scostamenti, se avessi investito 10.000€ su BAMI oggi avrei 298€, mentre se avessi investito 10.000€ su CPR oggi avrei 706.102€. Sottolineo la precisazione, l’analisi è semplificata, non si considerano un insieme di fattori, oltre ai costi operativi evidenziati sopra (commissioni, ecc. ) non considero i dividendi distribuiti, gli split, gli aumenti di capitale e tutte quelle operazioni di capitale che portano guadagni o perdite all’azionista.
Il punto da capire è se il risultato di 6961.02% è da considerarsi un anomalia o meno. Vediamo altri outperformer come AMP e REC, anche questi sono un’eccezione. Il primo passo per affrontare quest’analisi è il passaggio alla scala logaritmica. Un titolo che perde ogni giorno l’ 1% perde in termini monetari assoluti sempre meno, un titolo che guadagna 1% ogni giorno guadagna in termini monetari assoluti sempre di più. Rispetto alla scala logaritmica i guadagni (e le perdite) seguono un andamento lineare. I risultati visti sopra, calcolati secondo una scala logaritmica diventano:
Guadagno A2A.MI dal 01/03/2000 al 05/05/2022 di -0.82 log Guadagno AMP.MI dal 10/01/2001 al 05/05/2022 di 3.16 log Guadagno ATL.MI dal 09/22/2003 al 05/05/2022 di 0.64 log Guadagno AZM.MI dal 07/07/2004 al 10/27/2021 di 1.99 log Guadagno BGN.MI dal 11/15/2006 al 05/05/2022 di 1.24 log Guadagno BMED.MI dal 01/03/2000 al 05/05/2022 di -0.61 log Guadagno BAMI.MI dal 01/03/2000 al 05/05/2022 di -3.51 log Guadagno BPE.MI dal 01/03/2000 al 05/05/2022 di -2.21 log Guadagno BZU.MI dal 01/03/2000 al 05/05/2022 di 0.49 log Guadagno CPR.MI dal 07/06/2001 al 05/05/2022 di 4.26 log Guadagno CNHI.MI dal 09/30/2013 al 05/05/2022 di 0.37 log Guadagno DIA.MI dal 07/19/2007 al 05/05/2022 di 2.27 log Guadagno ENEL.MI dal 01/03/2000 al 05/05/2022 di 0.01 log Guadagno ENI.MI dal 01/03/2000 al 05/05/2022 di 0.25 log Guadagno EXO.MI dal 01/03/2000 al 05/05/2022 di 0.59 log Guadagno RACE.MI dal 01/04/2016 al 05/05/2022 di 1.48 log Guadagno FBK.MI dal 07/02/2014 al 05/05/2022 di 1.18 log Guadagno G.MI dal 01/03/2000 al 05/05/2022 di -0.45 log Guadagno HER.MI dal 03/28/2003 al 05/05/2022 di 0.67 log Guadagno IP.MI dal 01/03/2000 al 05/05/2022 di 2.14 log Guadagno ISP.MI dal 01/03/2000 al 05/05/2022 di -0.59 log Guadagno INW.MI dal 06/22/2015 al 05/05/2022 di 0.92 log Guadagno IG.MI dal 11/07/2016 al 05/05/2022 di 0.43 log Guadagno LDO.MI dal 07/18/2005 al 05/05/2022 di -0.35 log Guadagno MB.MI dal 01/03/2000 al 05/05/2022 di 0.08 log Guadagno MONC.MI dal 12/16/2013 al 05/05/2022 di 1.09 log Guadagno NEXI.MI dal 04/18/2019 al 05/05/2022 di 0.12 log Guadagno PIRC.MI dal 10/04/2017 al 05/05/2022 di -0.37 log Guadagno PST.MI dal 10/27/2015 al 05/05/2022 di 0.31 log Guadagno PRY.MI dal 05/03/2007 al 05/05/2022 di 0.68 log Guadagno REC.MI dal 01/03/2000 al 05/05/2022 di 3.72 log Guadagno SPM.MI dal 01/03/2000 al 05/05/2022 di -1.39 log Guadagno SRG.MI dal 12/06/2001 al 05/05/2022 di 0.79 log Guadagno STLA.MI dal 01/03/2000 al 05/05/2022 di 0.46 log Guadagno STM.MI dal 01/03/2000 al 05/05/2022 di -0.37 log Guadagno TIT.MI dal 01/03/2000 al 05/05/2022 di -2.73 log Guadagno TEN.MI dal 12/17/2002 al 05/05/2022 di 2.09 log Guadagno TRN.MI dal 06/23/2004 al 05/05/2022 di 1.48 log Guadagno UCG.MI dal 01/03/2000 al 05/05/2022 di -2.69 log Guadagno UNI.MI dal 01/03/2000 al 05/05/2022 di -2.41 log
Il grafico dei guadagni percentuali e logaritmici sono i seguenti:
Osservando il grafico sulle % sembra che i picchi siano delle anomalie, mentre rappresentando i medesimi dati in scala logaritmica sembrano coerenti e seguire un moto Browniano. I dati sono troppo esigui per rappresentarli con un’istogramma sensato, ma facendolo lo stesso otteniamo i seguenti diagrammi:
A occhio, ma servirebbe un matematico, la curva dei guadagni sembra seguire una distribuzione di chi-quadro, mentre la distribuzione dei guadagni logaritmici sembra seguire una distribuzione normale. Ipotesi da approfondire con un set di dati più ampio.
Come ultima simulazione tolgo tutti i titoli che hanno un valore logaritmico elevato fino a ottenere una media di valore logaritmico inferiore a zero. In altre parole sommando i logaritmi di guadagni e perdite prevalgono le perdite. Calcolando il guadagno % otteniamo un guadagno (seppure piccolo) positivo e come si vede il grafico del guadagno logaritmico è stato privato della parte alta con un significativo sbilanciamento verso i numeri negativi.
Guadagno medio -0.0327 log Guadagno medio 80.35%
In conclusione:
- Se ci aspettiamo che i guadagni logaritmici seguano una distribuzione normale, il mercato premia sempre un investimento a lungo termine diversificato su un paniere ampio di azioni (B&H)
- L’andamento nel lungo periodo delle azioni è legato all’analisi fondamentale e alle scelte strategiche operate dalle aziende
Lascia un commento