Backtrader Indicatore Chaikin Money Flow

Indicatore Chaikin Money Flow con backtrader

In questo articolo descriviamo come implementare e come usare l’indicatore Chaikin Money Flow con Backtrader per creare strategie di trading algoritmico.

Il Chaikin Money Flow (CMF) è un popolare indicatore basato sul volume. È stato sviluppato da Marc Chaikin, analista, trader e imprenditore del settore dal 1965. Inoltre, ha sviluppato indicatori di trading a partire dagli anni ’80, durante i quali ha lavorato su alcuni dei più noti indicatori (questo è uno di questi). Più recentemente ha fondato la società Chaikin Analytics che fornisce strumenti e software di analisi.

Fonte:  https://en.wikipedia.org/wiki/Marc_Chaikin

L’indicatore CMF di Marc è disponibile su Tradingview come indicatore open source. In questo modo possiamo dare un’occhiata a quel codice e usarlo per creare un porting su Backtrader. Tuttavia, prima di descrivere il codice, introduciamo la teoria alla base dell’indicatore e alcuni dei più comuni modi di interpretazione e analisi.

Chaikin Money Flow

Progettato per misurare il flusso di denaro in un determinato periodo di tempo, l’indicatore Chaikin Money Flow è positivo quando il denaro entra in un asset e negativo quando il denaro esce da un asset. La formula di calcolo dell’indicatore produce un risultato che può assumere  solamente valori tra -1 e 1. Quindi questo questo indicatore può essere considerato un oscillatore.

L’indicatore ha 3 principali componenti:

  • Moltiplicatore: è il componente chiave che permette all’indicatore di oscillare. Si esegue un calcolo che produce un valore negativo o positivo. Tale valore è quindi essere usato come moltiplicatore. In altre parole, il valore è  positivo se il prezzo close è più vicino al massimo della giornata. Al contrario, se il prezzo close è più vicino al minimo della giornata, il valore è negativo.
  • Volume adattato: si modifica il volume rispetto ad un valore positivo o negativo (volume* il moltiplicatore)
  • Valore CMF:  si considera una  somma dei volumi adattati per un periodo x e la dividiamo per lo stesso periodo del volume totale.

I dettagli della formula e del calcolo sono descritti nel seguente codice. Per maggiori approfondimenti matematici si può consultare il seguente link:  https://en.wikipedia.org/wiki/Chaikin_Analytics#Chaikin_Money_Flow

Usare il Chaikin Money Flow

Dato che si tratta di un oscillatore, abbiamo molti modi per interpretare il valore. I principali sono i seguenti:

  • Linea zero: se l’indicatore è sopra lo zero, suggerisce che c’è una propensione all’acquisto. Se è inferiore, abbiamo un bias di vendita.
  • Estremi: se il valore CMF raggiunge un livello estremo, potrebbe indicare un’inversione di tendenza. Tuttavia, dobbiamo stare attenti nel definire estremo. A causa del modo in cui viene calcolato l’indicatore, più lungo è il periodo di riferimento utilizzato, minore è la probabilità che si raggiunga un livello estremo. Ad esempio, con un periodo di riferimento di 20 sono necessarie 20 chiusure consecutive dove il massimo è uguale al valore di chiusura per ottenere il valore 1.

Il codice

Vediamo come implementare con python l’indicatore Chaikin Money Flow in Backtrader

				
					"""
//@version=3
study(title="Chaikin Money Flow", shorttitle="CMF")
length = input(20, minval=1)
ad = close==high and close==low or high==low ? 0 : ((2*close-low-high)/(high-low))*volume
mf = sum(ad, length) / sum(volume, length)
plot(mf, color=green, title="MF")
hline(0, color=gray, title="Zero", linestyle=dashed)
"""

import backtrader as bt
from datetime import datetime

