Se mi affacciassi oggi per la prima volta sui mercati finanziari di sicuro avrei molti più strumenti di un tempo. Non sto parlando soltanto di piattaforme più o meno stabili, ma anche di informazioni e strumenti gratuiti con i quali passare da un’idea, alla sua implementazione, in un tempo molto contenuto. In questo articolo desidero fare un esempio concreto e mi rivolgo in particolare a tutti coloro che ritengano si debba disporre di chissà quale tecnologia per arrivare ad un risultato concreto. Il mio pensiero va anche a tutti coloro che utilizzino da anni strumenti come Tradestation, Multicharts, Amibroker o la Metatrader per fare cose simili: leggete fino in fondo e proveremo a smantellare alcuni luoghi comuni sull’utilizzo di un vero linguaggio di programmazione.
Obiettivo: costruire un codice che permetta di sondare un pattern a piacere su un singolo strumento finanziario e successivamente su un intero paniere.
Primo problema: l’accesso ai dati.
Apriamo un Jupyter Notebook e importiamo le librerie che ci serviranno:

Si tratta di Numpy (per le operazioni algebriche), Pandas (per strutturare i dati in modo più comodo con i dataframe), Matplotlib (la principale libreria grafica) ed FFN (una libreria di analisi quantitativa, tra le tante disponibili, che contiene anche un comodo modulo di lettura dati da Yahoo Finance).
Decidiamo di indagare un primo titolo (Caterpillar, ticker CAT) e di fare riferimento allo storico dal 2010 ad oggi.

Creiamo una stringa di servizio che chiamiamo “input_string” che passeremo ad una funzione della libreria FFN per scaricare lo storico.


L’utilizzo della funzione anonima “lambda” ci serve a troncare al tick i prezzi scaricati da Yahoo Finance. Il nostro dataset è ora un Pandas DataFrame e ne visualizziamo le prime 10 righe. Noterete come Python, mediante Pandas, abbia già organizzato i nostri dati in una matrice di righe e colonne (appunto un Pandas DataFrame), abbia associato i tipi di dato opportuni a ciascun campo e abbia impostato le date come indice di riga (l’index della nostra base dati). Non è poco non doverci preoccupare di questi aspetti.
Successivamente sostituiamo, per maggiore pulizia, i nomi delle colonne con “open, high, low, close, volume”. Questa volta con “tail” visualizziamo gli ultimi 10 record.

Da questo momento abbiamo accesso da codice a tutti i campi come oggetti, senza doverci preoccupare che siano tali! Ad esempio, possiamo richiamare il campo chiusura semplicemente come nell’immagine seguente.

Ma la cosa notevole è che Pandas ci consente di fare dei confronti su base colonna a velocità C (notoriamente la velocità associata al linguaggio C è un termine di confronto importante per i linguaggi interpretati): ad esempio, se desideriamo verificare quando la chiusura sia superiore all’apertura (candela bianca o verde) dovremo semplicemente impostare la relazione tra oggetti Pandas.

In corrispondenza ad ogni True saremo in presenza di una candela rialzista.
Non ci rimane che generare degli indicatori di supporto con i quali definire il nostro pattern.

Nell’ultima immagine vediamo come sia possibile aggiungere varie colonne al nostro dataframe di partenza, mediante il formalismo:
dataframe[nuova_colonna] = contenuto
• In riga 1 generiamo la variazione percentuale di ciascuna barra calcolata da minimo e massimo.
• In riga 2 calcoliamo la posizione percentuale dell’apertura rispetto all’estensione tra massimo e minimo (fatti 100 gli intervalli possibili).
• In riga 3 calcoliamo la posizione percentuale della chiusura rispetto all’estensione tra massimo e minimo (fatti 100 gli intervalli possibili).
• In riga 4 calcoliamo la media mobile semplice a 20 periodi.
• In riga 5 calcoliamo la deviazione standard a finestra scorrevole di 20 periodi.
• In riga 6 e 7 calcoliamo rispettivamente la banda di Bollinger superiore ed inferiore.
• In riga 8 eliminiamo le righe in cui tali indicatori non siano ancora stati calcolati a causa della finestra scorrevole.
Non ci rimane che disegnare la curva delle chiusure e le bande di Bollinger sull’intero periodo di osservazione.

Potremmo utilizzare grafici interattivi e abbellire esteticamente il tutto con animazioni, ma rimaniamo concentrati sul codice di base e sul nostro obiettivo: creare uno screener prima della fine di questo articolo.
Andiamo dunque al sodo: definiamo il nostro pattern. Cerchiamo di rappresentare ad esempio una declinazione dell’ “hammer” che, in letteratura, consiste in una candela di possibile inversione rialzista durante un downtrend (fase ribassista). Per ottenerlo creiamo la nuova colonna “setup” che risulterà vera solo se saranno verificate contemporaneamente le seguenti condizioni:
1) Minimo attuale inferiore alla banda di Bollinger inferiore.
2) Chiusura sopra la stessa banda.
3) Chiusura posizionata sopra il 70% di escursione tra minimo e massimo.
4) Apertura posizionata sopra il 70% di escursione tra minimo e massimo.
5) Range (H-L) percentuale superiore all’1%.
Il simbolo “&” ci serve per enare le varie condizioni booleane (vere o false).

