Portafoglio All-Weather di Ray Dalio con Quantconnect

Portafoglio All-Weather di Ray Dalio con QuantConnect

In questo articolo descriviamo come implementare una strategia per ricreare una versione del portafoglio All-Weather di Ray Dalio con Quantconnect per il trading algoritmico raccomandato nel libro di Tony Robbin, Money Master the Game. Fondamentalmente, è una semplice strategia di Buy & Hold con ribilanciamento su base regolare. La salsa magica è quindi fornita sotto forma di selezione degli asset e del relativo peso del portafoglio.

Obiettivi

Prima di approfondire la strategia, vale la pena sottolineare che questo articolo descrive solo alcuni concetti ed argomenti che  potrebbero essere utili per migliorare altri algoritmi. Pertanto, anche se non si è interessati al portafoglio All-Weather di Ray Dalio con Quantconnect, questo articolo può essere di aiuto per i seguenti temi:

  1. Pianificazione degli eventi: come  effettuare il ribilanciamento con Quantconnect.
  2. Reinvestimento dei dividendi: argomento descritto anche in un articolo precedente)
  3. Simulare il reinvestimeno: Verificare i rendimenti se si  reinvestono i guadagni ogni volta che si ribilicia.

Portafoglio All-Weather di Ray Dalio

Come accennato in precedenza, il portafoglio All-Weather è una strategia buy & hold che alloca gli asset con una percentuale tale da superare diversi regimi di mercato. La strategia è stata condivisa da Ray dopo che Tony ha posto questa domanda:

Se non potessi lasciare nulla della tua ricchezza finanziaria ai tuoi figli, ma solo un portafoglio, una specifica asset allocation con un elenco di principi per guidarla, quale sarebbe?

È un’ottima domanda in quanto ha prodotto non solo il portafoglio per tutte le stagioni, ma anche alcuni principi molto interessanti che fanno riflettere. Riportare la risposta completa non è lo scopo di questo articolo, quindi descriviamo solo il principio fondamentale e l’asset allocation alla base del portafoglio per tutte le stagioni. Tuttavia, il lbrio è interessate e vale la pena leggerlo se si ha la possibilità.

Ray Dalio dice che in realtà ci sono solo 4 scenari di mercato (che lui chiama stagioni) che possono influenzare il prezzo di un asset. Inoltre, ogni stagione è favorevole a specifici tipi di asset. L’idea è cercare di mantenere il 25% del rischio totale in ogni stagione in modo che il portafoglio possa essere veramente bilanciato.

Di seguito è riportata una semplice immagine che mostra le quattro stagioni e quale tipo di asset performa meglio in ciascuna di esse.

Portafoglio All-Weather di Ray Dalio con Quantconnect

Allocazione

Ora che sappiamo quali tipi di asset possiamo prendere in considerazione durante ogni stagione, la domanda successiva è: quanto acquistiamo di ciascun asset? Fortunatamente, Ray fornisce il seguente suggerimento per le percentuali da usare:

  • Azioni:
    • 30% in S&P500 o altri indici per la diversificazione
  • Obbligazioni:
    • 15% in Treasury a 7-10 anni
    • 40% in Treasury a 20-25 anni
  • Materie Prime
    • 7,5% in oro
    • 7,5% in Altre materie prime

Ribilanciamento:

Il portafoglio All-Weather di Ray Dalio con  Quantconnect prevede un ribilanciamento almeno una volta all’anno. Il ribilanciamento implica semplicemente l’acquisto di più asset e la vendita di altri fino a quando la quantità di ciascuna classe di asset in portafoglio non raggiunge la sua percentuale target. Quindi, ad esempio, se le azioni aumentano di valore e le obbligazioni diminuiscono, le azioni potrebbero ora costituire il 50% del valore totale del portafoglio. Dato che vogliamo solo il 30% di azionario in portafoglio dobbiamo vendere alcune azioni (prendendo profitto) e investire questo profitto per acquistare più obbligazioni.

Il nostro portafoglio

