Primo Script con BackTrader

Primo Script con BackTrader

Dopo aver creato il nostro ambiente di sviluppo, come descritto in questo articolo, in questo articolo descriviamo come creare il primo script con Backtrader per verificare le prestazioni di strategie di trading algoritmico e quantitativo

Obiettivo

Questo articolo ha lo scopo di creare una semplice strategia basata sugli indicatori, mantenendo il codice il più semplice possibile. Cercherò di evitare alcuni concetti più avanzati presenti nella documentazione e in Python in generale. Ad esempio le linee come:

				
					if __name__ == '__main__': 
				
			

non saranno incluse perchè per imparare è necessario che i principianti dovrebbero cercare di reperire le informazioni su internet ed inoltre non voglio distrarre il lettore dalle funzionalità strettamente legate alla strategia che si vuole implementare (anche se alcuni programmatori professionisti potrebbero deridere la qualità del codice).

Ambito di backtesting: Per motivi di semplicità, il tutorial non include le commissioni, lo spread o altre considerazioni di backtesting più avanzate come benchmarking, l’ottimizzazione e l’analisi dei trade. Ho anche scelto di escludere la stampa / log per mantenere il codice il più semplicepossibile. (Anche se penso che la stampa / log sia importante per il debug quando aumenta la complessità del codice!)

La Strategia

Al momento della stesura di questo articolo siamo in presenza di un lungo mercato rialzista. Quando si negoziano azioni in un tale mercato, è ragionevolmente pensare di andare long. La ragione di ciò è che si trovano sul lato giusto del momentum long alla base della dinamica ascendente.

Con questo in mente, divertiamoci un po’ a implementare nel primo script con backtrader una strategia “solo long” che andrà long quando un semplice indicatore RSI giornaliero è ipervenduto e si mantiene la posizione fino a quando l’RSI non raggiungerà il livello di ipercomprato.

Entry

  • Quando RSI <30

Exit

  • Quando RSI> 70

Gestione del trade e dimensionamento delle posizioni

  • Non si implementa nessuna gestione del trade. Non è previsto nessun ridimensionamento in / out. Solo semplici acquisti e vendite con un’unica posizione aperta alla volta.
  • Per quanto riguarda le dimensioni della posizione, si semplifica le cose comprando / vendendo 100 azioni alla volta senza fare calcoli per vedere se abbiamo abbastanza liquidità per le dimensioni della posizione (se non abbiamo abbastanza liquidità, backtrader è abbastanza intelligente da rifiutare l’ordine)

Settaggio dell’indicatore

  • Periodo = 21
    Consente di utilizzare una finestra mobile più lunga rispetto ai 14 periodo standard. In teoria ciò dovrebbe tradursi nell’avere meno falsi segnali falsi e il prezzo dovrebbe scendere / aumentare di più prima di essere considerato ipercomprato / ipervenduto.
 

Requisiti​

In questo primo script con backtrader prevediamo di estrae i dati online da Yahoo. Penso che questo semplifichi le cose per un primo script in quanto non sarà scaricare ed utilizzare i propri dati. Tuttavia, per questo motivo, lo script richiede laa versione backtrader 1.9.49.116 o successiva a causa delle recenti modifiche nell’API di Yahoo.
Per verificare la versione di backtrader che stai utilizzando hai alcune opzioni. Per prima cosa puoi controllare il pip semplicemente digitando:

				
					pip3 list
				
			

(Nota per gli utenti di Windows: invece di “pip3” potrebbe essere “pip” se è installata solo una versione di python).

Quindi basta cercare la voce “backtrader” nell’output del precedente comando. Gli utenti Linux e Mac possono rendere questo processo un po ‘più veloce eseguendo il piping dell’output su grep.

				
					pip3 list | grep backtrader
				
			

