前阵子一个做生猪产业研究的朋友问我:你手上用的CnOpenData期货日线行情表,后面是不是还得自己拼一遍复权因子?我没有急着回答,而是反问他三个问题:你要的“主力连续”,是按成交量选出来的,还是按持仓量选出来的?每天记录里的持仓量,你是按单边理解还是双边理解?数据列名写着“收盘价”的那一栏,和交易所口径下的“结算价”是不是同一个东西?他愣了几秒说,这些问题还真没想过。
这恰恰是很多人面对期货日线行情表时的真实状态:打开表格看到一张很规整的二维表,日期、合约代码、开高低收、成交量、持仓量,觉得所有答案都在里面,直接跑个模型就能出结果。但期货数据不同于股票数据的根本点在于,它是多合约生命周期的、带交易所撮合规则的、有结算制度约束的。哪个字段代表资金成本,哪个字段决定保证金,哪个价格可实际成交,哪条线其实是人工拼接出来的,表里不会主动告诉你,全靠使用者自己去判别。
这篇文章我打算把“拿到一张期货日线行情表之后,从识数、清洗到加工因子、验证数据源”这条链路完整过一遍。适合打算用期货日线数据做套保监控、产业链研究、CTA策略回测或毕业论文的同学。我不承诺给你现成策略,但希望能帮你少走几个我当年走过的弯路。
1. 一张日线行情表,撑起的不只是“画K线”
1.1 从套保、投研到量化:日线数据喂饱了谁
在很多人眼里,期货日线就是给行情软件画K线用的,这低估了基础行情数据的能量。商品研究里的基差监控,CTA策略里的趋势突破、跨期套利、期限结构因子,学术领域里的价格发现、市场有效性检验,底层几乎都依赖同一份东西——多合约、长历史、字段完整的日线明细。
比如企业套保场景,业务同学关心的是期货价格与现货价格的偏离程度,他们通常从日线行情里提取主力合约的收盘价或结算价,计算基差百分位,再决定是否入场套保。表面上这是个很简单的减法,但如果你用的合约不是真正的活跃合约,或者日期归属把夜盘时段切错了,基差曲线就会平白无故多出很多毛刺,套保决策也跟着走样。
CTA量化则是另一类典型:他们不仅需要价格,还需要能用来构造仓位权重的持仓量、能识别移仓时点的成交量,以及能确认涨跌停是否发生过的涨跌停价格。很多日频模型的特征,就是直接从行情表里若干字段的组合变换中来的。与其自己在分钟线上重复造轮子,不如先把日线这张表的每个字段吃透。
学术研究相对“挑剔”一点,通常要求数据可追溯、口径可解释。这时候,一张包含全合约明细而非只含主力合约的日线表反而更有价值,因为你可以在论文里明明白白写出筛选主力的规则,而不是依赖某个黑盒字段。如果平台本身把每个合约的上市日和最后交易日都记录得完整,研究过程会省去很多麻烦。
1.2 先认清边界:日线数据回答不了什么问题
我知道很多刚接触量化的人容易高估日线数据的能力。一些人拿到一张多年日线表,很想用它来构造“日内动量”或模拟高频交易策略,这是把数据的时间分辨率用错了地方。日线行情的粒度决定了它适合回答跨日层次的规律,比如趋势是否延续、持仓是否支撑价格、期限结构如何变化。至于开盘后半小时内的微观结构、盘口买卖压力、逐笔大单流向,日线数据几乎无能为力,硬做也只能靠插值和想象。
反过来,如果你只做日频调仓,日线数据是性价比最高的选择。它没有分钟线那种海量存储负担,也不会因撮合时点的细微差异造成巨大回测噪音。很多经典商品策略——时间序列动量、展期收益、基差修复——在日线层面就能完成绝大部分研究,不需要一开始就上高频数据。
所以使用前建议先给自己的研究问题定个“时间尺度”。如果核心止损逻辑在分钟级别,那就别在日线上折腾;如果持仓周期按天或按周计算,日线行情表就是最合适的主战场。想清楚这一点,比多下载几十张表都重要。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 别急着跑模型:结算价、持仓量与成交量背后的口径
2.1 结算价为什么比收盘价更“贵”
谈到期货日线数据,第一个容易混淆的概念就是收盘价和结算价。股票市场里几乎没有“结算价”的概念,大家都是拿收盘价算收益。但期货实行当日无负债结算制度,每天收盘后,交易所会按一定规则计算出一个当日结算价,用这个价格对全部持仓进行盈亏划转、确定保证金水平和下一个交易日的涨跌停板基准。
具体到规则,不同交易所、不同品种的结算价计算方式略有差别,常见做法是取收盘前一段时间内成交量的加权平均价,或者全天成交量的加权平均价。交易所在盘后公布的期货日行情表里,通常会同时包含今收盘和今结算两列。如果你在回测中只关注收盘价,忽略了结算价,那么持仓盈亏、追加保证金这些与账户真实变动相关的场景就会失真。
我见过不少人做期货回测时,把股票逻辑直接搬过来,每天用收盘价计算权益曲线。但在有夜盘和结算制度的市场里,账户下一交易日的保证金占用、可用资金,理论上是按当日结算价重新校准过的。尤其碰到大幅波动行情,收盘价和结算价的差距可能并不小,这时候用收盘价算出来的风险指标,可能会给你一种“账户很安全”的错误安全感。
所以拿到日线行情表时,建议先搞清楚你的数据里有没有结算价,如果没有,就要评估它是否会影响你的研究结论。对于套保监控、风险评估这类贴近账户的场景,结算价几乎是必须的字段;对于纯技术面的价格突破类策略,收盘价也能用,但要在报告中说明口径。
2.2 成交量、持仓量的单双边与时点问题
成交量与持仓量是期货日线表里另两个容易被误读的字段。先说成交量:国内商品期货的公开行情里,不同交易所不同时期采用过单边和双边两种统计口径。双边统计意味着同一笔交易买卖两边各计一次,单边统计则只计一次。如果要把多个交易所的品种放在同一张表里做横截面比较,而不先统一口径,量能绝对值的大小会失真,排序也可能反。
再说持仓量。日线表里的持仓量通常是当日结算后的全市场持仓总量,体现的是市场中尚未平仓的合约数量。交易所公布持仓数据时,一般按单边计算,但如果你用的是某个终端自动合成的数据,它可能已经帮你做过处理,也可能没有。最稳妥的做法是先找一个已知品种和日期,去交易所官网发布的每日持仓报告做一次核对,确认口径后再放心用于因子计算。
夜盘带来的时点问题更要留意。有夜盘交易的品种,一个完整交易日是从前一个工作日夜盘开始,到当天下午日盘收盘结束。但不同数据供应商对“日期”的处理不一样:有些把夜盘记录归到自然日当天,有些则归到下一个交易日。你可能遇到过一种怪现象:表格里出现了周六的数据。这大概率不是脏数据,而是周五晚上的夜盘从深夜一路开到了周六凌晨,如果按自然日切分,那一截成交就被记成了周六。
遇到这种情况,千万别急着把这些周六记录当异常删除。先确认你拿到的是交易日口径还是自然日口径。做跨品种研究时,如果所有品种都统一按交易日归并,自然不会出问题;如果你手里的表混用了不同口径,那么周一的开盘价、周五的夜盘行情都会出现系统性偏差。
2.3 为什么同样的品种,两份数据源对不上
做数据分析的人早晚会遇到一个现象:同一品种同一交易日,从两个平台下载的日线数据看起来不太一样,有时候是收盘价差一两个点,有时候是整个成交量差了一倍。这不是哪个数据源在造假,绝大多数原因出在口径。
差一两个点的,可能是复权与否的问题。期货虽然没有股票那种现金分红,但在拼接连续合约、调整换月跳空时,有些平台会把历史价格整体按比例缩放。另一个常见原因是合约代码的编码规则不同,比如同一个到期月份,有的平台用数字,有的平台用字母,解析错了就可能把两个合约混在一起。
成交量差一倍,多半是单双边口径的差异,或者是对方把期权成交也合并进了期货成交量字段。如果你研究的是品种整体流动性,包含期权可能不至于致命;但如果你要计算期货端的换手率,这个污染就会让指标失去意义。我在核对某类全合约日线表与商业终端数据时发现,很多差异不是谁对谁错,而是“含不含夜盘”“算不算双边”“按没按交易日归并”这几个典型参数没有对齐。因此,做任何跨源对比之前,先把“字段定义说明”找出来,永远比对着数字猜来猜去高效。
3. 上表第一件事:数据清洗三板斧
3.1 先对基准,再谈清洗
有些人拿到数据后,习惯先跑一行df.describe()看一眼,觉得没有空值、数据类型正常就认为这表是干净的。这种“干净”其实只是表面完整。日线行情的数据质量,至少要从“是否与官方口径一致”和“是否内部自洽”两个维度去检验。
我的第一步通常是挑一个品种的近三个月数据,去交易所官网下载对应的每日行情公告,做一个逐行核对。不需要全量核对,一百行左右就够了,但要覆盖主力切换、涨跌停、长假前后的时间点。对比的列包括:日期是否对齐、开盘价是否一致、收盘价是否一致、结算价是否一致、成交量是否在同一个量级。这一步能筛掉绝大多数由于字段映射错误、代码解析不当带来的表级别错误。
以前我遇到过一次,某个老品种的行情文件里把“前结算”当成了“今开盘”,导致后续算出的涨跌序列突然在某一天出现虚假的极限值。核对官方行情后才发现,是文件格式
