量化专题报告 “量价淘金”选股因子系列研究(九) MemoryMap在因子生产加速上的应用 证券研究报告|金融工程 2024年11月20日 ——以构建羊群效应因子簇为例 前言:本文为国盛金工《“量价淘金”选股因子系列研究》的第九篇报告,也是“因子生产加速”相关研究的首次尝试,从数据存储技术、体系化的因子构建框架这两个角度出发,探索如何系统性、快速、批量挖掘Alpha 因子。 MemoryMap数据存储技术:相比于传统的CSV、Parquet等存储形式,MemoryMap减少了显式的文件I/O操作,将数据直接映射到内存中,可大幅提升访问速度。以读取宽表存储形式下、某一交易日所有股票的分钟 收盘价数据为例,MemoryMap的读取耗时不到800μs,读取速度约为Parquet的260倍、CSV的330倍。 体系化的因子构建框架——羊群效应因子簇:我们将事件研究的想法,融入到选股因子的构建中。提炼因子构建流程中的3个关键因素,事件识别、因子定义、数据频率,分别展开详细讨论。在MemoryMap数据存储技术 的助力下,基于经济学逻辑,最终构建了约50万个羊群效应因子,并通 过进一步筛选,保留其中效果最优且相关性较低的50个因子,称之为“羊群效应因子簇”。 羊群效应综合因子:在“羊群效应因子簇”中选取信息比率最高的10个因子、等权合成,得到羊群效应综合因子。回测期2016/01/01-2024/09/30内,在全体A股中,该因子的月度RankIC均值为0.116,年化RankICIR 为4.23;10分组多空对冲的年化收益为43.21%,信息比率为3.79,月度胜率为84.62%,最大回撤为6.31%。在剔除了市场常用风格和行业的影响后,纯净因子仍然有效,年化RankICIR达到3.67,全市场10分组多空对冲的信息比率为3.81。 指数增强组合的表现:基于羊群效应综合因子,构建月频调仓的指数增强组合:(1)沪深300指数增强组合的超额年化收益为9.06%,跟踪误差为 4.47%,信息比率为2.03,月度胜率为73.08%,最大回撤为4.42%;(2)中证500指数增强组合的超额年化收益为12.20%,跟踪误差为5.44%,信息比率为2.24,月度胜率为72.12%,最大回撤为4.36%;(3)中证1000指数增强组合的超额年化收益为17.78%,跟踪误差为6.57%,信息比率为2.71,月度胜率为82.69%,最大回撤为6.24%。 风险提示:以上结论均基于历史数据和统计模型的测算,如果未来市场环境发生明显改变,不排除模型失效的可能性。 作者 分析师沈芷琦 执业证书编号:S0680521120005 邮箱:shenzhiqi@gszq.com分析师刘富兵 执业证书编号:S0680518030007 邮箱:liufubing@gszq.com研究助理阮俊烨 执业证书编号:S0680124070019 邮箱:ruanjunye@gszq.com 相关研究 1、《“量价淘金”选股因子系列研究(一):如何将隔夜涨跌变为有效的选股因子?——基于对知情交易者信息优势的刻画》2022-04-26 2、《“量价淘金”选股因子系列研究(二):不同交易者结构下的动量与反转》2022-10-24 3、《“量价淘金”选股因子系列研究(三):如何基于RSI 技术指标构建有效的选股因子》2023-03-06 4、《“量价淘金”选股因子系列研究(四):高/低位放量:从事件驱动到选股因子》2023-12-18 5、《“量价淘金”选股因子系列研究(🖂):基于趋势资金日内交易行为的选股因子》2024-05-28 6、《“量价淘金”选股因子系列研究(六):创新高股票中的Alpha》2024-06-26 7、《“量价淘金”选股因子系列研究(七):盲目追随趋势资金的极端交易行为分析——羊群效应的识别与因子构建》2024-08-06 8、《“量价淘金”选股因子系列研究(八):逐笔买卖差异中的选股信息——条件成交不平衡因子》2024-10-09 9、《量化分析报告:择时雷达六面图:本期打分无变化》 2024-11-16 10、《量化周报:市场短期有可能进入震荡整固期》 2024-11-17 请仔细阅读本报告末页声明 内容目录 一、前言4 二、MemoryMap数据存储技术5 2.1概念简介5 2.2数据存储实例5 2.3数据读取与因子计算速度对比7 三、羊群效应因子簇的构建8 3.1因子构建的体系化思路8 3.2事件识别:趋势资金是否行动9 3.2.1各种不同维度的成交量9 3.2.2价格涨跌幅11 3.2.3价格波动率11 3.2.4量价相关性11 3.2.5小结12 3.3因子定义:羊群效应如何衡量13 3.3.1各种不同维度的成交量13 3.3.2价格涨跌幅14 3.3.3价格波动率14 3.3.4量价相关性14 3.3.5小结15 3.4数据频率:不同数据集的构建15 3.5因子的生产、筛选与表现16 3.5.1因子的批量生产与筛选:羊群效应因子簇16 3.5.2羊群效应综合因子示例17 3.5.3指数增强组合的表现19 四、国盛金工量价因子库简介22 �、总结23 图表目录 图表1:因子生产过程中的重要环节与因素4 图表2:宽表存储示例:以某日个股分钟收盘价为例5 图表3:窄表存储示例:以某日个股分钟行情数据为例5 图表4:MemoryMap数据存储结构:以某日个股分钟收盘价为例6 图表5:MemoryMap数据存储代码:以某日个股分钟收盘价为例6 图表6:MemoryMap、Parquet和CSV存储文件系统的数据读取速度对比7 图表7:因子构建的体系化思路:以羊群效应因子为例8 图表8:wind基于固定金额对大小单进行划分的标准9 图表9:平安银行(000001.SZ)20240830逐笔成交数据片段10 图表10:基于各种不同维度的成交量对趋势资金进行识别10 图表11:基于量价相关性的变化对趋势资金进行识别12 图表12:基于各种不同维度的成交量构建羊群效应因子14 图表13:基于量价相关性构建羊群效应因子15 图表14:羊群效应因子簇回测绩效示例16 图表15:羊群效应综合因子10分组及多空对冲净值17 图表16:羊群效应综合因子分年度表现18 图表17:羊群效应综合因子与Barra风格因子相关系数18 图表18:纯净羊群效应综合因子10分组及多空对冲净值19 图表19:纯净羊群效应综合因子分年度表现19 图表20:沪深300指数增强组合净值20 图表21:中证500指数增强组合净值20 图表22:中证1000指数增强组合净值21 图表23:国盛金工量价因子库示例22 一、前言 传统量化策略在当前市场环境下正面临一系列挑战,其中最显著的问题是边际效益递减。随着市场的发展与竞争的加剧,信息快速传播且投资者行为趋同,基于公开信息的策略越来越难以获得显著的Alpha,现有模型和因子的有效性在逐渐衰减;另一方面,靠人力挖掘Alpha新因子的难度也越来越大,提取增量信息的效率快速下降,需要持续投入大量资源对现有模型进行不断的升级和迭代,以维持未来获取超额收益的能力。 因此,如何系统性、快速、批量挖掘Alpha新因子,对传统模型进行迭代,就成为一项至关重要的技术。在此背景下,国盛金工推出“因子生产加速”相关研究,尝试在数据存储、因子计算、因子构建框架等各个层面做出努力,提升因子的生产效率。 图表1:因子生产过程中的重要环节与因素 资料来源:国盛证券研究所整理 本文为国盛金工《“量价淘金”选股因子系列研究》的第九篇报告,也是我们“因子生产加速”系列研究的首次尝试,先聚焦数据存储端,重点介绍MemoryMap这一数据存储技术将如何提升整个因子生产过程的效率,并具体以羊群效应因子的构建为例,详细介绍如何相对体系化地批量构建因子,最终提出“因子簇”的概念,得到羊群效应话题相关的一簇有效因子。 二、MemoryMap数据存储技术 2.1概念简介 MemoryMap(内存映射)技术是一种将文件或设备的内容直接映射到进程虚拟地址空间中的方法。通过这种方式,进程可以像访问内存一样访问文件或设备,而不需要显式地进行读写操作。 MemoryMap相比于传统的CSV、Parquet等存储形式,减少了显式的文件I/O操作,由于数据直接映射到内存中,因此提高了访问速度。该格式适用于需要频繁访问大文件的场景,如读取所有A股的高频量价数据。 2.2数据存储实例 股票行情数据的存储通常可分为宽表存储和窄表存储这两种形式,以分钟行情数据为例: (1))宽表存储,即将每个特征设置为二维矩阵、并保存为单独的文件,比如对于2024/09/30这一交易日的分钟收盘价数据,存为一个数据大小为242*N(242为每日分钟数据的总行数,N为当日股票数量)的矩阵文件; 图表2:宽表存储示例:以某日个股分钟收盘价为例 股票1 股票2 股票3 股票4 股票5 股票6 …… 股票N 分钟1分钟2分钟3 每个 格子里, 存放的 都是对应 股票对应分 钟的收 盘价数据 分钟4分钟5 …… 分钟242 资料来源:Wind,国盛证券研究所 (2)而对于窄表存储,我们会将当日的分钟开盘价、最高价、最低价、收盘价、成交量都存放在一个文件中作为列索引,行索引设置为股票代码和时间戳的双重索引,数据文件大小即为(242*N)*5。 图表3:窄表存储示例:以某日个股分钟行情数据为例 开盘价 最高价 最低价 收盘价 成交量 股票1 分钟1 股票1 分钟2 股票1 …… 股票1 分钟242 股票2 分钟1 每个格 子里,存放的 都是对应股票对 应分钟的 股票2 分钟2 开盘价 /最高价/最低 价/收盘价/成 交量数据 股票2 …… 股票2 分钟242 …… …… 股票N 分钟1 股票N 分钟2 股票N …… 股票N 分钟242 资料来源:Wind,国盛证券研究所 由于股票因子为截面数据,宽表更适合高效地进行向量化计算,因此我们选择宽表形式 存储高频量价数据,避免了窄表数据中需要通过for循环来遍历股票代码的操作。 接下来,我们具体展示一个利用MemoryMap格式进行数据存储的案例。比如 2024/09/30这一交易日分钟收盘价的宽表文件20240930_close_1m.mmap,由行索引 (分钟时间戳),列索引(股票代码)和数据值三部分构成。我们需要向系统申请一块连续的内存空间来存储这三部分数据,由于行索引和列索引为字符串格式,而数据值为浮点型,所以申请的内存空间数据格式也存在差异: (1)对于列索引(股票代码),我们认为每个股票代码的最长长度为9个字节(比如“000001.SZ”),因此需要9*N(N为股票数量)的空间来存储列索引; (2)对于行索引(分钟时间戳),我们认为最长长度为17个字节(比如“2024093009:30:00”),因此需要17*242的空间来存储行索引; (3)对于数据值,需要242*N的字节空间来存储。 至目前为止,我们一共需要9*N+17*242+242*N的空间来存储整个宽表文件。但在读取数据时,我们并不知道这块连续的空间中哪一部分是索引或者数据值,因此还需要在一开始留出额外的4个字节来存放基础信息:行索引个数、行索引最大长度、列索引个数、列索引最大长度。最终,我们总共需要4+9*N+17*242+242*N的空间来存储宽表文件20240930_close_1m.mmap,具体的存储结构如图表4所示。 图表4:MemoryMap数据存储结构:以某日个股分钟收盘价为例 资料来源:Wind,国盛证券研究所 图表5展示了具体的存储代码。对于DataFrame文件,我们首先计算出行和列索引的最大元素长度和元素数量(代码的第4-7行),然后定义内存空间的数据类型及写入的数据(代码的第10、11行),最后调用Numpy的memmap方法申请一块内存空间(代码的第14行)并写入数据(代码的第15行)。 图表5:M