当前位置: 首页 > article >正文

BackTrader -Indicators 03

本系列是使用Backtrader在量化领域的学习与实践,着重介绍Backtrader的使用。Backtrader 中几个核心组件:

  • Cerebro:BackTrader的基石,所有的操作都是基于Cerebro的。
  • Feed:将运行策略所需的基础数据加载到Cerebro中,一般为K线数据。
  • Indicator:BackTader自带的指标,并集成了talib中的指标。我们也可以选择继承一个Indicator实现自己的指标。
  • Strategy:交易策略。这里是整个过程中最复杂的部分,需要我们计算买入/卖出信号。
  • Analyzer:分析器,以图形和风险收益等指标对交易策略的回测结果进行分析评价。
  • Order:订单,记录了与当前订单相关的所有数据。
  • Trader:交易,记录了与当前交易相关的所有数据。
  • Position:持仓,记录了与当前持仓相关的所有数据。
  • Broker:可以理解成经纪人,整个策略的初始资金、交易费率、滑点等参数需要通过Broker进行设置。
  • Observer:观察者,对数据进行监控观察,比如资金曲线等等。
  • Plotting:可视化组件

本次介绍Backtrader中Indicators模块,Indicators模块是Backtrader核心模块之一,其提供众多技术指标,并支持talib指标的调用。

在使用Backtrader时,结合量化策略编写过程通常会考虑:

  1. 在Backtrader都有哪些指标?
  2. 怎么使用内置指标?是否可以自定义指标?
  3. 对于不同周期情况下如何处理?

Backtrader 大致有 2 种获取指标的方式:

  • 1、直接通过 DataFeeds 模块导入 已经计算好 的指标,比如 导入新增指标 PE、PB;
  • 2、在编写策略时调用 Indicators 指标模块 临时计算 指标,比如 5 日均线、布林带等 。
import backtrader as bt
import pandas as pd
import numpy as np
import datetime

daily_price = pd.read_csv("./data/daily_price.csv", parse_dates=['datetime'])

# 筛选 600466.SH 和 603228.SH 2只股票的数据集
data1 = daily_price.query(f"sec_code=='600466.SH'").set_index('datetime').drop(columns=['sec_code'])
data2 = daily_price.query(f"sec_code=='603228.SH'").set_index('datetime').drop(columns=['sec_code'])

Backtrader都有哪些指标

Indicators 指标模块提供了 140 多个技术分析指标计算函数,大部分指标与 TA-Lib 库里的指标是一致的。

参考官方网站对每个技术指标说明,包含:

  • Alias 函数别名,一般技术技术指标含有全英文名称和简称,在bt中可以使用的访问该指标名称的方式。例如:ExponentialMovingAverage,它的别名有:EMA, MovingAverageExponential,那么它的访问方式有:

    • btind.EMA();
    • btind.MovingAverageExponential();
    • btind.ExponentialMovingAverage();
  • Formula:技术指标算法说明,以EMA为例:

    • movav = prev * (1.0 - smoothfactor) + newdata * smoothfactor
  • Lines:函数返回的指标对象中包含哪些 lines,例如 ExponentialMovingAverage 返回ema。通过xxx.lines.ema 或 xxx.ema

  • Params:技术指标可以设置的参数。例如:ExponentialMovingAverage 中 period (30) 默认值为30天均值。

  • PlotInfo:绘制指标时

    • plot = True,是否显示这个指标值,True的显示,False不显示 ;
    • subplot = True,是否把指标显示到另一个窗口,True显示到另一个窗口,False显示在主图;
    • plotname = “”, 显示 line 的名称,默认是 class.name
    • plotabove = False, 指标绘制的位置,False 指标画在主图下方,True 指标画在主图上方;
    • plotlinelabels = False,False 显示的是指标函数的名称,True 显示指标线的名称;
    • plotymargin=0.0,画图的时候距离顶部和底部的距离;
    • plotyticks=[ ], y 轴刻度范围,取值为空列表时会自动计算;
    • plothlines=[ ],用于绘制水平线;
    • plotyhlines=[ ],用同一个参数,控制 plotyticks 和 plothlines 的取值;
    • plotforce=False,如果该绘制的指标没有被绘制,就将 plotforce 设置为 True 进行 强制绘图。,支持设置的图形参数。
  • PlotLines:绘制的曲线样式

