Home >  > ETF量化遇到的坑

ETF量化遇到的坑

一、QTM回测的取数问题
回测取20天的收盘价,可能包含了当天的收盘价。

在不同运行环境(实盘 / 某些数据服务)中,end_time 为当天日期时,底层可能返回一根代表当天的日线。如果这根日线已经包含了当天的“临时收盘价”或“最新价”,就相当于提前看到了当天的收盘数据。

我用测试代码测试了下,真的是这样:

#coding:gbk
import pandas as pd

def init(ContextInfo):
    print("开始测试...")

def handlebar(ContextInfo):
    today = '20260428'
    # 获取日线收盘价
    df_close = ContextInfo.get_market_data_ex(
        fields=['close'], stock_code=['513100.SH'], period='1d',
        count=3, end_time=today, dividend_type='front', fill_data=True, subscribe=False
    )
    # 获取日线成交量
    df_vol = ContextInfo.get_market_data_ex(
        fields=['volume'], stock_code=['513100.SH'], period='1d',
        count=3, end_time=today, dividend_type='none', fill_data=True, subscribe=False
    )

    if '513100.SH' in df_close:
        closes = df_close['513100.SH']
        print("日线收盘价 DataFrame:")
        print(closes)
        if today in closes.index.astype(str):
            print(">>> 警告:收盘价包含当日数据!")
        else:
            print(">>> 安全:收盘价不包含当日数据。")
    else:
        print("无收盘价数据")

    if '513100.SH' in df_vol:
        volumes = df_vol['513100.SH']
        print("日线成交量 DataFrame:")
        print(volumes)
        if today in volumes.index.astype(str):
            print(">>> 警告:成交量包含当日数据!")
        else:
            print(">>> 安全:成交量不包含当日数据。")
    else:
        print("无成交量数据")

二、ETF的复权问题

原来聚宽搞的是动态复权,官方有解释:
https://www.joinquant.com/view/community/detail/611ab01b6badd01f7f322af8c8c8b379?type=1

可是看不太懂。
我自己测试:set_option("use_real_price", True)
使用了这句:则价格等于同花顺的后复权。
不加这句,则等于同花顺的不复权。

AI的解释

时间线(回测运行方向):
────────────────────────────────────────────────────────────→
上市日 2019年除权日 2020年除权日 今天

当回测走到2019年:
当天成交价 = 不复权价(真实撮合价)
2019年之前的历史数据 = 以2019年的复权因子做前复权
2020年及之后 = 尚未发生,不存在

当回测走到2020年:
当天成交价 = 不复权价(真实撮合价)
2020年之前的历史数据 = 以2020年的复权因子做前复权
(此时2019年那天的前复权结果,可能与回测跑到2019年时不同)

三、价格差异
(一)0.01的判断,是数据源的问题,不管它。
(二)大的差异,是复权引起的,我注释掉聚宽的set_option("use_real_price", True),得到的数据和QMT下面的数据一样了。
比如515000有复权,QMT的数据如下:
2025-01-13 10:29:00 - DEBUG - 515000.SH 过滤(当前价 0.62 < 20日均价 0.65),计算20日均价用到的收盘价序列: [0.65, 0.64, 0.64, 0.65, 0.66, 0.67, 0.66, 0.67, 0.67, 0.69, 0.68, 0.68, 0.66, 0.63, 0.62, 0.62, 0.63, 0.63, 0.63, 0.62] 也和同花顺“向前复权”的结果一样。 (三) 510180.XSHG的数据,则是QMT和聚宽的数据差得比较大,和同花顺的数据也对不上。 QMTiqunat 2025-01-13 10:29:00 - DEBUG - 510180.SH 过滤(当前价 3.18 < 20日均价 3.33),计算20日均价用到的收盘价序列: [3.35, 3.34, 3.35, 3.37, 3.37, 3.36, 3.36, 3.41, 3.42, 3.41, 3.41, 3.43, 3.37, 3.26, 3.23, 3.22, 3.24, 3.24, 3.23, 3.20] 聚宽: 2025-01-13 10:29:00 - DEBUG - 510180.XSHG 过滤(当前价 3.22 < 20日均价 3.35,计算20日均价用到的收盘价数据:3.37, 3.36, 3.37, 3.39, 3.39, 3.38, 3.38, 3.42, 3.43, 3.43, 3.43, 3.44, 3.39, 3.29, 3.26, 3.25, 3.27, 3.27, 3.26, 3.23) 可是用同花顺和通达信看,不复权的价格 1月1日这天收盘价是3.55 1月10日这天收盘价是3.48呀, 原来也是复权的原因: 同花顺前复权后是1月10日这天收盘价是3.19 四、量比 除了下面的,其他的都对上了。 (一)iquant取不到数 2025-01-13 10:29:00 - DEBUG - 501018.SH 无有效现价,跳过 (二)513130.SH的量比两方对不上 2025-01-13 10:29:00 - DEBUG - 513130.SH | 现价:0.57 | 20日均:0.60 | 年化:-0.4921 | R2:0.5864 | 得分:-0.2885 | 量比:1.18 | 均线:未通过 五、R2 R²(决定系数)在这个策略中用于衡量 价格趋势线的拟合优度,也就是价格走势是否符合一条稳定的对数线性趋势。 其他都对得上,下面这个对不上 2025-01-13 10:29:00 - DEBUG - 513690.SH | 现价:0.84 | 20日均:0.87 | 年化:-0.2528 | R2:0.1256 | 得分:-0.0318 | 量比:0.49 | 均线:未通过 六、年化 其他的都对上,除了下面2个。 聚宽是0.6262,而iquant是 【2026-05-01 18:59:10.644】 2025-01-13 10:29:00 - DEBUG - 511090.SH | 现价:122.01 | 20日均:120.76 | 年化:0.6460 | R2:0.7772 | 得分:0.5021 | 量比:0.30 | 均线:通过 聚宽-0.4851,而iquant是 2025-01-13 10:29:00 - DEBUG - 510180.SH | 现价:3.18 | 20日均:3.33 | 年化:-0.5138 | R2:0.5832 | 得分:-0.2997 | 量比:0.53 | 均线:未通过 七、得分 其他都对上了,除了: 聚宽0.4866,而iquant是 【2026-05-01 18:59:10.644】 2025-01-13 10:29:00 - DEBUG - 511090.SH | 现价:122.01 | 20日均:120.76 | 年化:0.6460 | R2:0.7772 | 得分:0.5021 | 量比:0.30 | 均线:通过 下面的也有差异 2025-01-13 10:29:00 - DEBUG - 513690.SH | 现价:0.84 | 20日均:0.87 | 年化:-0.2528 | R2:0.1256 | 得分:-0.0318 | 量比:0.49 | 均线:未通过 2025-01-13 10:29:00 - DEBUG - 510180.SH | 现价:3.18 | 20日均:3.33 | 年化:-0.5138 | R2:0.5832 | 得分:-0.2997 | 量比:0.53 | 均线:未通过

暧昧帖

本文暂无标签