In figura possiamo osservare un’occorrenza di tale pattern in occasione del 27 ottobre 2010.
Ma per misurare se un pattern abbia valenza statistica, è opportuno osservare se in seguito alla sua manifestazione si generi una reazione del prezzo. Campioneremo tale reazione da una a dieci barre successive (anche se ci aspettiamo una reazione entro le prime cinque, al netto del bias rialzista che da sempre impatta il mercato azionario).
Per farlo realizziamo altre 10 colonne (ognuna per ogni giorno di osservazione) e mediante l’istruzione condizionale “np.where”, presa in prestito da Numpy, registriamo la differenza tra la chiusura di ciascun giorno e l’apertura del giorno successivo alla manifestazione del pattern. Se il giorno precedente il pattern non è stato individuato non popoliamo il campo.

Con una semplice istruzione di filtro sul DataFrame possiamo individuare tutte le date in cui il nostro hammer si sia manifestato.

Inoltre possiamo contare quante volte ciò sia avvenuto.

Ora, senza voler ricorrere a funzioni o cicli, osservate come sia possibile calcolare le statistiche relative alla sommatoria dei vari contributi (nell’esempio di figura vediamo il caso ad uno e due giorni successivi alla manifestazione del pattern).

Nel primo caso vediamo che cumulando i contributi successivi ad 11 hammer, otteniamo 5.02 $ dopo un giorno (con 8 trade in guadagno e 3 in perdita), 19.01 $ dopo 2 giorni (sempre con 8 trade in guadagno e 3 in perdita). Completando l’analisi per tutti e 10 i giorni e sistemando i risultati in un Pandas DataFrame, otteniamo dei risultati decisamente lusinghieri.

Non ci rimane che graficarli, come di consueto, mediante la libreria Matplotlib.

Lo shape della curva ci racconta di un massimo di reazione intorno ai 4 giorni successivi alla manifestazione del pattern. La successiva salita probabilmente è imputabile al bias di mercato.
Prima di procedere due parole sul codice: se qualche passaggio non fosse chiaro a prima lettura è più che naturale (è possibile colmare queste lacune sia da autodidatta, che seguendo la Python Academy), ma invito chi conosca Easylanguage / Powerlanguage a riflettere sulla maggiore pulizia del codice Python, sulla sua gratuità e fruibilità a 360 gradi. Ma questo è solo l’inizio!
Utilizzando le librerie Plotly & Cufflinks possiamo stampare la fase storica successiva a ciascuna manifestazione del pattern (il pattern identificato si trova in prima posizione da sinistra):

Il grafico si presenta ora in modo interattivo ed è molto semplice passare da una occorrenza alla successiva.

Vediamo adesso cosa accada se proviamo a ribaltare il pattern in modo speculare passando da un hammer ad una “shooting star” (la “stella cadente” è un pattern con implicazioni ribassiste da letteratura). Di seguito il codice che adesso fa riferimento alla banda di Bollinger superiore e posiziona apertura e chiusura sotto il 30% dell’escursione giornaliera. Ipotizzeremo di entrare short l’apertura successiva alla manifestazione del pattern.

Di seguito le statistiche relative ed il grafico riepilogativo.


Traspare chiaramente come convenga attendere fino ad una settimana per monetizzare l’effetto di una shooting star. Nei primi due giorni il contributo è addirittura negativo. Un po’ come una torta che debba ancora lievitare. In questo caso le occorrenze sono 15 su un periodo di 10 anni.

Ovviamente questi risultati (11 occorrenze per l’hammer e 15 per la shooting star) non hanno alcuna valenza statistica se prese da sole (il filtro all’1% di escursione è molto stringente). Tuttavia possiamo recuperare tale significatività ampliando l’analisi ad un paniere intero e arrivare a centinaia o a migliaia di occorrenze.
Per farlo in un esempio veloce nel caso del pattern hammer, abbiamo sistemato le funzionalità ricorrenti all’interno di cicli e funzioni e, se avete voglia di approfondire, potete trovare la ratio all’interno del libro “Strategie di trading con Python” edito da Hoepli e i codici integrali all’interno della Python Academy.
Di seguito la matrice dei risultati su 15 titoli pescati dal Dow Jones 30 Index.

Sulle righe vediamo i giorni successivi al pattern hammer, sulle colonne il ticker relativo al singolo asset e a destra la media per ciascuna riga. Questo campo (il “basket”) segnala se sia stato conveniente o meno applicare tale strategia sull’intero paniere. Il massimo dell’efficacia lo otteniamo tra tre e cinque giorni dopo il pattern. Ma diamo uno sguardo più qualitativo agli stessi dati, utilizzando una heatmap della libreria Seaborn.