如何在策略中使用指标

指标使用原则

在编制策略时,遵循“init() 负责指标计算,next() 负责指标调用”原则,即在__init__()中计算好指标,在next()中调用已经算好的指标。如此可以减少计算消耗,提升策略效率。

# 遵循“__init__() 负责指标计算,next() 负责指标调用”原则

import backtrader.indicators as btind

class TestStrategy(bt.Strategy):
    def __init__(self):
        sma1 = btind.SmoothedMovingAverage(self.data)
        ema1 = btind.ExponentialMovingAverage()
        
        close_over_sma = self.data.close > sma1
        close_over_ema = self.data.close > ema1
        sma_ema_diff = sma1 - ema1

        # 交易信号
        self.buy_signal= bt.And(close_over_sma,close_over_ema,sma_ema_diff>0)

    def next(self):
        if self.buy_signal:
            print('Buy 买入')

cerebro= bt.Cerebro()
st_date = datetime.datetime(2019,1,2)
ed_date = datetime.datetime(2021,1,28)
datafeed1 = bt.feeds.PandasData(dataname=data1,fromdate=st_date,todate=ed_date)
cerebro.adddata(datafeed1,name='600466.SH')
cerebro.addstrategy(TestStrategy)
result = cerebro.run()

指标调用形式

  1. 调用 Indicators 模块的函数计算指标时,默认是对 self.datas 数据对象中的第一张表格中的第一条line (默认第一条line是 close line)计算相关指标。

  2. 调用指标时会涉及 line 的索引和切片操作,在 next() 中调用当前时刻指标值时,可以写成:self.sma5[0] 或 self.sma5 或 self.data.close[0] 或 self.data.close。

class TestStrategy(bt.Strategy):
    def __init__(self):
        self.sma5 = btind.SimpleMovingAverage(period=5) # 5日均线
        self.sma10 = btind.SimpleMovingAverage(period=10) # 10日均线
        self.buy_sig = self.sma5 > self.sma10 # 5日均线上穿10日均线

    def next(self):
        # 提取当前时间点
        print('datetime', self.datas[0].datetime.date(0))
        # 打印当前值
        print('close', self.data.close[0], self.data.close)
        print('sma5', self.sma5[0], self.sma5)
        print('sma10', self.sma10[0], self.sma10)
        print('buy_sig', self.buy_sig[0], self.buy_sig)
        # 比较收盘价与均线的大小
        if self.data.close > self.sma5:
            print('------收盘价上穿5日均线------')
        if self.data.close[0] > self.sma10:
            print('------收盘价上穿10日均线------')
        if self.buy_sig:
            print('------ buy ------')
        
cerebro = bt.Cerebro()
st_date = datetime.datetime(2019,1,2)
end_date = datetime.datetime(2021,1,28)
datafeed1 = bt.feeds.PandasData(dataname=data1, fromdate=st_date, todate=end_date)
cerebro.adddata(datafeed1, name='600466.SH')
cerebro.addstrategy(TestStrategy)
rasult = cerebro.run()

自定义新指标

在 Backtrader 中,可以根据自身需要编写新指标,新指标的编写需要满足以下条件:

  1. 继承原始的 bt.Indicator 类: 如果涉及到自定义操作,一般都是通过继承原始的父类,然后在新的子类里自定义属性,自定义新指标,需要继承原始的 bt.Indicator 类,然后在新的子类里构建指标。
  2. lines = (‘xxx’, ‘xxx’, ‘xxx’,):定义指标函数返回的 lines 名称,方便后面通过名称调用具体的指标,如 self.lines.xxx、self.l.xxx、self.xxx
  3. params = ((‘xxx’, n),):定义参数,方便在子类里全局调用,也方便在使用指标函数时修改参数取值;
  4. init() 方法:同策略 Strategy 里的 init() 类似,对整条 line 进行运算,运算结果也以整条 line 的形式返回;
  5. next() 方法:同策略 Strategy 里的 next() 类似,每个 bar 都会运行一次,在 next() 中是对数据点进行运算;
  6. once() 方法:这个方法只运行一次,但是需要从头到尾循环计算指标;
