Skip to content

Latest commit

 

History

History
141 lines (91 loc) · 7.28 KB

File metadata and controls

141 lines (91 loc) · 7.28 KB

47、backtrader 的一些基本概念---技术指标(indicator)的使用教程

原文:https://yunjinqi.blog.csdn.net/article/details/115044810

最近在群里面有一些 backtrader 的使用者提到了如何使用 talib 计算均线的问题,想到还没有把 backtrader 如何使用指标做专题分享,今天就凑着这个周末,分享一下,如何在 backtrader 中使用技术指标(indicator)。

开始之前,再分享一下老生长谈的问题:backtrader 的 line 数据结构


Excel 表格与 backtrader 的 lines

backtrader 中大部分都是 line 结构,如果使用过 excel 的工作表,就特别容易理解 line 结构,也可以理解大部分的事件驱动的量化框架。

excel 中的工作表分不同的工作簿,一个工作簿中分为行和列;backtrader 中的类相当于一个工作簿,类里面包含的数据相当于一列一列的列表,每一个 line 就相当于一列数据。调取数据也和 excel 差不多,先找到是在哪个工作簿,然后找到是哪一列,然后找到是哪一行;区别在于 backtrader 找哪一行的时候是按照当前的 index 来找的,index=0,找到的是当前行的;index=-1,找到的是前一行的;index=1,找到的是下一行的。

不知道用 excel 的表格来讲 backtrader 的 line 是否够形象和易于理解,理解 backtrader 的 line 的数据结构是对 backtrader 进行深入了解的基础。


如何使用 backtrader 的技术指标

使用 backtrader 的技术指标,回测的使用,一般是在 strategy 类中的 init 中进行声明,然后在进入 next 之前,一般就已经把指标计算好了。

关于 backtrader 可以调用的技术指标,分为三种,一种是talib 上的技术指标,一种是backtrader 自带的技术指标,一种是自己创建的新的技术指标。使用具体指标的时候,尤其是 talib 的指标的时候,要认真检验一下,看是否和我们想要的结果一样,因为 talib 的代码一般比较难找到源码;我碰到过 talib 计算的和 backtrader 计算的指标不一致的情况。

  • 使用方法

    首先,想明白自己想要使用的指标是什么,需要哪些参数,可以在 talib 和 backtrader 自带的指标里面找,更进一步的话,也可以自己创建指标;

    其次,一般是在 strategy 类中的 init 中使用 self.xxx = bt.indicators.yyy(params)或者 self.xxx = bt.talib.yyy(params),如果遇到多个数据需要计算指标,一般是使用 dict 格式,key 是数据名称,value 是计算的指标值。

    最后,在 next 中调用指标值的时候,和普通的高开低收的行情数据没有差别。

  • 举例说明:

    参考文章:如何用 backtrader 实现双均线策略?以工商银行为例

    self.short_ma = bt.indicators.SMA(self.datas[0].close,period=self.p.short_window) 
    
    self.long_ma = bt.indicators.SMA(self.datas[0].close,period=self.p.long_window) 

    参考文章:【backtrader 股票策略】《151 trading strategies》中的三均线策略在 A 股中的测试

class xxx(bt.Strategy):
    params = (('short_period',10),
              ("middle_period",60),
              ("long_period",250),
             )

    def __init__(self):
        # 在这里面声明需要计算的公式
        self.bar_num=0
        # 保存均线数据
        self.stock_short_ma_dict={data._name:bt.talib.SMA(data.close,timeperiod=self.p.short_period) for data in self.datas}
        self.stock_middle_ma_dict={data._name:bt.talib.SMA(data.close,timeperiod=self.p.middle_period) for data in self.datas}
        self.stock_long_ma_dict={data._name:bt.talib.SMA(data.close,timeperiod=self.p.long_period) for data in self.datas}

    def prenext(self):

        self.next()

    def next(self):
        # 省略很多代码之后
        for data in self.datas:
            # 三条均线,保存成 line 的数据结构
            short_ma_info = self.stock_short_ma_dict[data._name]
            middle_ma_info = self.stock_middle_ma_dict[data._name]
            long_ma_info = self.stock_long_ma_dict[data._name]
            # 今日向上的条件
            up = short_ma_info[0]>middle_ma_info[0] and middle_ma_info[0]>long_ma_info[0]
            # 今日向下的条件
            down = short_ma_info[0]<=middle_ma_info[0]
            # 昨日向上的条件
            pre_up = short_ma_info[-1]>middle_ma_info[-1] and middle_ma_info[-1]>long_ma_info[-1]
            # 昨日向下的条件
            pre_down = short_ma_info[-1]<=middle_ma_info[-1] 

init 中计算指标的优势

  1. 有一部分指标可以使用向量的方式计算,加快速度
  2. 把需要计算的变量计算好,可以在 next 中集中精力实现策略逻辑

如何画出来具体的指标

直接使用 indicator 计算的变量,如果使用了 cerebro.plot()的话,是可以直接画出来的,如果是使用了中间变量,那么中间变量并不会直接画出来,需要我们声明。

举例说明,这个策略是来自官网上面

class MyStrategy(bt.Strategy):

    def __init__(self):

        sma1 = btind.SimpleMovingAverage(self.data)
        ema1 = btind.ExponentialMovingAverage()

        close_over_sma = self.data.close > sma1
        close_over_ema = self.data.close > ema1
        sma_ema_diff = sma1 - ema1

        buy_sig = bt.And(close_over_sma, close_over_ema, sma_ema_diff > 0)

    def next(self):

        if buy_sig:
            self.buy() 

在这个策略中,sma1 和 ema1 是可以直接画出来的,但是 close_over_sma 和 close_over_ema 和 sma_ema_diff 是不会直接画出来的,需要我们使用 LinePlotterIndicator 画出来中间变量。

close_over_sma = self.data.close > self.sma
LinePlotterIndicator(close_over_sma, name='Close_over_SMA') 

如果想要控制指标的位置和名称,可以在创建指标的时候,使用参数额外控制,如:

self.short_ma = bt.indicators.SMA(self.datas[0].close,period=self.p.short_window,subplot=True,plotname="short_ma") 

其中,subplot 是控制显示的位置,是在 K 线图上显示(subplot=False)还是另外一幅图上显示(subplot=True),plotname 是画出来的名称.测试了一下,没问题。

在下一讲中,将会分享一下,如何创建新的技术指标以及画图的各个参数的意义。


智慧、心灵、财富,总要有一个在路上,愿我们能在人生的道路上,不断成长、不断成熟~~~

感兴趣可以关注我的专栏:

my_quant_study_note:分享一些关于量化投资、量化交易相关的思考

backtrader 量化投资回测与交易:本专栏免费,分享 backtrader 相关的内容。

量化投资神器-backtrader 源码解析-从入门到精通:本专栏目前收费 99 元,预计更新 100 篇策略+20 篇 backtrader 讲解+80 篇源代码分析。