class MoneyFlow(bt.Indicator):

    lines = ('money_flow',)
    params = (
        ('len', 20),
        )

    plotlines = dict(
        money_flow=dict(
            _name='CMF',
            color='green',
            alpha=0.50
        )
    )

    def __init__(self):
        # Permettere all'indicatore di avere abbastanza dati
        self.addminperiod(self.p.len)

        # Visualizza la linea orizzondale
        self.plotinfo.plotyhlines = [0]

        # Alias per evitare righe troppo lunghe
        c = self.data.close
        h = self.data.high
        l = self.data.low
        v = self.data.volume

        self.data.ad = bt.If(bt.Or(bt.And(c == h, c == l), h == l), 0, ((2*c-l-h)/(h-l))*v)
        self.lines.money_flow = bt.indicators.SumN(self.data.ad, period=self.p.len) / bt.indicators.SumN(self.data.volume, period=self.p.len)


class testStrategy(bt.Strategy):

    def __init__(self):
        self.rsi = MoneyFlow(self.data)

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

# Aggiungere la strategia
cerebro.addstrategy(testStrategy)

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

# Aggiungere i dati a Cerebro
cerebro.adddata(data)

# Esecuzione del backtest
cerebro.run()

# Grafico dei risultati
cerebro.plot(style='candlestick')
				
			

Commento del codice

Tutta la logica di questo indicatore è implementata nel metodo __init__(). Per chiunque abbia una conoscenza di base di Backtrader e Python, la maggior parte del codice all’interno __init()__ dovrebbe essere autoesplicativo. Se invece sei un  neofita puoi leggere i precedenti articoli relativi a Backtrader.

Due temi che non sono ancora stati approfondi sono il dizionario plotlines e l’oggetto lines self.data.ad.

Plotlines

Tramite il dizionario delle plotlines possiamo specificare l’aspetto di visualizzazione dell’oggetto lines. Ogni lines ha il proprio dizionario al suo interno. In questo modo possiamo specificare parametri diversi per lines diverse. Backtrader usa matplotlib per  i grafici e quindi abbiamo bisogno di fare riferimento alla documentazione di matplotlib per capire quali opzioni/parametri abbiamo a disposizione. La documentazione ufficiale fa una menzione speciale a questo aspetto:

La maggior parte delle opzioni specificate in plotlines sono pensate per essere trasferite direttamente  matplotlib durante la produzione dei grafici.

Quindi, ad esempio, nei documenti ufficiali di Backtrader abbiamo il seguente codice:

				
					
lines = ('histo',)
plotlines = dict(histo=dict(_method='bar', alpha=0.50, width=1.0))
				
			

Tuttavia, seguendo quanto sopra e proviamo ad impostare un parametro width sul grafico di una lines piuttosto che sul grafico di una barra (modificando il metodo _method), otteniamo delle anomalie. Quindi è sempre una buona idea controllare la documentazione di matplotlib.

Documentazione di Backtrader:  https://www.backtrader.com/docu/plotting/plotting#line-specific-plotting-options

Documentazione di Matplotlib:  https://matplotlib.org/api/pyplot_summary.html

Opzioni di Matplotlib per la barra:  https://matplotlib.org/api/_as_gen/matplotlib.pyplot.bar.html#matplotlib.pyplot.bar

bt.If(), bt.And() e bt.Or()

Veddiamo ora l’oggetto lines self.data.ad. Anche se all’inizio sembra piuttosto complesso, possiamo scomporlo nella seguente logica:

self.data.ad = bt.If(bt.Or(bt.And(c == h, c == l), h == l), 0, ((2*c-l-h)/(h-l))*v)

SE Close == High E Close == Low O High == Low ALLORA assegniamo il valore 0 ALTRIMENTI eseguiamo il calcolo del moltiplicatore.

Può sembrare un po’ complicato perché dobbiamo nidificare  bt.And()bt.Or() all’interno della funzione bt.If(). Questo è necessario perchè non possiamo usare gli operatori if, and e or di python quando creaiamo nuovi dati lines all’interno del metodo __init__. A causa di questa è una limitazione tecnica sono stati creati bt.If() e una serie di altri operatori come soluzione alternativa. Per ulteriori informazioni, consultare la seguente documentazione:

https://www.backtrader.com/docu/concepts#some-non-overriden-operators-functions

Il Grafico

Infine, vediamo il grafico dell’indicatore Chaikin Money Flow in Backtrader applicato su alcuni dati.

Backtrader Indicatore Chaikin Money Flow - Grafico

Codice completo

In questo articolo abbiamo descritto come implementare e come usare l’indicatore Chaikin Money Flow con Backtrader per creare strategie di 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