class DummyInd(bt.Indicator):
    lines = ('dummyline',)

    params = (('value', 5),)

    def next(self):
        self.lines.dummyline[0] = max(0.0, self.params.value)

    def once(self, start, end):
        dummy_array = self.lines.dummyline.array

        for i in xrange(start, end):
            dummy_array[i] = max(0.0, self.params.value)

不同周期中指标的使用

在不同周期的指标情况下,可以使用“ ( ) ”语法操作来对齐不同周期的数据,对齐的方向是“大周期向小周期对齐”,可以选择指标对象中的某条 line 进行对齐,也可以对整个指标对象进行对齐。在使用该语法时,要将 cerebro.run() 中的 runonce 设置为 False,才能实现对齐操作。

# self.data0 是日度行情、self.data1 是月度行情
self.month = btind.xxx(self.data1) # 计算返回的 self.month 指标也是月度的

# 选择指标对象中的第一条 line 进行对齐
self.sellsignal = self.data0.close < self.month.lines[0]()

# 对齐整个指标对象
self.month_ = self.month()
self.signal = self.data0.close < self.month_.lines[0]

cerebro.run(runonce=False)

调用 TA-Lib 库

在Backtrader中使用talib与其内置指标的方式类似。

在此,以20日的SMA指标为例:

import backtrader as bt

class MyStrategy(bt.Strategy):
    params = (('period', 20),)

    def __init__(self):
        # 计算 20 日均线
        self.sma1 = bt.indicators.SMA(self.data, period=self.p.period)
        self.sma2 = bt.talib.SMA(self.data, timeperiod=self.p.period)

ta-lib 指标文档会自动解析并添加到 backtrader 文档中。您也可以查看 ta-lib 源代码/文档。

print(bt.talib.SMA.__doc__)
print(bt.talib.SMA.__doc__)
SMA([input_arrays], [timeperiod=30])

Simple Moving Average (Overlap Studies)

Inputs:
    price: (any ndarray)
Parameters:
    timeperiod: 30
Outputs:
    real

http://www.kler.cn/a/372593.html

相关文章:

  • Kotlin语言的数据结构
  • HTML `<head>` 元素详解
  • BH1750使用程序
  • 脚本工具:PYTHON
  • Data Filtering Network 论文阅读和理解
  • 解决leetcode第3426题所有安放棋子方案的曼哈顿距离
  • electron+vite+ts+vue3
  • P8775 [蓝桥杯 2022 省 A] 青蛙过河
  • CUDA环境安装终极指南——Linux(其它系统也一样)
  • 订购 Claude AI 的第二天 它独自完成 文字转语音 flask应用
  • C++ | Leetcode C++题解之第519题随机翻转矩阵
  • 轻型民用无人驾驶航空器安全操控理论培训知识总结-多旋翼部分
  • Redis 下载安装(Windows11)
  • 算法刷题基础知识总结
  • 逆变器前级倍压方案【工作日志】
  • 未来生活中的AI电脑是怎样的
  • 2023 春季测试 题解
  • 论坛系统测试报告
  • Postgresql源码(137)执行器参数传递与使用
  • 大语言模型(LLM)快速理解
  • DOM---鼠标事件类型(移入移出)
  • 基于Unet卷积神经网络的脑肿瘤MRI分割
  • LinkedList和链表(下)
  • 豆包,攻克数字是个什么工具?《GKData-挖掘数据的无限可能》(数据爬虫采集工具)
  • Ceph 存储系统全解
  • TMUX1308PWR规格书 数据手册 具有注入电流控制功能的 5V 双向 8:1单通道和 4:1 双通道多路复用器芯片