Creazione di coppie di Ticker

Backtest ETF: Creazione di coppie di Ticker

Sommario

In questo articolo descriviamo come effettuare la creazione di coppie di Ticker degli ETF da usare per il backtest di una strategia mean-reverting di trading algoritmico. L’articolo fa parte della miniserie “Backtest di una strategia di mean reverting con gli ETF”.

Gli articoli che fanno parte di questa serie sono:

  1. Backtest ETF: Web scraping e Database Sqlite3
  2. Backtest ETF: Creazione di coppie di Ticker
  3. Backtest ETF: Mean-reverting con Python
  4. Backtest ETF: Strategia di Trading con lo Z-score
  5. Backtest ETF: Pair trading con Python 

Quindi articolo può essere considerato il primo vero articolo relativo allo script  per il backtest di una strategia mean-revering sugli ETF che stiamo cercando di elaborare. Nel precedente articolo abbiamo creato il nostro database SQLite e lo abbiamo popolato con i dati degli ETF raccolti da www.etf.com. Abbiamo quindi a disposizione oltre 1000 ticker ETF da estrarre e utilizzare insieme a YFinance per scaricare i dati storici dei prezzi giornalieri dal Web e usarli nel backtest.

Tale approccio permette di avere un database con una serie di informazioni di supporto da abbinare a ciascuno ETF (come la classe dell’asset sottostante,  la regione geografica e “focus”, solo per citarne alcuni) invece di avere solo un elenco di ticker ETF non identificabili. Queste informazioni consentonodi analizzare i ticker dell’ETF e creare coppie che hanno maggiori probabilità di co-integrarsi grazie a comuni fattori fondamentali sottostanti, invece che attraverso indicibili permutazioni di ticker casuali nella speranza di imbatterci in qualcosa di utile. Ad esempio, 2 ETF che tracciano l’argento come asset sottostante hanno maggiori probabilità di essere co-integrati rispetto a un ETF che traccia l’argento e un altro che traccia le società di servizi pubblici nella regione dell’Asia Pacifico, giusto? Sembra avere senso …

Iniziamo un po’ di codice!

Connessione al Database

				
					import sqlite3 as db
import pandas as pd

# imposta il percorso del file del database a cui desideriamo connetterci
# questo è univoco e dipende dove si trova il database SQLite nel sistema locale
database = 'C:\Users\Datatrading\sqlite_databases\etfs.db'

# questa è l'istruzione SQL contenente le informazioni riguardo 
# a quali ticker vogliamo estrarre dal database
# Ad esempio, ho scelto di estrarre tutti i ticker che hanno 
# il loro "Focus" corrispondente a "Silver"
sql = 'SELECT Ticker FROM etftable WHERE Focus = "Silver";'

# crea una connessione al database
cnx = db.connect(database)
cur = cnx.cursor()

# eseque l'istruzione SQL e salva i risultati in una variabile chiamata "tickers"
tickers = pd.read_sql(sql, con=cnx)
				
			

Se stampiamo la varibiale “tickers” otteniamo il seguente DataFrame:

				
					   Ticker
0     SLV
1    SIVR
2     AGQ
3    USLV
4     ZSL
5    SLVO
6    DSLV
7     DBS
8     USV
9     SLV
10   SIVR
11    AGQ
12   USLV
13    ZSL
14   SLVO
15   DSLV
16    DBS
17    USV
				
			

Iteriamo questo DataFrame e aggiungiamo ogni ticker in una lista in modo da poterli usare più facilmente in seguito.

				
					
# crea una lista vuota
symbList = []

# iterazione sul DataFrame e inserimento dei ticker nella lista
for i in range(len(tickers)):
    symbList.append(tickers.ix[i][0])
				
			

Creazione di Coppie di Ticker

Implementiamo quindi una funzione che prende la lista symbList come input e restituisce una lista di coppie univoche di ticker. Lavoriamo con coppie di ticker perchè è l’input previsto dalla funzione principale di backtest, che implementiamo in seguito.

L’approccio usato in questo esempio può non essere quello più accurato per farlo, ma per il momento è il più semplice e fa bene il suo lavoro. Se tuttavia, alcuni esperti di python si imbattono in questo articolo e hanno qualche critica costruttiva, sono sempre felice di imparare nuove soluzioni.

				
					

