In questo articolo descriviamo come implementare il Klinger Oscillator con Backtrader per aggiungerlo come indicatore ad una strategia di trading algoritmico.
Klinger Oscillator
Il Klinger Volume Oscillator (KVO) prende il nome (come con tanti indicatori tecnici) dal suo inventore/sviluppatore Stephen J. Klinger. La documentazione su Internet suggerisce che il signor Klinger volesse sviluppare un indicatore in grado di identificare le tendenze del flusso di denaro a lungo termine, ma anche abbastanza sensibile da catturare le inversioni di prezzo a breve termine. Fonte: https://www.multicharts.com/support/base/volume-based-gt-klinger-volume-oscillator/
Nei set di dati OHLCV
, il volume fornisce il miglior indicatore del flusso di denaro. È probabilmente per questo motivo che è diventato il fulcro centrale di questo oscillatore. Ad esempio, se abbiamo più volume in acquisto che in vendita, il prezzo aumenterà. Al contrario, se abbiamo più volume in vendita che in acquisto, il prezzo scenderà. In altre parole, il volume misura i flussi di denaro in entrata/uscita da un asset.
Componenti
L’oscillatore di volume Klinger ha due linee principali, la linea KVO e una linea di segnale . La linea KVO è generata sottraendo un EMA lenta da un EMA veloce ( Exponential Moving Average). I dati dei volumi sono usati per alimentare le due EMA, ma vengono leggermente modificati prima di aggiungerli. Se il prezzo è in aumento, il volume viene aggiunto come valore positivo. Se il prezzo sta diminuendo, il volume viene aggiunto come valore negativo.
La linea di segnale è una semplice EMA a 13 periodi della linea KVO. La logica è simile a quella di un oscillatore stocastico.
Idee operative
I punti seguenti descrivono alcuni modi comuni per interpretare l’oscillatore KVO.
- KVO e Signal Crossovers: Dal momento che abbiamo due linee, un’opzione ovvia sarebbe andare long quando il KVO attraversa sopra la signal line e andare short quando la KVO line incrocia sotto la signal line.
- Zero Crossover: quando le linee KVO o Signal (scegli tu) attraversano la linea zero.
- Divergenza: quando il prezzo sta facendo un nuovo massimo o minimo ma la linea KVO non sta facendo un nuovo massimo/minimo.
- Momentum: Misura la forza del movimento, ovvero la “forza del volume” come conferma per determinare se un movimento di prezzo ha convinzione.
Il codice
Vediamo il codice che implementa l’oscillatore e descriviamo come funziona il Klinger Oscillator in Backtrader
"""
PINE SCRIPT EXAMPLE
//@version=3
study(title="Klinger Oscillator")
sv = change(hlc3) >= 0 ? volume: -volume
kvo = ema(sv, 34) - ema(sv, 55)
sig = ema(kvo, 13)
plot(kvo)
plot(sig, color=green)
"""
import backtrader as bt
from datetime import datetime
class KlingerOsc(bt.Indicator):
lines = ('sig','kvo')
params = (('kvoFast',34),('kvoSlow',55),('sigPeriod',13))
def __init__(self):
self.plotinfo.plotyhlines = [0]
self.addminperiod(55)
self.data.hlc3 = (self.data.high + self.data.low + self.data.close) / 3
# In backtrader l'indicizazione deve essere () invece che []
# Vedi: https://www.backtrader.com/docu/concepts#lines-delayed-indexing
self.data.sv = bt.If((self.data.hlc3(0) - self.data.hlc3(-1)) / self.data.hlc3(-1) >=0, self.data.volume, -self.data.volume)
self.lines.kvo = bt.indicators.EMA(self.data.sv, period=self.p.kvoFast) - bt.indicators.EMA(self.data.sv, period=self.p.kvoSlow)
self.lines.sig = bt.indicators.EMA(self.lines.kvo, period=self.p.sigPeriod)
class testStrategy(bt.Strategy):
def __init__(self):
self.KOsc = KlingerOsc(self.data)
# Creare una instanza di cerebro
cerebro = bt.Cerebro()
# Aggiungere la strategia
cerebro.addstrategy(testStrategy)
# Ottenere i dati da Yahoo Finance
data = bt.feeds.Quandl(
dataname='AAPL',
fromdate = datetime(2016,1,1),
todate = datetime(2017,1,1),
buffered= True,
apikey="NBQhvwRzCgdB-6e7XNAD"
)
# Aggiungere i dati a cerebro
cerebro.adddata(data)
# Esecuzione del backtest
cerebro.run()
# Grafico dei risultati
cerebro.plot(style='candlestick')
Commento del codice
La maggior parte della logica di questo indicatore è implementata nel metodo __init__
. Possiamo sfruttare la capacità di Backtrader di creare feed di dati e linee in __init__
senza dover chiamare next()
. In Tradingview è davvero semplice fare riferimento a un valore precedente nello stesso feed di dati. Questo è semplice anche in Backtrader MA devi leggere la documentazione e se sei neofito, potresti non sapere cosa cercare.
Per emulare Tradingview, in questo caso non possiamo utilizzare l’indicizzazione convenzionale di Backtrader, cioè self.data.hlc3[-1]
. Se lo facciamo otteniamo un errore di indicizzazione. Questo aspetto è molto importante è può creare problemi durante lo sviluppo dell’indicatore. Backtrader si basa su oggetto chiamato lines che prevede di indicizzare i valori nella fase __init__ usando ()
invece di []
. Per maggiori informazioni si rimanda alla seguente documentazione ufficiale:
Fonte: https://www.backtrader.com/docu/concepts#lines-delayed-indexing
Inoltre si può approfondire altri aspetti del framework Backtrader negli altri articolo disponibili su DataTrading.info. Infine, per determinare la forza del volume, l’indicatore esamina le variazioni del prezzo tipico per determinare se abbiamo un volume di acquisto o di vendita. Per determinare la variazione usiamo un valore hlc3
e lo confrontiamo con il valore hlc3
della barra precedente. Questo metodo è più accurato che valutare solamente la differenza tra i valori open
e close
, o close
e close
. Se il prezzo tipico è in aumento, la forza del volume è positiva e quindi si aggiunge il volume alla EMA. Se il prezzo tipico è in calo, il volume è negativo e quindi si sottrae il volume alla EMA.
Il grafico
Codice completo
In questo articolo abbiamo descritto come implementare il Klinger Oscillator con Backtrader ed aggiungerlo come indicatore ad una strategia 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