『Moonshot is all you need』01 - 5分钟上手极简回测框架

做基本面策略回测,不想用 backtrader 这样的框架,但 Alphalens 也不适合日线;另外,作为初学者,希望能从零开始实现一个策略回测,有助于了解策略回测的原理。这个想法也没错,关键是,要如何实现?

这一系列文章,将以中金2023年的一期研报为例,介绍如何实现一个较复杂的策略回测。我们将学习到如何获取各种数据,如何进行数据预处理,如何设计回测框架等关键技术。

图1 中金研报

这个策略从股息收益、资本利得和风险规避三大维度入手,综合了事件选股和因子选股的手段,最终回测结果表明,近5年年化收益率达到29%。

图2 基本面策略构建思路

我们将实现一个可用于月度调仓策略的普适性框架,它有这些特点:

  • 按月调仓 适用于基本面策略
  • 模块职责划分清晰 易于叠加组合
  • 简单易上手

核心驱动框架

往简单里说,回测就是在指定的时间段(过去)里:

  1. 根据当时能得到的数据,发出交易信号
  2. 根据交易信号进行调仓
  3. 计算策略的每个交易期的收益
  4. 策略评估与可视化

一般来说,第一步是策略的核心。策略不同,要使用的数据也不同,构建的因子,以及决策逻辑也不同。但其它部分可以做到重复使用。特别是第4步,策略的评估与可视化,我们将使用 Quantstats 来实现。

我们先介绍如何实现第2步和第3步,即调仓和收益计算。

假设我们已经获取了股票的日线行情数据。由于我们的策略是按月调仓,所以,我们将行情数据重采样成了月线数据。

现在,这份数据看起来如下图所示:

图3 月行情数据

对月度调仓策略,先将数据重采样到月是一个重要的技巧。如果不这样,你就要先确定每个月的调仓日(每个月还不固定),再根据这个调仓日,去查找个股当天的因子数据和收盘价。一旦调仓日有个股停牌,就会出现数据缺失。

另一个好处是,现在我们可以在上月发出调仓信号后,按下月的开盘价买入,下月的收盘价卖出,这样严格地避开了未来数据。一些策略在计算收益时,仅使用收盘价,这样不可避免地要么引入未来数据,或者信号响应不及时。

现在,计算收益就变得很简单。比如,计算基准收益就是:

df.groupby("month").apply(
    lambda x: (x.close / x.open - 1).mean()
)
图4 基准收益计算

如果要计算组合的收益率呢?我们需要增加一列,先标记出哪些股票在当月的股票池中:

图5 组合收益计算

在图5中,我们增加了3列。其中 filter_1 是用来筛选股票的基础数据,比如,研报要求按每月筛选出股息率前 500 的股票,这一列就可以是股息率数据。

flag 列是根据 filter_1 列的数据,按照规则生成的『个股是否在股票池』的标记。在图中,假定规则是,如果 filter_1 大于零,则该个股在下个月的股票池中。这样我们就得到了2023年2月的股票池。

现在,我们计算策略收益时,只需要按月执行:

∑(returns×flag)∑flag \frac{\sum(returns \times flag)}{\sum flag} flag(returns×flag)

就能得到每月的策略收益。这一步相当于执行代码:

df.groupby("month").apply(
    lambda group: group[group["flag"] == 1]["returns"].mean()
)

到这一步为止,我们已经明确了要实现一个极简的月度回测框架,大致上要做的事情如下:

  1. 获取行情数据,重采样成为月度数据
  2. 根据策略要求,获取相关数据,构建因子
  3. 将第2步中构建的因子 (factor) 也重采样成为月度数据,附加到1中生成的 DataFrame 中
  4. 根据策略逻辑,将 factor 列转换成为 flag 列。
  5. 按月计算基准收益和策略收益
  6. 调用 quantstats 生成回测报告。

Moonshot 的实现

我们把这个极简框架命名为 Moonshot,因为它更适合固定按月调仓换股的策略。它的核心是一个名为 Moonshot 的类:

class Moonshot:
    def __init__(self, daily_bars:pd.DataFrame):
        self.data: pd.DataFrame = resample_to_month(daily_bars, open='first', close='last'
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

量化风云

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值