Ho notato che su una delle mie macchine Linux, pip3 riportava una versione inferiore rispetto a quella effettivamente installata (non ho ancora capito perché). Quindi, se la versione segnalata non sembra corretta, possiamo anche controllarla aprendo una shell python, importare backtrader e stampare la versione.

				
					import backtrader as bt
print(bt.__version__)
				
			

Se non si utilizza la versione più recente, avviare un terminale (o il prompt dei comandi) e digitare i seguenti comandi:

				
					pip3 install --upgrade backtrader
				
			

I risultati

Per vedere i risultati del nostro primo script con backtrader in un grafico bidimensionale, si può usare la libreria Python (esterna all’installazione standard) chiamata “Matplotlib”. Questo modulo è la libreria grafica defacto per molti scienziati, analisti e ricercatori che usano Python.

Assicurati di averlo installato aprendo un terminale o un prompt dei comandi e digitando:

				
					pip3 install matplotlib
				
			

Primo script con Backtrader

Lo script è composto da due parti principali. La prima parte si crea una nuova classe dove implementare tutta la logica della strategia. Nella seconda parte si configura l’ambiente di esecuzione dello script (come aggiungere il framework, prevedere una fonte dati per i test, ecc.).

Nota importante: in questo esempio si utilizza i dati disponibili con l’API di Quandl. Con questa API sei limitato al numero di chiamate che puoi effettuare al giorno. Per avere accesso illimitato ai loro dati è sufficiente registrarsi gratuitamente nel loro sito e richiedere una API key ed aggiungi la keyword apikey alla chiamata ai dati di quandl in questo modo (www.quandl.com):

				
					
data = bt.feeds.Quandl(
    dataname='F',
    fromdate = datetime(2016,1,1),
    todate = datetime(2017,1,1),
    buffered= True,
    apikey="INSERT YOUR API KEY"
    )
				
			

Importazioni

				
					import backtrader as bt
from datetime import datetime
				
			

Il primo import dovrebbe essere abbastanza ovvia. Stiamo importando il framework backtrader. Inoltre, si importa il modulo datetime dalla libreria standard di Python. Questo è usato per impostare le date di inizio e fine del periodo di backtesting. Backtrader prevede di ricevere oggetti datetime durante la creazione di feed di dati. Per ulteriori informazioni sul modulo datetime, consultare la documentazione disponibile su:

docs.python.org/3/library/datetime.html

La strategia

				
					

class firstStrategy(bt.Strategy):

    def __init__(self):
        self.rsi = bt.indicators.RSI_SMA(self.data.close, period=21)

    def next(self):
        if not self.position:
            if self.rsi < 30:
                self.buy(size=100)
            else:
                if self.rsi > 70:
                    self.sell(size=100)
				
			

Per creare una strategia con backtrader, dobbiamo ereditare molti metodi e attributi dalla classe base `bt.Strategy`. In altre parole, dobbiamo prendere il template di una strategia che è stata scritta nel framework di backtest e aggiungere la logica della nostra strategia. 

Nella programmazione questa tecnica si chiama ereditarietà. In questo modo possiamo usare tutto il codice che è stato scritto nella strategia di base e sovrascrivere le parti che vogliamo cambiare. Non è necessario preoccuparsi di tutto il codice, dietro le quinte, che consente di interagire con i dati, gestire gli ordini, le notifiche dei broker e così via. E’ Il framework BackTrader che se ne occupa! 

La nuova classe della strategia può essere breve, pulita e di facile lettura. Tuttavia, se lo desideri, puoi scavare più a fondo e modificare il contenuto del nucleo della classe base. La classe del nostro primo script con backtrader si chiama firstStrategy (piuttosto originale) e contiene il codice per l’inizializzazione della strategia e il metodo “next”.

L’inizializzazione è solo una riga, vogliamo solo inizializzare un indicatore RSI dalla libreria di backtrader. Per fare ciò si aggiunge l’indicatore durante l’inizializzazione della strategia (__init__). Una volta impostato, backtrader si occupa di tenere traccia dei dati, calcolare i risultati e aggiungerli al grafico finale.

