《BackTrader量化交易图解》第10章:Trade 交易操作

文章目录

  • 10 Trade 交易操作
    • 10.1 量化回测分析流程
    • 10.2 Cerebro 类模块
    • 10.3 案例:Trade 交易
    • 10.4 实盘交易机器隐性规则
    • 10.5 Stake 交易数额和 Trade 交易执行价格

10 Trade 交易操作

10.1 量化回测分析流程

从本章开始讲解 BackTrader 的实盘操作。前面的章节讲过,一个完整的量化回测分析/交易流程可以分为四个步骤:

  1. 设置一个回测主函数;
  2. 设置量化回测参数;
  3. 调用量化回测程序,开始 run 运行量化回测分析;
  4. 回测数据分析,或者根据回测推荐结果进行交易。

其中第二步的量化回测参数的设置相对比较复杂,包括设置数据源、起始资金、回测数据、读取数据、添加数据,以及进行数据清洗等于处理工作。然后,添加策略和与策略相关的变量参数、策略分析参数。

第三步的调用量化回测程序和第一步的设置回测主函数类似,都很简单,通常都只有一行代码。

所有的量化策略在进行回测数据分析时, 最重要的指标就是ROI投资回报率。 在实盘操作查看收益图时, 大家最关心的也是ROI投资回报率。ROI指标重点在于检验策略模型的盈利性, 如果ROI投资回报率为负数, 或者低于市场的平均水平, 那么该策略模型后续就不要再使用了, 说明其稳定性和盈利性非常差。

10.2 Cerebro 类模块

cerebro在西班牙语中是“大脑”的意思, 所以变量cerebro是BackTrader量化分析程序的全局主变量, 表示量化引擎源自BackTrader
的Cerebro模块库。Cerebro类的关系属性图如下:

btr_cerebro

10.3 案例:Trade 交易

本实例代码 :Cerebro.py 。

本案例的主流程部分代码如下:

print("\n#1,设置 BT 量化回测程序入口")
cerebro = bt.Cerebro()  # create a "Cerebro" engine instanceprint("\n#2,设置BT回测初始参数及策略")
print("\n\t#2-1,设置BT回测初始参数:起始资金等")
dmoney0 = 100000.0
cerebro.broker.setcash(dmoney0)
dcash0 = cerebro.broker.startingcashprint("\n\t#2-2,设置数据文件,需要按时间字段正序排序")
rs0 = os.path.abspath(os.path.dirname(__file__)) + "/../data/"
filename = "002046.SZ.csv"
fdat = rs0 + filename
print("\t@数据文件名:", fdat)print("\t 设置数据BT回测运算:起始时间、结束时间")
print("\t 数据文件,可以是股票期货、外汇黄金、数字货币等交易数据")
print("\t 格式为:标准OHLC格式,可以是日线、分时数据")t0stx, t9stx = datetime(2020, 1, 1), datetime(2021, 12, 31)
data = bt.feeds.YahooFinanceCSVData(dataname=fdat, fromdate=t0stx, todate=t9stx)cerebro.adddata(data)  # Add the data feedprint("\n\t#2-3,添加BT量化回测程序,对应的策略参数")
print("\n\t# 案例当中,使用的是MA均线策略")
cerebro.addstrategy(MyStrategy)print("\n\t#2-4,添加broker经纪人佣金,默认为:千一")
cerebro.broker.setcommission(commission=0.001)print("\n\t#2-5,设置每手交易数目为:10,不再使用默认值:1手")
cerebro.addsizer(bt.sizers.FixedSize, stake=10)print("\n\t#2-6,设置addanalyzer分析参数")
cerebro.addanalyzer(SQN)
#
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name="SharpeRatio", legacyannual=True)
cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name="AnnualReturn")
#
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="TradeAnalyzer")
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="DW")
#
# 周期回报率,不同时间周期
cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Years, _name="timReturns"
)
# cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Months,_name='timReturns')
#
# 动态加权回报率 Variability-Weighted Return: Better SharpeRatio with Log Returns
cerebro.addanalyzer(bt.analyzers.VWR, _name="VWR")print("\n#3,调用BT回测入口程序,开始执行run量化回测运算")
results = cerebro.run()print("\n#4,完成BT量化回测运算")
dval9 = cerebro.broker.getvalue()
dget = dval9 - dcash0
kret = (dval9 - dcash0) / dcash0 * 100print("\t 起始资金Starting Portfolio Value:%.2f" % dcash0)
print("\t 资产总值Final Portfolio Value:%.2f" % dval9)
print("\t 利润总额:  %.2f," % dget)
print("\t ROI投资回报率Return on investment: %.2f %%" % kret)# ---------
print("\n#5,analyzer分析BT量化回测数据")
strat = results[0]
anzs = strat.analyzers
#
dsharp = anzs.SharpeRatio.get_analysis()["sharperatio"]
#
dw = anzs.DW.get_analysis()
max_drowdown_len = dw["max"]["len"]
max_drowdown = dw["max"]["drawdown"]
max_drowdown_money = dw["max"]["moneydown"]
#
print("\t5-1夏普指数SharpeRatio : ", dsharp)
print("\t最大回撤周期 max_drowdown_len : ", max_drowdown_len)
print("\t最大回撤 max_drowdown : ", max_drowdown)
print("\t最大回撤(资金)max_drowdown_money : ", max_drowdown_money)
#
print("\t#5-2,常用量化分析数据")
print("\tSQN指数、AnnualReturn年化收益率,Trade交易分析报告")
print("\t可以通过修改参数,改为其他时间周期:周、月、季度等")
for alyzer in strat.analyzers:alyzer.print()
# ----------
print("\n#6,绘制BT量化分析图形")
cerebro.plot(style="candle")

