An article on quantitative framework backtrader to understand visualization

Introduction

When backtesting, we often want to know the operation of the strategy. Although we can get a glimpse of it through the final statistical indicators, it is most humane to visualize the backtesting process. At the same time, we can also design better by observing the backtesting process& Optimize quantitative strategies. Backtrader uses the matplotlib library to provide visualization capabilities

Instructions

Backtrader data visualization is very simple, just call the plot() method after run().

cerebro.run()
cerebro.plot()

plot(self, plotter=None, numfigs=1, iplot=True, **kwargs)The meaning of each parameter of the method is as follows:

  • plotter: PlotScheme and its derived class objects containing plotting properties. The default is None. If it is None, the default PlotScheme object will be instantiated.

  • numfigs: Split the graph into multiple images for display, the default is 1

  • iplot: Whether to automatically plot inline when running in Jupyter Notebook, the default is True. If you are not running in jupyter, it is best to set this parameter to False, otherwise problems may occur.

  • *kwargs:args parameter is used to change the plotter attribute value

There are two ways to systematically control the visualization configuration:

  1. Directly by setting the args parameter of the plot() method, as shown below.

cerebro.plot(iplot=False,
             style='candel',  # 设置主图行情数据的样式为蜡烛图
             plotdist=0.1,    # 设置图形之间的间距
             barup = '#ff9896', bardown='#98df8a', # 设置蜡烛图上涨和下跌的颜色
             volup='#ff9896', voldown='#98df8a', # 设置成交量在行情上涨和下跌情况下的颜色
            )

2. Customize the PlotScheme class to modify the corresponding parameters

The PlotScheme object includes all system-level plotting options, as shown below.

class PlotScheme(object):
    def __init__(self):
        # to have a tight packing on the chart wether only the x axis or also
        # the y axis have (see matplotlib)
        self.ytight = False

        # y-margin (top/bottom) for the subcharts. This will not overrule the
        # option plotinfo.plotymargin
        self.yadjust = 0.0
        # Each new line is in z-order below the previous one. change it False
        # to have lines paint above the previous line
        self.zdown = True
        # Rotation of the date labes on the x axis
        self.tickrotation = 15

        # How many "subparts" takes a major chart (datas) in the overall chart
        # This is proportional to the total number of subcharts
        self.rowsmajor = 5

        # How many "subparts" takes a minor chart (indicators/observers) in the
        # overall chart. This is proportional to the total number of subcharts
        # Together with rowsmajor, this defines a proportion ratio betwen data
        # charts and indicators/observers charts
        self.rowsminor = 1

        # Distance in between subcharts
        self.plotdist = 0.0

        # Have a grid in the background of all charts
        self.grid = True

        # Default plotstyle for the OHLC bars which (line -> line on close)
        # Other options: 'bar' and 'candle'
        self.style = 'line'

        # Default color for the 'line on close' plot
        self.loc = 'black'
        # Default color for a bullish bar/candle (0.75 -> intensity of gray)
        self.barup = '0.75'
        # Default color for a bearish bar/candle
        self.bardown = 'red'
        # Level of transparency to apply to bars/cancles (NOT USED)
        self.bartrans = 1.0

        # Wether the candlesticks have to be filled or be transparent
        self.barupfill = True
        self.bardownfill = True

        # Wether the candlesticks have to be filled or be transparent
        self.fillalpha = 0.20

        # Wether to plot volume or not. Note: if the data in question has no
        # volume values, volume plotting will be skipped even if this is True
        self.volume = True

        # Wether to overlay the volume on the data or use a separate subchart
        self.voloverlay = True
        # Scaling of the volume to the data when plotting as overlay
        self.volscaling = 0.33
        # Pushing overlay volume up for better visibiliy. Experimentation
        # needed if the volume and data overlap too much
        self.volpushup = 0.00

        # Default colour for the volume of a bullish day
        self.volup = '#aaaaaa'  # 0.66 of gray
        # Default colour for the volume of a bearish day
        self.voldown = '#cc6073'  # (204, 96, 115)
        # Transparency to apply to the volume when overlaying
        self.voltrans = 0.50

        # Transparency for text labels (NOT USED CURRENTLY)
        self.subtxttrans = 0.66
        # Default font text size for labels on the chart
        self.subtxtsize = 9

        # Transparency for the legend (NOT USED CURRENTLY)
        self.legendtrans = 0.25
        # Wether indicators have a leged displaey in their charts
        self.legendind = True
        # Location of the legend for indicators (see matplotlib)
        self.legendindloc = 'upper left'

        # Plot the last value of a line after the Object name
        self.linevalues = True

        # Plot a tag at the end of each line with the last value
        self.valuetags = True

        # Default color for horizontal lines (see plotinfo.plothlines)
        self.hlinescolor = '0.66'  # shade of gray
        # Default style for horizontal lines
        self.hlinesstyle = '--'
        # Default width for horizontal lines
        self.hlineswidth = 1.0

        # Default color scheme: Tableau 10
        self.lcolors = tableau10

        # strftime Format string for the display of ticks on the x axis
        self.fmt_x_ticks = None

        # strftime Format string for the display of data points values
        self.fmt_x_data = None

