__ How can I create the indicator myself? __
Indicator creation -Create a class that inherits the bt.indicator class -Set the Lines object to plot ・ Set parameters such as the period of the moving average line -Add plot display settings if necessary ・ Write an expression I will create it in the flow.
As an example, let's create a stochastic oscillator and take a look at its contents.
sto1.py
import backtrader as bt
class MyStochastic1(bt.Indicator): #bt.Inherit Indicator
lines = ('k', 'd', ) #Lines object to display on the plot
params = (
('k_period', 14), #Specify parameters with tuples of tuples
('d_period', 3), #Comma at the end of the tuple(、)Put in
)
plotinfo = dict(plot =True,
subplot=True,
plotname='',
)
def __init__(self):
highest = bt.indicators.Highest(self.datas[0], period=self.params.k_period)
lowest = bt.indicators.Lowest(self.datas[0], period=self.params.k_period)
self.lines.k = k = (self.datas[0] - lowest) / (highest - lowest)
self.lines.d = bt.ind.SimpleMovingAverage(k, period=self.params.d_period)
def next(self):
pass
This is the big picture of the indicator class. A 14-day high / low price is required to calculate the stochastic oscillator. The amount of change is calculated by combining them with the closing price and smoothed by a 3-day simple moving average.
class MyStochastic1(bt.Indicator):
First, declare the "MyStochastic1" class that inherits the Backtrader Indicator class.
lines=('k','d')
There are two lines in Stochastic Oscillator, K and D. So I'm setting up two Lines objects to display on the plot. This Lines object is like "Index buffer" in MQL4, and is a ** iterable array ** in which a numerical value and a time axis are connected. Cerebro will plot this Lines object on the chart.
In MQL4, the latest bar is represented by [0]. Counting from the latest Bar, the number increases as it gets older, 1, 2, 3, .... Even in backtrader, the latest Bar / Lines object is represented by [0]. This is the same as MQL4. However, as the bar becomes older with 0 as the standard, minus signs such as -1, -2, -3 ... are added.
In this regard, Lines objects cannot perform Python's native slicing operations. If you want to use slices, use the get () method.
myslice = self.lines.my_sma.get (ago = 0, size = 1)
[-1] Only one array except [0]
myslice = self.lines.my_sma.get (ago = 0, size = 10)
10 arrays from [-1] to [-10] except [0]
myslice = self.lines.my_sma.get (ago = -1, size = 5)
Arrays from [-2] to [-6] except [-1]
** * The [] operator can be used for Lines objects only in the next method. I will summarize the next method at a later date. ** **
params = (
('k_period', 14),
('d_period', 3),
* # Add a comma at the end *
)
Stochastic oscillators perform calculations over a 14-day period and smooth the results with a 3-day simple moving average. (K_period, d_period) It is this parameter that sets it. Specify by tuple of tuple or dict (). (Reference 1)
It is expressed by writing "self.params.name" like self.params.k_period. For tuples, be careful not to forget to put the last comma.
plotinfo = dict(plot =True, subplot=True, plotname='', )
You can change the settings when plotting.
plot: Plot display On / Off subplot: Subplot display switching plotname: Footnote display name (class name is displayed if blank)
There are other setting items.
highest = bt.indicators.Highest(self.datas[0],period=self.params.k_period)
lowest = bt.indicators.Lowest(self.datas[0],period=self.params.k_period)
Describe the stochastic calculation in the init method.
First, calculate the high and low prices for 14 days. Fortunately, backtrader has an indicator that calculates the high and low prices for a specific period.
Built-in indicators can be called with bt.indicators.XXXX (). (Note s at the end!) Here we call Highest and Lowest to find the highest and lowest values during the k_period period. I put the result in the Lines objects highest and lowest.
self.lines.k = k = (self.datas[0] - lowest) / (highest - lowest)
self.lines.d = bt.ind.SimpleMovingAverage(k,period=self.params.d_period)
The Lines object to plot is represented by "self.lines.name". k is self.lines.k
and d is self.lines.d
. The resulting Lines object can also be used for calculations. Here, in order to simplify the notation of the calculation on the next line, it is assigned to "k" and passed to the simple moving average indicator.
self.datas[0]
Self.datas [0] in the formula represents the "first CSV data". Unless otherwise specified, the closing price is used. Since multiple data can be passed, for example, when passing two CSV data such as daily and weekly, the smaller time frame must be specified first and the larger time frame must be specified later. In other words, datas [0] must be daily data and datas [1] must be weekly data. This time, only daily data is passed.
--- | Official | abridgement |
---|---|---|
lines | self.lines.XXX | self.l.XXX |
params | self.params.XXX | self.p.XXX |
datas | self.datas[0].close | self.data.close or self.data |
indicators | bt.indicators.XXX | bt.ind.XXX |
Alias | SimpleMovingAverage | SMA |
Backtrader can be abbreviated. It's convenient, but it can be confusing until you get used to it. And in fact, you can omit all plotinfo this time. If plot, subplot, plotname are omitted, the default settings will be used.
I haven't used it this time, but if you want to judge the condition or perform processing for each Bar, describe the contents in the next method.
__ How do I display the indicator? __
All settings are complete. If you instantiate this indicator class inside the init method of the strategy class, Cerebro will plot it on the chart. You can freely name the instance.
self.myind1 = MyStochastic1(self.data)
(Explanatory comments have been added to various places and omitted as much as possible.)
sto12.py
%matplotlib notebook
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import datetime
import os.path
import sys
import backtrader as bt
class MyStochastic1(bt.Indicator):
lines = ('k', 'd', ) #Lines object to display on the plot
params = (
('k_period', 14), #Specify parameters with tuples of tuples
('d_period', 3), #Comma at the end of the tuple(、)Put in
)
#abridgement
#plotinfo = dict()
def __init__(self):
#To be exact, self.datas[0]Can be omitted
# self.params.k_omit period and self.p.k_period
highest = bt.ind.Highest(self.data, period=self.p.k_period)
lowest = bt.ind.Lowest(self.data, period=self.p.k_period)
self.lines.k = k = (self.data - lowest) / (highest - lowest)
self.lines.d = bt.ind.SMA(k, period=self.p.d_period)
class TestStrategy(bt.Strategy):
def __init__(self):
#The instance name myind1 can be any name
self.myind1 = MyStochastic1(self.data)
if __name__ == '__main__':
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy)
datapath = 'C:\\Users\\XXXX\\orcl-1995-2014.txt'
# Create a Data Feed
data = bt.feeds.YahooFinanceCSVData(
dataname=datapath,
fromdate=datetime.datetime(2000, 1, 1),
todate=datetime.datetime(2000, 12, 31),
reverse=False)
cerebro.adddata(data)
cerebro.run(stdstats=False)
cerebro.plot(style='candle')
The stochastic oscillator is displayed safely.
__ What is Cerebro? __
This is the core function of Backtrader. If you start this Cerebro after making various settings, it will automatically buy and sell, analyze and optimize, and plot the results automatically. I will review the flow up to the start of Cerebro in the previous script.
cerebro = bt. Cerebro ()
cerebro.adddata (data)
cerebro.addstrategy (TestStrategy)
cerebro.run ()
cerebro.plot ()
If you create a strategy class "TestStrategy" that you think of yourself, specify CSV data, and then execute Cerebro, the contents of this "TestStrategy" class will be executed automatically. This time we are not doing automatic trading, but since Stochastic Oscillator is used in "Test Strategy", Cerebro will plot it.
What did you think? To use a custom indicator with Backtrader, create your own class of custom indicators and instantiate it inside the strategy class.
Reference 1
Reference 2 2.Gold vs SP500 https://www.backtrader.com/blog/posts/2016-12-13-gold-vs-sp500/gold-vs-sp500/
Recommended Posts