使用 Backtrader 框架构建了一个简单的量化交易回测系统。首先,导入必要的模块和 Backtrader 库。然后,创建了一个自定义的策略类 TestStrategy,在这个策略中,__init__ 方法引用了收盘价数据,next 方法会在每个 K 线数据上被调用,用于按天输出收盘价。接着,创建了 Cerebro 对象作为回测的核心管理单元,添加了自定义策略和从 CSV 文件读取的股票数据,并设置初始资金为 10 万。最后,打印初始投资组合价值,运行回测,再打印回测结束后的投资组合价值。由于策略中没有添加实际的交易逻辑,所以初始和最终价值相同。
(1)Backtrader程序代码
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import datetime # 用于datetime对象操作
import os.path # 用于管理路径
import sys # 用于在argvTo[0]中找到脚本名称
import backtrader as bt # 引入backtrader框架
# 创建策略
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' 策略的日志函数'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# 引用data[0]数据的收盘价数据
self.dataclose = self.datas[0].close
def next(self):
# 日志输出收盘价数据
self.log('Close, %.2f' % self.dataclose[0])
# 创建cerebro实体
cerebro = bt.Cerebro()
# 添加策略
cerebro.addstrategy(TestStrategy)
# 先找到脚本的位置,然后根据脚本与数据的相对路径关系找到数据位置
# 这样脚本从任意地方被调用,都可以正确地访问到数据
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
datapath = os.path.join(modpath, '../../TQDat/day/stk/000001.csv')
# 创建价格数据
data = bt.feeds.GenericCSVData(
dataname = datapath,
fromdate = datetime.datetime(2024, 1, 1),
todate = datetime.datetime(2025, 1, 10),
nullvalue = 0.0,
dtformat = ('%Y-%m-%d'),
datetime = 0,
open = 1,
high = 2,
low = 3,
close = 4,
volume = 5,
openinterest = -1
)
# 在Cerebro中添加价格数据
cerebro.adddata(data)
# 设置启动资金
cerebro.broker.setcash(100000.0)
# 打印开始信息
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
# 遍历所有数据
cerebro.run()
# 打印最后结果
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
(2)Backtrader程序代码输出结果
2025-01-03, Close, 11.38
2025-01-06, Close, 11.44
2025-01-07, Close, 11.51
2025-01-08, Close, 11.50
2025-01-09, Close, 11.40
Final Portfolio Value: 100000.00
(3)程序代码注释
# 从 __future__ 模块导入绝对导入、除法、打印函数和 Unicode 字面量支持
# 确保代码在不同 Python 版本中具有一致的行为
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# 导入 datetime 模块,用于处理日期和时间,如指定数据的时间范围
import datetime
# 导入 os.path 模块,用于管理文件和目录路径,方便找到数据文件
import os.path
# 导入 sys 模块,用于获取命令行参数和系统相关信息,帮助定位脚本位置
import sys
# 引入 backtrader 框架,用于构建和运行量化交易回测
import backtrader as bt
# 创建策略类,继承自 backtrader.Strategy
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' 策略的日志函数,用于输出带有日期的信息 '''
# 如果没有传入日期,使用当前数据的日期
dt = dt or self.datas[0].datetime.date(0)
# 打印日期和信息
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# 引用 data[0] 数据的收盘价数据,方便后续使用
self.dataclose = self.datas[0].close
def next(self):
# 调用日志函数,输出当天的收盘价
self.log('Close, %.2f' % self.dataclose[0])
# 创建 cerebro 实体,Cerebro 是 Backtrader 的核心管理对象
cerebro = bt.Cerebro()
# 向 cerebro 中添加自定义的策略
cerebro.addstrategy(TestStrategy)
# 获取当前脚本的绝对路径的目录部分
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
# 根据脚本目录和相对路径构建数据文件的完整路径
datapath = os.path.join(modpath, '../../TQDat/day/stk/000001.csv')
# 创建价格数据对象,从 CSV 文件中读取数据
data = bt.feeds.GenericCSVData(
# 数据文件的路径
dataname = datapath,
# 数据的起始日期
fromdate = datetime.datetime(2024, 1, 1),
# 数据的结束日期
todate = datetime.datetime(2025, 1, 10),
# 处理缺失值,用 0.0 填充
nullvalue = 0.0,
# 日期的格式
dtformat = ('%Y-%m-%d'),
# 日期列在 CSV 文件中的索引
datetime = 0,
# 开盘价列在 CSV 文件中的索引
open = 1,
# 最高价列在 CSV 文件中的索引
high = 2,
# 最低价列在 CSV 文件中的索引
low = 3,
# 收盘价列在 CSV 文件中的索引
close = 4,
# 成交量列在 CSV 文件中的索引
volume = 5,
# 持仓量列在 CSV 文件中的索引,-1 表示没有该列
openinterest = -1
)
# 将价格数据添加到 cerebro 中
cerebro.adddata(data)
# 设置经纪人(代理)的初始资金为 10 万
cerebro.broker.setcash(100000.0)
# 打印初始的投资组合价值
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
# 运行回测,遍历所有数据
cerebro.run()
# 打印回测结束后的投资组合价值
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/913379
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!