The PlotScheme class defines a color(self, idx)method that returns the color to be used. Subclasses can overload it, and its idx parameter is the current index of the line to be drawn. For example, MACD draws three lines, and the idx variable has three values: 0, 1, and 2. The new indicator idx will restart from 0. The default color scheme is Tableau 10 Color Palette, and the corresponding index is tab10_index = [3, 0, 2, 1, 2, 4, 5, 6, 7, 8, 9]. The colors to be used can be changed by overriding the color() method in a custom PlotScheme class or by passing the lcolors variable to the plot method.

def color(self, idx):
        colidx = tab10_index[idx % len(tab10_index)]
        return self.lcolors[colidx]

Visual components

Backtrader supports visualization of 3 major components:

  • Data feeds data source: import cerebro's original data through the adddata, replaydata and resampledata methods

  • Indicators : indicators declared in the strategy class or added through addindicator

  • Observers observer objects: observers added through addobserver, such as Cash and Value objects

When drawing graphics, the default is to draw the data feeds on the main chart. Some indicators are drawn on the main chart together with the data feeds, such as moving averages, and some are drawn in the form of subgraphs; observers are usually drawn on on sub-picture

Visualization options

In addition to the above-mentioned system control of visualization options through plot() parameters and custom PlotScheme, Indicators and Observers have some options to control their drawing forms. There are 3 types in total :

  • Object object-level visualization options—can affect the drawing behavior of the entire object, controlled by plotinfo

plotinfo = dict(plot=True, # 是否绘制
                subplot=True, # 是否绘制成子图
                plotname='', # 图形名称
                plotabove=False, # 子图是否绘制在主图的上方
                plotlinelabels=False, # 主图上曲线的名称
                plotlinevalues=True,
                plotvaluetags=True,
                plotymargin=0.0,
                plotyhlines=[],
                plotyticks=[],
                plothlines=[],
                plotforce=False,
                plotmaster=None,
                plotylimited=True,
           )

There are 2 ways to access plotinfo's properties as follows:

# 通过参数来设置
sma = bt.indicators.SimpleMovingAverage(self.data, period=15, plotname='mysma')

# 通过属性来设置
sma = bt.indicators.SimpleMovingAverage(self.data, period=15)
sma.plotinfo.plotname = 'mysma'
  • Line related visualization options - You can use the plotlines object to control the drawing behavior of the lines object. The options in plotlines will be directly passed to matplotlib when drawing, as shown below.

lines = ('histo',)
plotlines = dict(histo=dict(_method='bar', alpha=0.50, width=1.0))
  • Method-controlled visualization — When dealing with indicator indicators and observers, the _plotlabel(self), _plotinit(self) methods allow further control of the visualization

Conclusion & Communication

Follow the WeChat public account: Zhuge Shuo Talk for more content. At the same time, you can also get invitations to join the quantitative investment group, communicate and discuss with many investment enthusiasts, quantitative practitioners, and technology experts, and quickly improve your investment level in actual combat.

Writing articles is not easy. If you think this article is helpful to you, please click and read it.

reference

Guess you like

Origin blog.csdn.net/richardzhutalk/article/details/125697148