案例输出中有收盘价,还有买卖执行等信息:

2021-08-17, 当前收盘价Close, 9.72
2021-08-18, 买单执行BUY EXECUTED,成交价: 9.57,小计 Cost: 95.70,佣金 Comm 0.10
2021-08-18, 当前收盘价Close, 10.02
2021-08-19, 卖单执行SELL EXECUTED,成交价: 10.08,小计 Cost: 95.70,佣金 Comm 0.10
2021-08-19, 交易操盘利润OPERATION PROFIT, 毛利GROSS 5.10, 净利NET 4.90

本案例是一个完整的量化分析流程, 使用了一个完整的量化交易策略——MA均线策略。
第一步设置一个回测主函数, 代码如下:

print("\n#1,设置 BT 量化回测程序入口")
cerebro = bt.Cerebro()  # create a "Cerebro" engine instance

第二步设置参数, 包括数据源、 起始资金的设置, 然后读取数据、添加数据, 代码如下:

print("\n#2,设置BT回测初始参数及策略")
print("\n\t#2-1,设置BT回测初始参数:起始资金等")
dmoney0 = 100000.0
cerebro.broker.setcash(dmoney0)
dcash0 = cerebro.broker.startingcashprint("\n\t#2-2,设置数据文件,需要按时间字段正序排序")
rs0 = os.path.abspath(os.path.dirname(__file__)) + "/../data/"
filename = "002046.SZ.csv"
fdat = rs0 + filename
print("\t@数据文件名:", fdat)print("\t 设置数据BT回测运算:起始时间、结束时间")
print("\t 数据文件,可以是股票期货、外汇黄金、数字货币等交易数据")
print("\t 格式为:标准OHLC格式,可以是日线、分时数据")t0stx, t9stx = datetime(2020, 1, 1), datetime(2021, 12, 31)
data = bt.feeds.YahooFinanceCSVData(dataname=fdat, fromdate=t0stx, todate=t9stx)cerebro.adddata(data)  # Add the data feed

在设置完量化分析数据源等基础数据后, 添加策略和与策略相关的变量参数。

MyStrategy 类是量化回测策略,需要完成 nextnotify_ordernotify_tradestop 等函数。使用如下代码设置策略:

print("\n\t#2-3,添加BT量化回测程序,对应的策略参数")
print("\n\t# 案例当中,使用的是MA均线策略")
cerebro.addstrategy(MyStrategy)

在设置完量化回测策略后, 还需要设置交易佣金参数, 默认费用为千分之一, 交易数额默认是1手, 但本书案例中的交易数额设置为10手:

print("\n\t#2-4,添加broker经纪人佣金,默认为:千一")
cerebro.broker.setcommission(commission=0.001)print("\n\t#2-5,设置每手交易数目为:10,不再使用默认值:1手")
cerebro.addsizer(bt.sizers.FixedSize, stake=10)

然后设置常用的分析参数, 如SQN指数、 Sharp指数、 回报率、MaxDown、 交易数据等, 代码如下:

print("\n\t#2-6,设置addanalyzer分析参数")
cerebro.addanalyzer(SQN)
#
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name="SharpeRatio", legacyannual=True)
cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name="AnnualReturn")
#
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="TradeAnalyzer")
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="DW")
#
# 周期回报率,不同时间周期
cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Years, _name="timReturns"
)
# cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Months,_name='timReturns')
#
# 动态加权回报率 Variability-Weighted Return: Better SharpeRatio with Log Returns
cerebro.addanalyzer(bt.analyzers.VWR, _name="VWR")

