买入并持有,是一个最简单的策略,一般来说这个策略是用来衡量其他策略好坏的基础。也就是如果一个策略的收益最后还跑不赢买入并持有的策略的话说明这个策略是无效策略,白折腾一场。
在backtrader官网上有相关介绍:https://www.backtrader.com/blog/2019-06-13-buy-and-hold/buy-and-hold/
这里我只介绍最简单的买入并持有的策略代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class BuyAndHold_1(bt.Strategy): def start(self): self.val_start = self.broker.get_cash()
def nextstart(self): size = self.broker.getvalue() / self.data.close[0] // 100 * 100 self.buy(size=size)
def stop(self): self.roi = (self.broker.get_value() / self.val_start) - 1.0 print('ROI: {:.2f}%'.format(100.0 * self.roi))
|
在策略开始时调用start函数,获取当前的现金。随后调用nextstart函数把所有现金都用来购买股票,nextstart函数在第一个next函数调用开始前触发,nextstart函数只触发一次。最后在回测时间结束后调用stop函数,计算投资回报率。
回测结果如下,回测区间为 2019-01-01 到 2024-01-01,第一个交易日为2019-01-01,用所有现金以这一天的收盘价购买了股票。

控制台输出:

下面是我自己改写的支持指定日期的买入并持有的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class BuyAndHold(bt.Strategy): params = ( ('start_date', None), ) def __init__(self): self.ok=False self.start_date = datetime.strptime(self.p.start_date, '%Y-%m-%d %H:%M:%S') if self.p.start_date is not None else None
def start(self): self.val_start = self.broker.get_cash()
def next(self): if self.start_date is not None and self.start_date>bt.utils.num2date( self.data.datetime[0]): return if self.ok: return self.ok=True vol = self.broker.getvalue() / self.data.close[0] // 100 * 100 self.buy(size=vol)
def stop(self): self.roi = (self.broker.get_value() / self.val_start) - 1.0 print('ROI: {:.2f}%'.format(100.0 * self.roi))
|
用start_date参数传入开始买入的时间,用一个ok变量来记录有没有买入股票,如果当前k线的时间大于start_date且ok为False则把所有资金都买入股票,然后把ok变量设置为True。
回测结果如下,回测区间为 2019-01-01 到 2024-01-01,设置的start_date为 2020-01-01 ,start_date 后的第一个交易日为 2020-01-02 ,用所有现金以这一天的收盘价购买了股票。

控制台输出结果:

这一篇就到这里啦。欢迎大家点赞、转发、私信。
