performance storiche degli ETF

Analizzare le performance storiche degli ETF a leva in Python

Sommario

In questo articolo descriviamo come analizzare le performance storiche degli ETF a leva (o Leveraged ETF) in Python, oltre a simulare il loro rendimento in periodi di tempo precedenti al loro lancio.

In questo articolo introduciamo gli ETF a leva ed analizziamo le performance storiche tramite le librerie di Python. Nel successivo articolo  descriviamo il backtest di un portafoglio di ETF a leva con Backtrader.

I Leveraged ETF

Molte persone sconsigliano di mantenere aperta una posizione in un ETF con leva a causa del beta slippage. Diamo un’occhiata alla performance di SPY, un ETF S&P 500, rispetto a UPRO, un ETF S&P 500 con leva 3x.

Per prima cosa importiamo alcune librerie.

				
					import pandas as pd
import yfinance as yf
import datetime
				
			

Implementiamo alcune funzioni per evitare duplicazioni del codice.

				
					def returns(prices):
    """
    Calcola la crescita di 1 dollaro investito in un titolo con determinati prezzi
    """
    return (1 + prices.pct_change(1)).cumprod()

def drawdown(prices):
    """
    Calcola il drawdown di un titolo con determinati prezzi
    """
    rets = returns(prices)
    return (rets.div(rets.cummax()) - 1) * 100

def cagr(prices):
    """
    Calcola il Compound Annual Growth Rate (CAGR) di un titolo con determinati prezzi
    """
    delta = (prices.index[-1] - prices.index[0]).days / 365.25
    return ((prices[-1] / prices[0]) ** (1 / delta) - 1) * 100
				
			

Passiamo quindi a visualizzare il grafico dei prezzi di chiusura aggiustati di UPRO rispetto a SPY.

				
					start = "2009-01-01"
end = "2020-01-01"

spy = yf.download("SPY", start, end)["Adj Close"]
upro = yf.download("UPRO", start, end)["Adj Close"]

spy_returns = returns(spy).rename("SPY")
upro_returns = returns(upro).rename("UPRO")

spy_returns.plot(title="Growth of $1: SPY vs UPRO", legend=True, figsize=(10,6))
upro_returns.plot(legend=True)
plt.show()

print("CAGRs")
print(f"SPY: {cagr(spy):.2f}%")
print(f"UPRO: {cagr(upro):.2f}%")
				
			
				
					CAGRs
SPY: 14.25%
UPRO: 38.07%
				
			
performance storiche degli ETF

Come possiamo vedere, l’ETF con leva 3x offre prestazioni migliori della sua controparte senza leva, ma con un compromesso di rischio maggiore. Diamo un’occhiata ai drawdown.

				
					spy_drawdown = drawdown(spy)
upro_drawdown = drawdown(upro)
print("Max Drawdown")
print(f"SPY: {spy_drawdown.idxmin()} {spy_drawdown.min():.2f}%")
print(f"UPRO: {upro_drawdown.idxmin()} {upro_drawdown.min():.2f}%")
upro_drawdown.plot.area(color="red", title="UPRO drawdown", figsize=(10,6))
plt.show()
				
			
				
					Max Drawdown
SPY: 2009-03-09 00:00:00 -27.13%
UPRO: 2011-10-03 00:00:00 -51.73%
				
			
performance storiche degli ETF

Un investitore che deteneva SPY durante il periodo di tempo analizzato avrebbe subito un drawdown massimo di poco inferiore al 20%, mentre un investitore long su UPRO avrebbe dovuto sopportare di perdere più volte oltre la metà del proprio portafoglio!

Simulazione delle prestazioni storiche

Fino ad ora abbiamo visto che UPRO effettivamente supera SPY sin dal suo inizio. Tuttavia, UPRO ha visto solamente un mercato rialzista, quindi non sorprende che abbia avuto una buona crescita annuale. Per simulare come si sarebbe comportato UPRO in passato, inclusa la crisi finanziaria, possiamo applicare il rapporto di leva e spesa 3x di UPRO (0,92%) a VFINX, un ETF su S&P 500 che esiste dal 1976.