Iniziamo con un saldo iniziale di 10.000 USD. Inoltre, vogliamo simulare anche i risparmi di denaro  (cioè liquidità aggiuntiva) tra ogni ribilanciamento e l’investimento di quella somma (cioè un PAC) per vedere se ha un effetto sul risultato complessivo. Dopotutto, questo è lo scenario più probabile per un investitore retail. Costruire ricchezza nel tempo.

Relativamente la selezione degli asset, usiamo gli ETF per ciascuna classe di asset. In questo modo possiamo mantenere il portafoglio il più diversificato possibile. L’unico svantaggio è per il backtesting dato che alcuni ETF non esistono da molti anni. Pertanto, a seconda dell’ETF selezionato, può essere difficile eseguire il backtest per periodi di tempo che includo tutte e 4 le stagioni. Nel nostro esempio, utilizzeremo i seguenti ETF del mercato statunitense perchè hanno molto storico:

  1. Vanguard S&P 500 ETF (15%)
  2. ETF Vanguard FTSE Mercati Sviluppati (15%)
  3. iShares 7-10 anni Treasury Bond ETF (15%)
  4. iShares 20+ Year Treasury Bond ETF (40%)
  5. SPDR Gold Trust (7,5%)
  6. Fondo petrolifero degli Stati Uniti (7,5%)

Infine, prevediamo un ribilanciamento semestrale. Questo non è così frequente affinchè le commissioni possano incedere sulle prestazioni. Inoltre, vediamo come effettuare un ribilanciamento solo in mesi specifici con QuantConnect 

Il codice

				
					import numpy as np