然后调用回测程序,开始运行回测分析:

print("\n#3,调用BT回测入口程序,开始执行run量化回测运算")
results = cerebro.run()

运行完成后,进行回测结果分析,包括回执量化分析表。

10.4 实盘交易机器隐性规则

大家对于BackTrader的使用属于准实盘交易阶段, 准实盘交易和实盘交易最主要的差别在于以下两个方面:

  • 数据源的实时更新。
  • 操作资金的实际投入

如果做实盘交易, 必须使用每天的最新数据。

BackTrader 在原生版本中对股票池的支持有限。为了提升对股票池的回测能力,可以在BackTrader的基础上增加一个外部循环来遍历整个股票池。实盘操作中,一些资金雄厚的金融团队采用全市场模式,即将市场中所有可交易的股票作为股票池。此模式没有预设的股票池限制,所有交易股票都作为输入数据。进一步地,可以在全市场模式基础上进行二次筛选,类似于单因子分析,比如与前几天的收益进行比较。

在量化交易实盘操作中,还存在一些隐性规则需要注意:

  1. 策略测试与参数优化:使用的交易策略应经过充分测试并优化参数。例如,尽管MA均线策略可能默认设定为15天周期,但这并不意味着它是最优的选择。实际操作中需对这些参数进行调整以寻找最佳方案。

  2. 缩短回测周期:为了提高回测分析的速度和效率,可以考虑缩短回测周期。这有助于更快地评估策略的有效性和适应性。

  3. 注意仓位检查:在实施策略时,应持续关注仓位(Position)的变化。仓位管理是量化交易中的关键部分,需要精确控制以避免潜在的风险。

这些考虑因素有助于提高量化交易策略的实际应用效率和成功率。

Position 子模块关系属性示意图如下:

btr_pos

主要相关的子模块库有LineBuffer、 Order、Sizer、 Trade等。使用BackTrader的position类函数还可以看到买入时的价格,随时根据平均仓位成本进行操作。

下面再看看案例策略源码, position函数主要用于next函数:

def next(self):# 检查当前股票的仓位positionif not self.position:## 如果该股票仓位为0 ,可以进行BUY买入操作,......else:# 如果该股票仓位>0 ,可以进行SELL卖出操作,......

在使用BackTrader进行量化交易时,执行买卖操作前需先确认持仓状态(Position)。这样做确保了只在持有股票时才能进行卖出操作,从而提高回测效率。策略逻辑主要在next()函数执行,而数据源和指标参数在init()中设置。

BackTrader默认不支持空头交易,用户必须拥有股票才能卖出。Position函数用于检查持仓状态,确保在持有股票时才执行卖单操作,而买单则无此限制。用户可以灵活设置Position,如设定持仓量或资金阈值以控制卖出,或依据现金比例购买股票。这种灵活性使BackTrader适应多样化的交易策略和风险管理需求。

10.5 Stake 交易数额和 Trade 交易执行价格

每次的交易数额都可以通过参数进行设置。在主流程中, 可以设置每次交易是10手:

print("\n\t#2-5,设置每手交易数目为:10,不再使用默认值:1手")
cerebro.addsizer(bt.sizers.FixedSize, stake=10)

使用固定交易数额的方法在操作上更加直接和简便。对于初学者来说,在设置持仓(Position)和交易数量(Stake)时,推荐采用简单的设置方法,避免过于复杂的操作。

接下来考虑交易执行价格的设置。BackTrader在设定买卖单时,默认会根据当天的收盘价来确定交易价格。市场上的交易价格一旦达到这个设定值,系统就会执行买卖操作。值得注意的是,这个价格并非固定不变,而是有一定的浮动范围,这个范围也是可以设定的。

所有买卖操作都由系统在后台自动完成。用户只需设置交易指令,一旦买入和卖出的价格达到一致,订单就会自动进入交易队列。订单的成交遵循“先到先得”的原则。买单和卖单操作比较复杂, BackTrader采用了一个独立的子模块BuySell来进行操作, 如图11-7所示是BuySell子模块关系属性示意图如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在订单执行时, 系统会输出成交价格、 佣金数额等信息。再看看案例输出信息, 以及图表的买卖点图标信息:

2021-09-29, 设置买单 BUY CREATE, 12.50, name : 002046.SZ
2021-09-30, 买单执行BUY EXECUTED,成交价: 11.84,小计 Cost: 118.40,佣金 Comm 0.12

