Strategia di Moving Average Crossover in Python con Pandas

Sommario Tutorial

TUTORIAL

Nel precedente articolo relativo allo Sviluppo di un BackTesting Vettoriale con Python e Pandas abbiamo creato un ambiente di backtesting orientato agli oggetti e testato su una strategia di previsione casuale. In questo articolo utilizzeremo gli strumenti che abbiamo introdotto per condurre ricerche su una strategia reale, ovvero il Moving Average Crossover su AAPL.

Strategia di Moving Average Crossover

La strategia di Moving Average Crossover (ovvero incrocio della media mobile) è una semplice strategia di momentum estremamente nota. È spesso considerata come l’esempio di “Hello World” per il trading quantitativo.

La strategia qui descritta è solo long. Si considerano due simple moving average separate, costruite su diversi periodi, di una particolare serie storica. I segnali per l’acquisto dell’asset si verificano quando la media mobile semplice più breve incrocia dal basso, cioè supera, la media mobile semplice più lunga. Se successivamente la media più lunga supera la media più breve, l’asset viene venduto. La strategia funziona bene quando una serie temporale entra in un periodo di forte trend e poi rallenta lentamente.

Per questo esempio, ho scelto Apple, Inc. (AAPL) come serie temporali, con una media mobile breve di 100 giorni e una media mobile lunga di 400 giorni. Questo è l’esempio presente nella libreria di trading algoritmico “zipline“. Quindi, se vogliamo implementare il nostro backtester, dobbiamo assicurarci che corrisponda ai risultati ottenuti da zipline, come metodo base per la convalidare il test.

Implementazione

Assicurati di aver letto il precedente tutorial, che descrive come viene costruita la gerarchia dell’oggetto iniziale del nostro backtester, altrimenti il codice sottostante non potrà funzionerà. Per questa particolare implementazione ho usato le seguenti librerie:

  • Python – 3.7
  • NumPy – 1.16.2
  • Pandas – 0.24.2
  • Matplotlib – 3.0.3

L’implementazione di ma_cross.py richiede il file backtest.py del precedente tutorial. Il primo passaggio consiste nell’importare i moduli e gli oggetti necessari:

Come nel precedente tutorial, si eredità la classe astratta della strategia (Strategy) per produrre la classe MovingAverageCrossStrategy, che contiene tutti i dettagli per generare  segnali quando le medie mobili di AAPL si incrociano l’una sull’altra.

L’oggetto richiede una short_window e una long_window su cui operare. I valori sono stati impostati com valori predefiniti, rispettivamente pari a 100 giorni e 400 giorni, che sono gli stessi parametri utilizzati nell’esempio di zipline.

Le medie mobili vengono create tramite la funzione rolling_mean applicata a bars['Close'], cioè i prezzi di chiusura del titolo AAPL. Una volta che le singole medie mobili sono state calcolate, la serie di segnali viene generata impostando la colonna uguale a 1,0 quando la media mobile breve è maggiore della media mobile lunga o 0,0 in caso contrario. Da queste informazioni si può generare gli ordini positions per rappresentare i segnali di trading.

La classe MarketOnClosePortfolio è una classe derivata dalla classe astratta Portfolio, presente in backtest.py. È quasi identico all’implementazione descritta nel tutorial precedente, con l’eccezione che le operazioni vengono ora eseguite su base Close-to-Close, piuttosto che Open-to-Open. Ho trascritto tutto il codice completo per rendere autonomo questo tutorial:

Ora che sono state definite le classi MovingAverageCrossStrategy e MarketOnClosePortfolio, verrà chiamata una funzione __main__ per collegare insieme le funzionalità delle due classi. Inoltre, la performance della strategia sarà esaminato attraverso un grafico della curva equity.

L’oggetto DataReader di pandas scarica i prezzi OHLCV del titolo AAPL per il periodo che va dal 1 gennaio 1990 al 1 gennaio 2002, in seguito di crea il DataFrame signals per generare i segnali long-only. Successivamente il portafoglio è generato con una base di capitale iniziale di 100.000 USD e i rendimenti sono calcolati sulla curva equity.

Il passaggio finale consiste nell’utilizzare matplotlib per tracciare un grafico a due figure con i prezzi di AAPL, sovrapposti con le medie mobili e i segnali di acquisto / vendita, nonché la curva equity con gli stessi segnali di acquisto / vendita. Il codice di plotting è stato preso (e modificato) dall‘esempio di zipline.

Il grafico output del codice è il seguente. Ho fatto uso del comando IPython %paste per inserirlo direttamente nella console IPython di Ubuntu, in modo che l’output grafico rimanesse visibile. Gli uptick rosa rappresentano l’acquisto del titolo, mentre i downtick neri rappresentano la vendita:
Performance di un Moving Average Crossover su AAPL tra il 01/01/1990 e il 01/01/2002
Come si può vedere la strategia perde denaro lungo questo periodo, con cinque trade di apertura e chiusra della posizione. Ciò non sorprende, tenuto conto del comportamento dell’AAPL nel periodo in esame, che era leggermente in calo, seguito da un significativo aumento a partire dal 1998. Il periodo di take profit dei segnali della media mobile è piuttosto ampio e ha influito sul profitto finale dell’operazione. , che altrimenti potrebbe l’avrebbe resa una strategia redditizia. Negli articoli successivi creeremo uno strumento più sofisticato per analizzare le prestazioni, oltre a descrivere come ottimizzare i take profit dei singoli segnali della media mobile.

 

Per il codice completo riportato in questo articolo utilizzando il modulo di backtesting vettoriale VectorBacktest si può consultare il seguente repository di github:
https://github.com/datatrading-info/VectorBacktest

Torna in alto
Scroll to Top