def get_symb_pairs(symbList):
    """
    symbList è una lista di simboli ETF
    Questa funzione ha una lista di simboli come paramentro
    e restituisce una lista di coppie univoche di simboli
    """

    symbPairs = []
    i = 0

    # scorre la lista e crea tutte le possibili combinazioni di coppie
    # di ticker e aggiunge le coppie alla lista "symbPairs"
    while i < len(symbList) - 1:
        j = i + 1
        while j < len(symbList):
            symbPairs.append([symbList[i], symbList[j]])
            j += 1
        i += 1

    # scorre la lista di coppie appena creato e rimuove
    # tutte le coppie composte da due ticker identici
    for i in symbPairs:
        if i[0] == i[1]:
            symbPairs.remove(i)

    # crea una nuova lista vuota per memorizzare solo coppie univoche
    symbPairs2 = []
    
    # scorre la lista originale e aggiunge alla nuova lista solo coppie univoche 
    for i in symbPairs:
        if i not in symbPairs2:
            symbPairs2.append(i)
    return symbPairs2
				
			

Richiamo la funzione nella seguente istruzione:

				
					
symbPairs = get_symb_pairs(symbList)
				
			

Otteniamo il seguente elenco:

				
					[[u'SLV', u'SIVR'],
 [u'SLV', u'AGQ'],
 [u'SLV', u'USLV'],
 [u'SLV', u'ZSL'],
 [u'SLV', u'SLVO'],
 [u'SLV', u'DSLV'],
 [u'SLV', u'DBS'],
 [u'SLV', u'USV'],
 [u'SIVR', u'AGQ'],
 [u'SIVR', u'USLV'],
 [u'SIVR', u'ZSL'],
 [u'SIVR', u'SLVO'],
 [u'SIVR', u'DSLV'],
 [u'SIVR', u'DBS'],
 [u'SIVR', u'USV'],
 [u'SIVR', u'SLV'],
 [u'AGQ', u'USLV'],
 [u'AGQ', u'ZSL'],
 [u'AGQ', u'SLVO'],
 [u'AGQ', u'DSLV'],
 [u'AGQ', u'DBS'],
 [u'AGQ', u'USV'],
 [u'AGQ', u'SLV'],
 [u'AGQ', u'SIVR'],
 [u'USLV', u'ZSL'],
 [u'USLV', u'SLVO'],
 [u'USLV', u'DSLV'],
 [u'USLV', u'DBS'],
 [u'USLV', u'USV'],
 [u'USLV', u'SLV'],
 [u'USLV', u'SIVR'],
 [u'USLV', u'AGQ'],
 [u'ZSL', u'SLVO'],
 [u'ZSL', u'DSLV'],
 [u'ZSL', u'DBS'],
 [u'ZSL', u'USV'],
 [u'ZSL', u'SLV'],
 [u'ZSL', u'SIVR'],
 [u'ZSL', u'AGQ'],
 [u'ZSL', u'USLV'],
 [u'SLVO', u'DSLV'],
 [u'SLVO', u'DBS'],
 [u'SLVO', u'USV'],
 [u'SLVO', u'SLV'],
 [u'SLVO', u'SIVR'],
 [u'SLVO', u'AGQ'],
 [u'SLVO', u'USLV'],
 [u'SLVO', u'ZSL'],
 [u'DSLV', u'DBS'],
 [u'DSLV', u'USV'],
 [u'DSLV', u'SLV'],
 [u'DSLV', u'SIVR'],
 [u'DSLV', u'AGQ'],
 [u'DSLV', u'USLV'],
 [u'DSLV', u'ZSL'],
 [u'DSLV', u'SLVO'],
 [u'DBS', u'USV'],
 [u'DBS', u'SLV'],
 [u'DBS', u'SIVR'],
 [u'DBS', u'AGQ'],
 [u'DBS', u'USLV'],
 [u'DBS', u'ZSL'],
 [u'DBS', u'SLVO'],
 [u'DBS', u'DSLV'],
 [u'USV', u'SLV'],
 [u'USV', u'SIVR'],
 [u'USV', u'AGQ'],
 [u'USV', u'USLV'],
 [u'USV', u'ZSL'],
 [u'USV', u'SLVO'],
 [u'USV', u'DSLV'],
 [u'USV', u'DBS']]
				
			

Fantastico! Abbiamo un elenco completo di coppie univoche di ticker composte da ETF che hanno la parola “Silver” nel campo “Focus”.

Questo è molto utile quando dobbiamo fornire un input alla funzione di backtesting che descriviamo nel prossimo articolo.

Codice completo

In questo articolo abbiamo descritto come effettuare la creazione di coppie di Ticker degli ETF. Per il codice completo riportato in questo articolo, si può consultare il seguente repository di github: https://github.com/datatrading-info/Backtest_Strategie

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