Analyzer2

代码仓库链接:CPythoner/BackTraderDemo at develop (github.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/343368.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SwiftUI 为任意视图加上徽章(Badge)而想到的(下)

概览 在 SwiftUI 为任意视图加上徽章(Badge)而想到的(上) 这篇文章中,我们讨论了如何使用 Preference 技术打造 SwiftUI 中任意视图上徽章的实现。 虽然,我们完成了一系列挑战最后基本得偿所愿,不过在上篇的实现中仍有些许不尽如人意之处。 在本篇博文中,您将学到如下…

java流程控制-给个一件三连呗!✨✨✨✨✨

接下来我们来看流程控制方面的知识 文章目录 1.Scanner类的使用1.1 使用next()进行接收1.2 nextLine()1.3 hasNext()1.4 scanner.nextInt() 2.选择结构2.1 if...else....语句2.2 if....else if....else...语句2.3 switch() case...语句 3.循环结构3.1for 循环:3.2w…

浅谈装配中的螺栓拧紧力矩——SunTorque智能扭矩系统

装配中的螺栓拧紧力矩是确保机械设备稳定运行的重要因素之一。在装配过程中,通过对螺栓拧紧力矩的合理控制,可以有效地提高螺栓连接的可靠性和耐久性,减少设备故障的发生。SunTorque智能扭矩系统从螺栓拧紧力矩的基本概念、影响因素以及如何选…

C桑(Cython)从入门到入土(2): np数组操作对比

C桑(Cython)从入门到入土 2. np数组操作对比 Node sc518 Copy has image data of type unsigned long long实际上, 👆🏻这个错误是我探索Cython的缘起… code1: Form: 更现代的方法是使用内存视图而不是指针: cdef np.uint32_t[:,:,::1] …

mysql基础操作

1.基础操作 1.1 启动服务 a.手动启动 我的电脑->右键->管理->服务->mysql->右键启动/启动 b.命令方式 在管理员模式下运行cmd,执行如下操作: net start mysql --启动服务 net stop mysql --关闭服务1.2 命令连接数据库(客户端连接数据…

STL之vector

目录 vector的定义和特性 vector的定义和结构非常简单,它由以下几个重要的部分组成: vector的常用函数 vector排序去重 排序 去重 代码示例 vector的定义和特性 在c中,vector是一个动态数组容器,可以存储一系列相同类型的…

深度解析:接口测试与功能测试的区别,精彩回答震撼心灵

软件测试的细分领域范围广泛。 很多人常常搞不清楚接口测试与功能测试之间的区别。 今天用一篇文章来讲清楚“接口测试与功能测试的区别及内存联系”。 接口测试和功能测试都属于软件测试的细分领域。 更准确的说,软件测试按大的方向分类分别为:功能…

如何用Mac工具制作“苹果高管形象照”

大伙儿最近有没有刷到“苹果高管形象照”风格,详细说来就是: 以苹果官网管理层简介页面中,各位高管形象照为模型,佐以磨皮、美白、高光等修图术,打造的看上去既有事业又有时间有氧的证件照,又称“苹…

对运放设计静态工作电压和求摆幅的理解

MOS的电压关系 在运放设计静态工作电压时要利用vod来确定,已知MOS的VTH,工作在饱和区,再假设管子的Vdsat,根据下式就能由G求S或由S求G: 上述关系可以用来确定电路的所有电压工作点,因为一旦Vod确定&#…

flask框架基本使用

一、使用pycharm创建项目 1.创建项目 2.调整默认终端 3.打开虚拟终端 打开终端可以看出使用的是p1的虚拟机终端了 4.pyCharm小技巧 在flask种输入一个完整并且存在的函数名称或者类明, 然后 Alt 回车,pycharm可以自动导包,不用在手动在代…

Web前端 ---- 【Vue3】Proxy响应式原理

目录 前言 安装Vue3项目 安装 Proxy 语法格式 前言 从本文开始进入vue3的学习。本文介绍vue3中的响应式原理,相较于vue2中通过object.defineProperty(vue2中的响应式)来实现响应式,vue3中换成了Proxy来进行实现。 安装Vue3项目…

chat-plus部署指南

目录 1.下载代码 2.启动 3.测试 1.下载代码 cd /optwget https://github.com/yangjian102621/chatgpt-plus/archive/refs/tags/v3.2.4.1.tar.gz 2.启动 cd /opt/chatgpt-plus-3.2.4.1/deploydocker-compose up -d 3.测试 管理员地址xxx:8080/admin 账号密码admin/admin1…