A colpo d’occhio possiamo apprezzare come la strategia di acquistare dopo un hammer sia vincente in particolare su MMM, CAT, GS e JNJ. Allo stesso modo la heatmap suggerisce come potrebbe essere utilizzata al contrario (andando short) su BA, CVX, KO e IBM. Di seguito un dettaglio dei ticker con contributo positivo giorno per giorno.

Questa analisi ci dice varie cose:
– Innanzitutto, di come non servano dati a pagamento o piattaforme costose per analizzare il mercato sul time frame daily. Le cose cambiano in intraday, dove la qualità dei dati sulle fonti free diventa meno competitiva (va detto tuttavia che la disponibilità di dati di buona qualità rappresenta un prerequisito essenziale anche disponendo di piattaforme a pagamento e fa parte dei costi fissi di un’impresa di trading).
– Di come il codice sia pulito, ordinato e quindi di semplice interpretazione anche a prima lettura e non essendo dei programmatori (anche grazie all’indentazione obbligatoria). Ciò agevola moltissimo anche progetti in team, tipici della ricerca finanziaria.
– Costituisce un patrimonio di conoscenza che non si esaurisce all’interno di questa o quella piattaforma commerciale, ma è utilizzabile e rivendibile anche in ambito lavorativo e in modo multidisciplinare (ripetiamo sempre il mantra “perché apprendere qualcosa con fatica se poi non è scalabile anche nel mondo del lavoro come competenza riconosciuta?”).
Se vi siete incuriositi e desiderate iniziare un cammino concreto di conoscenza su Python e sull’Analisi Quantitativa avete tre strade:
1) Studiare Python da soli da autodidatti senza spendere un euro. La salita sarà più faticosa e richiederà più tempo, ma rimane una scelta valida.
2) Leggere il libro “Strategie di trading con Python” edito da Hoepli. Un modo per fare una rapida full immersion sui temi principali con un investimento minimo.
3) Seguire la Python Academy da subito e comodamente da casa propria. Un percorso completo ed esauriente che vi porterà ad essere indipendenti su tanti temi tra i quali: l’analisi profonda dei dati, la ricerca di inefficienze statistiche da sfruttare in modo ripetitivo sui mercati finanziari, la realizzazione di diversi motori di backtesting ed ottimizzazione (che vi renderanno indipendenti da Tradestation e Multicharts ad esempio, nella creazione di trading system), la costruzione di architetture evolute di validazione, la costruzione e l’utilizzo di sistemi di inibizione e riattivazione di strategie (Equity & Performance Control), la realizzazione e la gestione di portafogli di strategie (in ottica trading) e di portafogli costruiti con differenti strumenti finanziari (in ottica investing). Dulcis in fundo come collegare i vostri codici all’API del broker per andare a mercato in maniera automatica. Ovviamente questi sono solo i punti cardinali di un percorso che si snoda su 16 settimane e 7 moduli didattici, con una interattività garantita direttamente con me.
Desidero segnalare come la Python Academy sia anche una community di persone che si scambiano codici e idee di trading e di investing (in questo bacino peschiamo anche per collaborazioni mirate) e di come sia un percorso in continuo aggiornamento ed evoluzione, insomma un prodotto “vivo”.
Dato che ogni persona ha esigenze diverse e soprattutto aspettative differenti, da diversi anni organizziamo (per chi vuole) dei colloqui telefonici gratuiti per orientare la persona sul percorso più adatto o per indirizzarlo altrove. E’ sufficiente scriverci allo stesso indirizzo info@gandalfproject.com.
Sperando di avervi fatto cosa gradita vi auguriamo una buona prima settimana di Agosto!
Giovanni Trombetta
Head of Research & Development
Gandalf Project
AVVERTENZE: I contenuti di questo articolo (e degli altri contenuti in questo sito) e le opinioni espresse non devono in nessun caso essere considerati come un invito all’investimento.
Le analisi non costituiscono mai una sollecitazione all’acquisto o alla vendita di qualsivoglia strumento finanziario. Queste note hanno per oggetto analisi finanziarie e ricerca in materia di investimento. Qualora vengano espresse delle raccomandazioni, queste hanno carattere generale, sono rivolte ad un pubblico indistinto e mancano dell’elemento della personalizzazione.
Sebbene frutto di approfondite analisi, le informazioni contenute in questo e negli altri articoli possono contenere errori. Gli autori non possono in nessun caso essere ritenuti responsabili per eventuali scelte effettuate dai lettori sulla base di tali informazioni erronee. Chi decide di porre in essere una qualsiasi operazione finanziaria sulla base delle informazioni contenute nel sito lo fa assumendone la totale responsabilità.
DISCLAIMER: The contents of these notes and the opinions expressed should in no case be considered as an invitation to invest. The analyzes never constitute a solicitation to buy or sell any financial instrument.
These notes relate to financial analysis and investment research. If recommendations are made, these are of a general nature, are aimed at an indistinct audience and lack the element of personalization.
Although the result of in-depth analysis, the information contained in these notes may contain errors. The authors cannot under any circumstances be held responsible for any choices made by readers on the basis of such erroneous information. Anyone who decides to carry out any financial transaction on the basis of the information contained in the site does so assuming full responsibility.