###
# All-Weather Portfolio
# ---------------------------------------------
# Strategy Author: Ray Dalio 
# Source: Tony Robbins / Money, master the game
# ----------------------------------------------
###
class BasicTemplateAlgorithm(QCAlgorithm):
    '''Basic template algorithm simply initializes the date range and cash'''

    def Initialize(self):
        '''
        Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. 
        All algorithms must initialized.
        '''

        self.SetStartDate(2011, 1, 1)  # Imposto data inizio
        self.SetEndDate(2019, 1, 1)  # Imposto data fine
        self.SetCash(100000)  # Imposto capitale iniziale

        # Gestione dividendi
        self.raw_handling = True

        # Simulazione del PAC dei risparmi per ogni periodo 
        self.savings_on = False
        self.savings_amt = 1000

        # Non effettuare il pca al primo ribilanciamento dopo l'esecuzione dell'algoritmo
        self.first_rebalance = True

        # Dizionario degli asset e dei pesi 
        # può essere ampliato con altri ETF
        self.all_weather = {
            "Equity 1": {
                "Ticker": "VOO",  # Vanguard S&P 500 ETF
                "Weight": 0.15,
            },
            "Equity 2": {
                "Ticker": "VEA",  # Vanguard FTSE Developed Markets ETF
                "Weight": 0.15,
            },

            "Bonds Med-Term": {
                "Ticker": "IEF",  # iShares 7-10 Year Treasury Bond ETF
                "Weight": 0.15,
            },

            "Bonds Long-Term": {
                "Ticker": "TLT",  # iShares 20+ Year Treasury Bond ETF
                "Weight": 0.4,
            },
            "Commodity 1": {
                "Ticker": "GLD",  # SPDR Gold Trust
                "Weight": 0.075,
            },
            "Commodity 2": {
                "Ticker": "USO",  # United States Oil Fund
                "Weight": 0.075,
            },

        }

        # Imposta la simulazione del broker IB
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)

        # Aggiunge gli ETF
        # ---------------
        for key, asset in self.all_weather.items():
            self.AddEquity(asset["Ticker"], Resolution.Daily)

            # Imposta il metodo per gestire i dividenti
            # ----------------------------
            # https://www.quantconnect.com/forum/discussion/508/update-dividends-splits-and-custom-price-normalization/p1
            if self.raw_handling:
                self.Securities[asset["Ticker"]].SetDataNormalizationMode(DataNormalizationMode.Raw)
            else:
                self.Securities[asset["Ticker"]].SetDataNormalizationMode(DataNormalizationMode.TotalReturn)

        # Assumiamo che se possiamo effettuare un ordine per le azione, possiamo farlo anche per gli ETF. 
        self.Schedule.On(self.DateRules.MonthStart(self.all_weather["Equity 1"]["Ticker"]),
                         self.TimeRules.AfterMarketOpen(self.all_weather["Equity 1"]["Ticker"]),
                         self.Rebalance)

    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.

        Arguments:
            data: Slice object keyed by symbol containing the stock data
        '''
        # Log di ogni dividendo ricevuto.
        # ---------------------------
        for kvp in data.Dividends:  # aggiornamento del dizionario dei dividendi
            div_ticker = kvp.Key
            div_distribution = kvp.Value.Distribution
            div_total_value = div_distribution * self.Portfolio[div_ticker].Quantity
            self.Log("DIVIDEND >> {0} - ${1} - ${2}".format(div_ticker, div_distribution, div_total_value))

    def Rebalance(self):
        month = self.Time.month

        # Esce se non vogliamo fare il ribilanciamento questo mese
        # Aggiungere altri mesi se vogliamo ribilanciare più spesso
        # ad es. per Marzo inserire 3 nella lista 
        if month not in [1, 6]: return

        self.Log('-------------------->>')
        self.Log("{0} RE-BALANCE >> Total Value {1} | Cash {2}".format(
            self.Time.strftime('%B').upper(),
            self.Portfolio.TotalPortfolioValue,
            self.Portfolio.Cash))

        if self.savings_on and not self.first_rebalance:
            cash_after_savings = self.Portfolio.Cash + self.savings_amt
            self.Log("Top Up Savings >> New Cash Balance {0}".format(
                cash_after_savings))
            self.Portfolio.SetCash(cash_after_savings)

        # Ribilanciamento                                                                
        for key, asset in self.all_weather.items():
            holdings = self.Portfolio[asset["Ticker"]].Quantity
            price = self.Portfolio[asset["Ticker"]].Price

            self.Log("{0} >> Current Holdings {1} | Current Price {2}".format(
                self.Portfolio[asset["Ticker"]].Symbol,
                holdings,
                price))

            self.SetHoldings(asset["Ticker"], asset["Weight"])

        self.Log('-------------------->>')

        # Impostare il primo ribilanciamento a False così possiamo aggiungere il PAC dal prossimo
        self.first_rebalance = False
				
			

Non analizziamo il codice in dettaglio perchè in questo articolo ci focalizziamo sulla strategia. I neofiti che hanno difficoltà a capire il codice possono leggere gli atri articoli relativi a QuantConnect

Parametri

Oltre a impostare le date di inizio e di fine, la strategia prevedere i seguenti parametri:

  • raw_handling: se impostato a true, i dividendi ricevuti sono pagati in contanti sul conto. Se falso, i dividendi non  sono pagati e il prezzo è corretto per  includere il dividendo. (per maggiori informazioni si può leggere l’articolo sugli split e dividendi )
  • saving_on: se impostato su true, si investe x$ ogni volta che ribilanciamo il portafoglio.
  • saving_amt:  valore in dollari di quanto denaro extra (risparmi) aggiungiamo ad ogni ribilanciamento.

Oltre a questi parametri, abbiamo anche il dizionario self.all_weather dove possiamo aggiungere/rimuovere i simboli degli ETF e impostare il loro peso relativo. Il peso è una percentuale in cui 1 è 100% e 0 è 0%. Possiamo aggiungere più ETF o azioni al backtest semplicemente aggiungendo ulteriori elementi a questo dizionario. Il resto del codice non deve essere aggiornato fintanto che sarà ancora presente la voce “Equity 1”. Se lo rimuoviamo, dobbiamo modificare self.Schedule.On(). In caso contrario, si genera un errore. Usiamo la prima equity per assicurarci che i mercati siano aperti per il trading alla data di ribilanciamento ideale. Partiamo dal presupposto che se i mercati sono aperti per il primo ETF, gli altri dovrebbero essere buoni. Tieni presente che se i mercati non sono aperti, QuantConnect modificherà in modo intelligente la data per assicurarci di non perdere un ribilanciamento.

A proposito, gli eventi programmati sono una parte importante di questa strategia. In questa strategia, usiamo un evento programmato per richiamare il metodo  Rebalance() (funzione) il primo giorno di negoziazione di ogni mese. È quindi all’interno del  metodo Rebalance() che acquistiamo/vendiamo  gli ETF. Per ulteriori informazioni sulla programmazione, si può consultare i seguenti documenti ufficiali.

Documenti ufficiali:  https://www.quantconnect.com/docs/algorithm-reference/scheduled-events

OnData()

In questo medoto prevediamo solamente di registrare tutti i dividendi ricevuti per il log. Questa sezione di codice è un copia e incolla dell’articolo sulla gestione dei dividendi. Per informazioni più dettagliate si può far riferimento a quell’articolo

Rebalance()

La funzione Rebalance() è chiamata all’inizio di ogni mese. Si chiama mensilmente perché al momento non ci sono DateRules semestrali o trimestrali su Quantconnect. Per ribilanciare solo una volta ogni sei mesi, dobbiamo aggiungere un po’ di logica. Dobbiamo verificare il numero del mese corrente e se non è un mese in cui vogliamo ribilanciare, allora usciamo (return) senza fare nient’altro.

				
					
# Esce se non vogliamo fare il ribilanciamento questo mese
if month not in [1,6]: return
				
			

Dopo questo controllo, aggiorniamo facoltativamente la liquidità per aggiungere alcuni risparmi sul conto semplicemente aggiungendo il valore  self.savings_amt alla liquidità disponibile nel conto. Quindi impostiamo il nuovo saldo di cassa usando il metodo self.Portfolio.SetCash(). Questo metodo potrebbe non essere perfetto ma fa il suo lavoro.

Infine, analizziamo il  dizionario All-Weather impostando gli asset con il peso corretto. Questo si traduce in piccole transazioni che aggiungono o tolgono solo poche quote di ETF per bilanciare il  portafoglio. Fortunatamente, questo è un processo indolore. Possiamo usare la funzione SetHolding() di QuantConnect che rende l’allocazione un gioco da ragazzi perchè gestisce tutta la logica di elaborazione delle corrette quantità per ogni asset.

Risultati

Prima di tutto, diamo un’occhiata ai risultati senza aggiungere il PAC. Non male: l’equity finale arriva a un rispettabile 14.037,20$.

Con il PAC

Possiamo vedere che differenza attivare un PAC con il denaro risparmiato ogni mese! In questo caso l’equity finale è stata di 30.427,14$.

Da notare che durante il backtest sono stati aggiunti 15.000& del equity finale tramite il PAC. Quindi il risultato finale sembra molto più impressionante della realtà perchè ha comportato un guadagno di 5.427,14$ sulla somma investita (25.000$ distribuiti su 7 anni con 10.000$ in anticipo).  Confrontiamo questo risultato con i 4.037,20$ di profitti a partire dai 10.000 $ del primo test. In sintesi vediamo che 15.000$ in più hanno aumentato i guadagni solo del 34%. Potrebbe sembrare una piccola somma dato che abbiamo più che raddoppiato la liquidità durante il backtest, ma dobbiamo ricordare che ogni investimento di 1000$ è stato a mercato per un diverso periodo di tempo. Più tardi sono state aggiunti 1000$, meno tempo ha contribuito alle performance del portafoglio! Per aggiungere ulteriori dettagli, se avessimo investito all’inizio l’intero importo di $ 25.000, il risultato sarebbe stato di circa 35.000$.

Speriamo che questo articolo possa ispirare alcune persone a fare un passo indietro rispetto la  ricerca dell’indicatore magico e cercare modi alternativi per generare rendimenti. Questo non  significa che il portafoglio All-Weather è l’approccio migliore. Nessuno potrebbe fare una simile affermazione con sicurezza senza un’enorme quantità di ricerca a supporto. Tuttavia, l’arte della selezione e del ribilanciamento degli asset è spesso trascurata dai trader retail, soprattutto con tutto lo sfarzo e il fascino dell’ultimo indicatore scoperto o l’eccitazione del day trading per un singolo strumento.

Codice completo

In questo articolo abbiamo descritto come implementare il portafoglio All-Weather di Ray Dalio con Quantconnect per il trading algoritmico. Per il codice completo riportato in questo articolo, si può consultare il seguente repository di github:
https://github.com/datatrading-info/QuantConnect

Gli altri articoli di questa serie

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