backtrader2

backtrader的基本策略构成:

#构成
#Backtrader 回测代码编写流程如下: 

import backtrader as bt # 导入 Backtrader 
import backtrader.indicators as btind # 导入策略分析模块
import backtrader.feeds as btfeeds # 导入数据模块

# 创建策略
class TestStrategy(bt.Strategy):
    # 可选,设置回测的可变参数:如移动均线的周期
    params = (
        (...,...), # 最后一个“,”最好别删!
    )
    def log(self, txt, dt=None):
        '''可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self):
        '''必选,初始化属性、计算指标等'''
        pass

    def notify_order(self, order):
        '''可选,打印订单信息'''
        pass

    def notify_trade(self, trade):
        '''可选,打印交易信息'''
        pass

    def next(self):
        '''必选,编写交易策略逻辑'''
        sma = btind.SimpleMovingAverage(...) # 计算均线
        pass

# 实例化 cerebro
cerebro = bt.Cerebro()
# 通过 feeds 读取数据
data = btfeeds.BacktraderCSVData(...) 
# 将数据传递给 “大脑”
cerebro.adddata(data) 
# 通过经纪商设置初始资金
cerebro.broker.setcash(...)
# 设置单笔交易的数量
cerebro.addsizer(...)
# 设置交易佣金
cerebro.broker.setcommission(...)
# 添加策略
cerebro.addstrategy(TestStrategy)
# 添加策略分析指标
cerebro.addanalyzer(...)
# 添加观测器
cerebro.addobserver(...)
# 启动回测
cerebro.run()
# 可视化回测结果
cerebro.plot()

数据传入必须包含的字段:

   datetime     sec_code    open      high       low      close       volume openinterest
0  2019-01-02  600466.SH 33.064891  33.496709  31.954503  32.386321   10629352    0
1  2019-01-02  603228.SH 50.660230  51.458513  50.394136  51.120778   426147  0

3、导入 backtrader,构建“大脑”

import backtrader as bt # 导入 Backtrader 

# 实例化 cerebro
cerebro = bt.Cerebro()

获取当前资金

cerebro.broker.getvalue()

4、如何导入多只股票的历史行情数据?

# 按股票代码,依次循环传入数据
for stock in daily_price['sec_code'].unique():
    # 日期对齐
    data = pd.DataFrame(index=daily_price.index.unique()) # 获取回测区间内所有交易日
    df = daily_price.query(f"sec_code=='{stock}'")[['open','high','low','close','volume','openinterest']]
    data_ = pd.merge(data, df, left_index=True, right_index=True, how='left')
    # 缺失值处理:日期对齐时会使得有些交易日的数据为空,所以需要对缺失数据进行填充
    data_.loc[:,['volume','openinterest']] = data_.loc[:,['volume','openinterest']].fillna(0)
    data_.loc[:,['open','high','low','close']] = data_.loc[:,['open','high','low','close']].fillna(method='pad')
    data_.loc[:,['open','high','low','close']] = data_.loc[:,['open','high','low','close']].fillna(0)
    # 导入数据
    datafeed = bt.feeds.PandasData(dataname=data_, fromdate=datetime.datetime(2019,1,2), todate=datetime.datetime(2021,1,28))
    cerebro.adddata(datafeed, name=stock) # 通过 name 实现数据集与股票的一一对应
    print(f"{stock} Done !")

5、配置回测条件(手续费,滑点,初始资金)

# 初始资金 100,000,000 
cerebro.broker.setcash(100000000.0) 
# 佣金,双边各 0.0003
cerebro.broker.setcommission(commission=0.0003) 
# 滑点:双边各 0.0001
cerebro.broker.set_slippage_perc(perc=0.0001)

6、查看指标

cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='pnl') # 返回收益率时序数据
cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='_AnnualReturn') # 年化收益率
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='_SharpeRatio') # 夏普比率
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='_DrawDown') # 回撤

7、交易代码

self.close() 平仓;
self.buy() 买入、做多;
self.sell() 卖出、做空;
self.cancel() 取消订单;
self.order_target_percent() 按持仓百分比下单,“多退少补”原则, 对于股票当前无持仓或持有的是多单(size>=0)的情况,若目标占比 target > 当前持仓占比,买入不够的部分;若目标占比 target < 当前持仓占比,卖出多余的部分。

8、打印回测日志

def notify_order(self, order):
    # 未被处理的订单
    if order.status in [order.Submitted, order.Accepted]:
        return
    # 已经处理的订单
    if order.status in [order.Completed, order.Canceled, order.Margin]:
        if order.isbuy():
            self.log(
                    'BUY EXECUTED, ref:%.0f,Price: %.2f, Cost: %.2f, Comm %.2f, Size: %.2f, Stock: %s' %
                    (order.ref, # 订单编号
                     order.executed.price, # 成交价
                     order.executed.value, # 成交额
                     order.executed.comm, # 佣金
                     order.executed.size, # 成交量
                     order.data._name)) # 股票名称
        else: # Sell
            self.log('SELL EXECUTED, ref:%.0f, Price: %.2f, Cost: %.2f, Comm %.2f, Size: %.2f, Stock: %s' %
                        (order.ref,
                         order.executed.price,
                         order.executed.value,
                         order.executed.comm,
                         order.executed.size,
                         order.data._name))

9、打印回测结果

# 启动回测
result = cerebro.run()
# 从返回的 result 中提取回测结果
strat = result[0]
# 返回日度收益率序列
daily_return = pd.Series(strat.analyzers.pnl.get_analysis())
# 打印评价指标
print("--------------- AnnualReturn -----------------")
print(strat.analyzers._AnnualReturn.get_analysis())
print("--------------- SharpeRatio -----------------")
print(strat.analyzers._SharpeRatio.get_analysis())
print("--------------- DrawDown -----------------")
print(strat.analyzers._DrawDown.get_analysis())

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神出鬼没,指的就是我!

必须花钱,数据超好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值