Scriviamo una funzione helper. La variazione percentuale giornaliera viene calcolata prendendo la variazione percentuale giornaliera del proxy, sottraendo il rapporto di spesa giornaliera, quindi moltiplicando per la leva finanziaria.

				
					
def sim_leverage(proxy, leverage=1, expense_ratio = 0.0, initial_value=1.0):
    pct_change = proxy.pct_change(1)
    pct_change = (pct_change - expense_ratio / 252) * leverage
    sim = (1 + pct_change).cumprod() * initial_value
    sim[0] = initial_value
    return sim
				
			

Per testare la nostra simulazione, confrontiamo un UPRO simulato con tutto lo storico disponibile per UPRO.

				
					
vfinx = yf.download("VFINX", start, end)["Adj Close"]
upro_sim = sim_leverage(vfinx, leverage=3).rename("UPRO Sim")
upro_sim.plot(title="Growth of $1: UPRO vs UPRO Sim", legend=True, figsize=(10,6))
upro_returns.plot(legend=True)
plt.show()
				
			
Leveraged-ETF-storico-UPRO-simulato

Le serie sono quasi identiche! Simuliamo ora le ipotetiche prestazioni di UPRO dall’inizio di VFINX.

				
					
start = '1976-08-31'
vfinx = yf.download("VFINX", start, end)["Adj Close"]
upro_sim = sim_leverage(vfinx, leverage=3, expense_ratio=0.00).rename("UPRO Sim")
upro_sim.plot(title="Growth of $1: VFINX vs UPRO Sim", legend=True, figsize=(10,6))

vfinx_returns = returns(vfinx).rename("VFINX")
vfinx_returns.plot(legend=True)
plt.show()

print("CAGRs")
print(f"VFINX: {cagr(vfinx):.2f}%")
print(f"UPRO Sim: {cagr(upro_sim):.2f}%")

				
			
				
					CAGRs
VFINX: 10.87%
UPRO Sim: 20.46%
				
			
Leveraged-ETF-VFINX-UPRO-simulato

La simulazione UPRO supera ancora la sua controparte senza leva, ma diamo un’occhiata ai drawdown.

				
					

upro_sim_drawdown = drawdown(upro_sim)
vfinx_drawdown = drawdown(vfinx)

print("Max Drawdown")
print(f"VFINX: {vfinx_drawdown.idxmin()} {vfinx_drawdown.min():.2f}%")
print(f"UPRO Sim: {upro_sim_drawdown.idxmin()} {upro_sim_drawdown.min():.2f}%")
upro_sim_drawdown.plot.area(color="red", title="UPRO Sim drawdown", figsize=(10,6))
plt.show()

				
			
				
					Max Drawdown
VFINX: 2009-03-09 00:00:00 -55.25%
UPRO Sim: 2009-03-09 00:00:00 -97.11%
				
			
Leveraged-ETF-UPRO-simulato-drawdown

VFINX ha un drawdown abbastanza consistente di oltre il 55%, ma un investitore che detiene l’UPRO simulato incontrerebbe molti grandi  drawdown tra cui uno superiore al 97% durante la crisi finanziaria del 2008!

Conclusione

L’UPRO simulato ha avuto un tasso di crescita annuo composto medio del 18,76% rispetto al 10,39% dell’S&P 500. Sebbene i rendimenti siano più elevati, i drawdown vicini al 100% lo rendono un investimento estremamente rischioso da avare da solo. Nel prossimo articolo vediamo la performance storica simulata di altri ETF a leva e esaminiamo alcune strategie di allocazione multi-asset.

Codice completo

In questo articolo abbiamo descritto come analizzare le performance storiche degli ETF a leva (o Leveraged ETF) in Python. Per il codice completo riportato in questo articolo, si può consultare il seguente repository di github:
https://github.com/datatrading-info/AnalisiDatiFinanziari

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...

Scroll to Top