Se non conosci la programmazione, puoi notare che possiamo chiamare l’indicatore RSI come preferisci, ma devi prefissarlo con “self”. In questo modo può essere usato da altri metodi (chiamati anche “funzioni” quando non stiamo parlando di una classe). In questo caso, abbiamo semplificato la lettura del codice e inizializzato l’indicatore come “self.rsi”.

Il metodo next (funzione) viene chiamato ad ogni nuova barra o, in altre parole, ogni volta che viene ricevuta una nuova candela. È in questo metodo che si deve scrivere la logica “if this then that“. In questo esempio si controlla se siamo in posizione, dato che come prerequisito si prevede di effettuare un solo trade alla volta. 

Se non siamo in una posizione, allora si verifica il livello dell’indicatore RSI. Se è inferiore a 30, si acquista 100 azioni mentre se è superiore non si fa nulla (Perché non abbiamo scritto alcun codice per ciò che accade quando l’RSI è sopra i 30 e non siamo in una posizione). 

Il secondo step della logica prevede le azioni da fare quando SIAMO già in una posizione. In questo caso si cerca un’opportunità di vendita. Se l’RSI supera i 70, si vende tutte le 100 azioni. Altrimenti, di nuovo non si fa nulla. Questo si ripete ogni volta che arriva una nuova candela (ogni giorno) fino a quando tutti i dati sono stati controllati.

Il Setup

				
					

# Variabile per il capitale iniziale
startcash = 10000

# crea un'istanza di cerebro
cerebro = bt.Cerebro()

# Aggiunge la strategia
cerebro.addstrategy(firstStrategy)

# Download dei dati di Apple da Yahoo Finance.
data = bt.feeds.Quandl(
    dataname='AAPL',
    fromdate = datetime(2016,1,1),
    todate = datetime(2017,1,1),
    buffered= True
    )

# Aggiungi i dati di Apple a Cerebro
cerebro.adddata(data)

# Imposta il capitale iniziale
cerebro.broker.setcash(startcash)
				
			

Dopo aver scritto la strategia, è necessario implementare il setup e all’esecuzione. Questo in sostanza si riduce a:

  • Chiamare il motore backtrader (cerebro)
  • Ottenere i dati storici e caricarli nel motore.
  • Impostazione della quantità di denaro che dobbiamo negoziare (startcash)
  • Caricare la strategia nel motore
  • Esecuzione del test
  • Monitorare i risultati

Alcune cose da sottolineare:

  • Durante la stampa, si utilizza l’argomento con keyword style = candlestick, se non lo si utilizza si ottiene un grafico a linee del prezzo di chiusura.
  • Durante l’inizializzazione del feed dei dati si richiama il modulo datetime, come sottolineato in precedenza. Stiamo passando un oggetto datetime agli argomenti della keyword fromdate e todate. Infine la keyword buffer indica che backtrader eseguirà il buffer di tutti i dati richiesti prima dell’inizio dell’analisi.

Eseguire lo script

Presumo che tu abbia svolto le lezioni di base su Python, come menzionato nel mio precedente post. Quindi copia il codice, aggiungi le parti basi del linguaggio, avvia lo script e controlla i risultati.

I Risultati

Primo script con backtrader

2 operazioni in profitto. Tasso di vincita del 100%. Saremo ricchi!

Tornando ad un tono più serio, prendi questi risultati con le pinze. Non abbiamo confrontato i risultati con un benchmark o una semplice strategia di “buy & hold”. Non abbiamo aggiunto commissioni e slippage, non disponiamo di dati di test a lungo termine sufficienti per convalidare la strategia. Un test per un titolo azionario in solo anno non dovrebbe riempirci di fiducia, ma almeno abbiamo creato una base per fare ricerche ulteriori.

Codice completo

 in questo articolo abbiamo descritto come creare il primo script con Backtrader 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/BackTrader

Scroll to Top