楼主: tianjixuetu
1299 0

[交易平台及行情软件] 【答读者问12】如何理解backtrader的line以及对line进行操作? [推广有奖]

教授

53%

还不是VIP/贵宾

-

TA的文库  其他...

投资理财书籍

威望
0
论坛币
9911 个
通用积分
38.0729
学术水平
67 点
热心指数
67 点
信用等级
61 点
经验
1211 点
帖子
714
精华
3
在线时间
1562 小时
注册时间
2009-12-16
最后登录
2024-4-25

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

理解line是理解backtrader的基础,backtrader是一个事件驱动的量化框架,基于元编程技术,形成了line的数据结果;在前面的文章中如何使用技术指标中,已经讲过如何理解line这种backtrader的数据结构了,但是可能还是有一部分读者对这个数据结构不太了解。

backtrader和excel表格的关系

事件驱动的核心本质是一样的,都是基于事件(数据)的更新,不断更新相关的量。backtrader本身的底层结构看起来比较抽象,但是,如果我们把backtrader和excel表格对比,对于backtrader的认识,就会瞬间提高很多。

  • backtrader的datas相当于一个文件名是datas的excel表格,每个data就相当于一个工作簿,data中的open、high、low、close等line就相当于工作簿的一个个列

  • strategy中的next每次运行相当于指向了excel表格中的下一行,用下一行代表当前行;举例说明,如果当前行是2021年6月14日,此时,data.close[0]是数据2021年6月14日的,此时,excel表格中相当于以2021年6月14日所在的行作为当前行;然后next运行一次,下个数据的日期是2021年6月15日,那么,data.close[0]就指向了2021年6月15日的bar的收盘价,excel中,当前行的index会增加1,以2021年6月15日作为当前行。


这样理解之后,会不会对backtrader的line的数据结构理解的更清晰?

backtrader的line数据结构的相关操作如何获取line的一个值
  • 0获取的是当前的值,如close[0]是当前bar的收盘价

  • -1获取的是前一个bar的值,如close[-1]是前一个bar的收盘价

  • 1获取的是后一个bar的值,如close[1]获取的是下一个bar的收盘价,如果是最后一个bar,就会报IndexError的错误,如果使用这个,就要避免报错导致的程序中断,另外,下个bar的信息是未来数据,要慎用;在实盘的时候,是不存在下个bar的数据的,仅仅只能用于回测之中。


如何获取line的多个值
  • line是一个特殊的数据结构,获取line的多个值,和python的切片有所不同。举例说明,要想获取line里面的最近的10个值,需要使用line[-9:0],line[0]也在切片的数据中;python中line[-9:]是获取的最后的9个数值,和backtrader不一样。

  • backtrader定义了一个get的函数,用于获取过去的值,close.get(ago=0,size=10),代表获取从当前值开始的最近的10个收盘价;close.get(ago=-1,size=20)代表获取从前一个bar开始的20个收盘价。


如何获取一个line的长度

有两种不同的line的长度,一种是len,这个是backtrader已经处理过的数据的长度;一种是buflen(),这个是backtrader预先加载的数据的长度。

  • len(line):计算出backtrader已经处理(运行)的长度,如prenext,next等运行的长度

  • line.buflen()计算的是backtrader加载的line的总的数目

  • 一般情况下,是buflen大于len,如果两者想等了,可能是这个bar是最后一个bar;也有可能是某些情况下的实盘交易造成的。


line之间如何进行逻辑操作

backtrader自己集成了一些常见的操作

  • bt.And(a,b):a和b都是真的时候,才返回真值,值也是line

  • bt.Or(a,b):a和b一个是真的时候,就返回真值,值也是line

  • bt.If(cond,a,b):如果cond成立,返回a,否则,返回b,值是line

  • bt.Any、bt.All、bt.Cmp、bt.Max、bt.Min、bt.Sum和python中的any、all、cmp、max、min、sum类似

  • 这些改写的函数,可以对line进行的操作,是向量形式的操作,返回的新的结果也是line

    并且可以自己定义相应的操作方法,比如想要对一个line取绝对值,除了可以直接用abs(line)之外,还可以继承Logic,自己实现相应的类,如

    """
    # 需要把这个类放到backtrader中的functions文件中
    class Abs(Logic):

        def __init__(self, a):
            super(Abs, self).__init__(a)
            self.a = self.args[0]

        def next(self):
            self[0] = abs(self.a[0])
        def once(self, start, end):
            # cache python dictionary lookups
            dst = self.array
            srca = self.a.array
            
            for i in range(start, end):
                dst = abs(srca)
    """
    import pandas as pd
    import numpy as np
    import backtrader as bt
    import datetime

    class SmaStrategy(bt.Strategy):
       
        def log(self, txt, dt=None):
            ''' log信息的功能'''
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))

        def __init__(self):
            # 一般用于计算指标或者预先加载数据,定义变量使用
            self.bar_num = 0
            self.diff_price = bt.Abs(self.datas[0].close - self.datas[0].open)
            

        def next(self):
            self.log(f"len:{len(self.datas[0].close)},buflen:{self.datas[0].close.buflen()}")
            self.log(self.diff_price[0])
            
                           
    # 添加cerebro
    cerebro = bt.Cerebro()
    # 添加策略
    cerebro.addstrategy(SmaStrategy)
    # 准备数据        
    params = dict(
                    fromdate = datetime.datetime(2005,1,4),
                    todate = datetime.datetime(2020,8,3),
                    timeframe = bt.TimeFrame.Days,
                    compression = 1,
                    #dtformat=('%Y-%m-%d %H:%M:%S'),
                    # tmformat=('%H:%M:%S'),
                    datetime=0,
                    high=2,
                    low=3,
                    open=1,
                    close=4,
                    volume=5,
                    openinterest=6)
    # 数据的地址,使用自己的数据地址
    data_path = '/home/yun/data/stock/index.csv'
    df = pd.read_csv(data_path,encoding='gbk')
    df.columns = ['datetime','open','high','low','close','volume','openinterest']
    df['datetime']=pd.to_datetime(df['datetime'])
    df = df.sort_values("datetime")
    df.index=pd.to_datetime(df['datetime'])
    df=df[['open','high','low','close','volume','openinterest']]
    feed =  bt.feeds.PandasDirectData(dataname=df,**params)
    # 添加合约数据
    cerebro.adddata(feed, name = "index")
    cerebro.broker.setcommission(commission=0.0005)

    # 添加资金
    cerebro.broker.setcash(100000.0)

    # 开始运行
    cerebro.run()

    # 打印相关信息
    cerebro.plot()

写作这篇文章,使用两个晚上,共用89分钟。

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

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

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

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

量化投资神器-backtrader源码解析-从入门到精通:本专栏目前收费299元,预计更新100篇策略(更新中)+36篇backtrader讲解(已完成)+backtrader源码分析。
————————————————
版权声明:本文为CSDN博主「云金杞」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_26948675/article/details/117934404


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:trader Trade line 如何理解 Back

已有 1 人评分经验 收起 理由
wwqqer + 100 精彩帖子

总评分: 经验 + 100   查看全部评分

今天,我持续不断地改进自己,在各方面,我会越来越好!
您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jr
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-26 19:20