做了一个小频率动量策略,主要感受了回测和实盘差异。。

3 月 19 日
 matters

最近老加班,但也挤时间做了一个小频率动量策略(主要是日内或日频),我是真的爱,谁懂!!

1. 策略思路

2. 回测表现

回测部分其实代码不复杂,核心就是用过去几天收益做一个简单排序:


import pandas as pd

#假设已有行情数据:date, symbol, close
df = pd.read_csv("daily_price.csv", parse_dates=["date"])

#按股票分组,计算过去 5 日收益率(动量因子)
df["momentum"] = df.groupby("symbol")["close"].pct_change(5)

#每天按动量排序,取前 20%作为买入信号
df["rank"] = df.groupby("date")["momentum"].rank(pct=True)

df["signal"] = 0
df.loc[df["rank"] >= 0.8, "signal"] = 1

#下一交易日收益(模拟第二天持有)
df["next_return"] = df.groupby("symbol")["close"].pct_change().shift(-1)

#回测收益(理想状态,不考虑滑点手续费)
df["strategy_return"] = df["signal"] * df["next_return"]

#每天组合平均收益
daily_return = df.groupby("date")["strategy_return"].mean()

#累计收益曲线
cum_return = (1 + daily_return).cumprod()

print(cum_return.tail())

实盘中你需要处理缺失值、停牌、成交量异常,否则 signal 可能触发错误交易。

如果有接类似 AKShare 、AllTick 之类的实时行情 API ,可以直接把 data 替换成实时数据流,生成实时 signal 。

3. 实盘差异

4. 小小心得

1366 次点击
所在节点    投资
4 条回复
balckcloud37
3 月 19 日
这个信号是按天产生的,那什么时候买,开盘时吗?回测是预设以信号当天的收盘价买入的
LxxxW
3 月 19 日
# 1. 缺失值未处理
df["momentum"] = df.groupby("symbol")["close"].pct_change(5) # 前 5 行会是 NaN

# 2. 停牌股票未过滤
# 停牌股票复牌后可能大幅补涨/补跌,动量因子会失真

# 3. 成交量未验证
# 没有检查流动性,可能选到无法成交的标的

# 4. 信号未去重
# 每天调仓?还是持有 N 天?逻辑不清晰
Sawyerhou
3 月 19 日
好奇你这个底层票池是什么,如果是沪深 300 ,那选前 20%的票是每天持有 60 只?还是说实盘没买这么多只?

这个策略回测中真的是赚钱的吗?理论上周级别价格走势应该以反转为主,月级别以上才是动量为主。

佣金姑且不说,代码里可以先加个印花税 5%%试试,即:
daily_return -= 5e-4
inframe
3 月 21 日
实时行情的模拟盘来测试就好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1199556

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX