WonderTrader / Data & Servo
wondertrader 数据落地:格式、目录、基础文件与标的代码规则
实盘能不能跑,一半取决于数据这一层。官方文档明确:实盘环境只支持自有文件存储,历史数据压缩存放、实时数据用内存映射直接读写,而回测环境额外支持直接读 csv。这一页把存储方式、目录结构、基础文件清单、标的代码规则,以及官方自己写出的一个硬边界整理成可核对的表。
三种存储方式的取舍
官方文档把可选方式说得很清楚,选错的代价通常在实盘当天才暴露。
| 方式 | 支持的环境 | 读写特性 | 适用场景 | 注意点 |
|---|---|---|---|---|
| 自有文件存储 | 实盘与回测 | 历史 K 线压缩存放;实时数据用内存映射文件直接读写 | 实盘只支持这种方式;回测也推荐 | 实时文件不压缩,是为了保证读写速度,代价是占用空间比历史文件大 |
| csv 直读 | 仅回测 | 首次读取后转成自有压缩格式,之后解压即得结构化数据 | 把外部供应商给的 csv 快速纳入回测 | 只限历史 K 线;csv 体积大且首次读取开销高,别反复用 csv 跑大回测 |
| 数据库存储 | 回测(历史数据) | 支持用 MySQL 存历史数据 | 要在此之上搭自有投研库 | 实盘默认仍走文件存储,数据库是扩展而非默认;数据格式转换有成本 |
| 外部数据存储对接 | 回测与实盘 | 通过扩展加载器从既有数据引擎取数,通过扩展转储器在收盘作业时写回原存储 | 从其他量化平台迁移、不想先做全量数据转换 | 官方为迁移场景专门提供了加载器与转储器两个扩展点,但需自己实现接口 |
| 高频历史数据 | 回测与实盘 | 逐笔、股票逐笔委托明细、成交明细、委托队列均压缩存放 | 做盘口级研究 | 官方给出量级参考:股票全市场一天的逐笔数据压缩后不到 2GB 量级 |
| 内存缓存策略 | 实盘 | 历史数据全部缓存到内存,读取时直接引用内存切片 | 降低高频读取的拷贝开销 | 缓存换内存:标的订阅越多,常驻内存越高 |
数据目录长什么样
理解目录结构,是排查「数据到底落地了没有」的最快路径。以下目录树来自官方文档。
| 目录层级 | 存放内容 | 文件后缀 | 生成时机 | 排查时怎么看 |
|---|---|---|---|---|
| rt/ticks、rt/min1、rt/min5 | 实时高频数据与当日基础周期 K 线,按交易所分目录 | .dmb | 交易时段实时写入 | 盘中就该有文件且持续变大;没变化说明数据组件没接上行情 |
| his/ticks/交易所/交易日/ | 按交易日归档的逐笔数据 | .dsb | 收盘作业转储 | 按天分目录,便于定位某一天的行情 |
| his/min1、his/min5 | 合并后的分钟级历史 K 线 | .dsb | 收盘作业合并 | 与 rt 下的同日数据可交叉比对 |
| his/day | 由逐笔数据生成的日 K 线 | .dsb | 收盘作业生成 | 日线是当日 tick 生成的,不是供应商给的,口径要清楚 |
| cache.dmb | 临时缓存文件 | .dmb | 运行期 | 异常中断后残留属正常,但不应长期增长 |
| 数据落地根目录 | 上述全部结构的父目录 | — | 配置指定 | 官方明确要求数据组件与交易进程的该路径必须一致,否则读不到数据 |
11 个基础文件各自管什么
这些 json 文件是引擎初始化的输入。官方明确提醒:品种与合约文件需要定期维护,新增品种未同步映射会导致引擎初始化报错。
| 文件 | 管什么 | 关键字段 | 什么时候要动它 | 注意点 |
|---|---|---|---|---|
| commodities.json | 期货品种信息 | 平仓类型、价格模式、分类、交易模式、价格精度、最小变动、合约倍数、交易时段、节假日 | 新增期货品种 | 分类与价格模式的取值语义要按 CTP 口径理解,填错会导致下单行为异常 |
| contracts.json | 期货合约信息 | 名称、代码、交易所、所属品种、限价单与市价单单笔最大委托数量 | 合约换月、新品种挂牌 | 官方说回测时该文件内容不太关键,但品种文件里必须有你要回测的品种 |
| stk_comms.json | 股票品种信息 | 格式同期货品种文件 | 股票侧上线前 | 股票的平仓模式与交易模式(是否 T+1)与期货不同 |
| stocks.json | 股票与 ETF 列表 | 代码、交易所、名称、类型,可含地区与所属行业 | 股票池变化 | 与品种文件配合使用,缺一不可 |
| sopt_comms.json / stk_options.json | 股票期权品种与合约 | 行权价、底层品种、底层倍数、期权类型 | 期权上市或到期 | 期权代码结构与期货不同,别直接套用 |
| fee.json | 佣金费率 | 开仓、平仓、平今费用;按交易额还是按笔数计费 | 费率调整 | 费率填错会系统性扭曲回测绩效,比策略逻辑错误更难发现 |
| holidays.json | 节假日 | 地区与日期列表 | 每年更新 | 缺失会造成交易日计算错误 |
| hots.json / seconds.json | 主力与次主力换月规则 | 换月日期、换出与换入合约、换月前后收盘价 | 每月维护 | 使用主力合约代码时才需要;官方提供自动确定工具,比手工维护稳 |
| session.json | 交易时段模板 | 时段名称、夜盘偏移、集合竞价、分段交易时间 | 新交易时段 | 夜盘需要做时间偏移,使所有交易段落在同一交易日内 |
标的代码规则:写错一处,数据就取不到
官方 FAQ 给出了统一的代码标准。这张表是全文最容易踩坑的一页,建议在写第一行策略代码前先核对。
| 品种类型 | 标准格式 | 示例 | 常见错误 | 注意点 |
|---|---|---|---|---|
| 期货合约 | 交易所.品种.月份 | CFFEX.IF.2306 | 月份写成 3 位 | 郑商所的合约月份同样需要扩展为 4 位 |
| 期货主力 | 交易所.品种.HOT | CFFEX.IF.HOT | 手工写具体月份当主力用 | 框架会依据主力规则文件自动映射到分月合约,规则文件需每日维护 |
| 股票 | 交易所.类型.代码 | SSE.STK.600000 | 只写 6 位代码 | 取历史数据时要按复权口径处理,与信号代码写法不同 |
| 指数 | 交易所.类型.代码 | SZSE.IDX.399001 | 与股票代码混用 | 指数不可交易,只能作为信号输入 |
| ETF | 交易所.类型.代码 | SSE.ETF.510050 | 当普通股票处理 | 交易单位与股票一致,但标的类型不同 |
| ETF 期权 | 交易所.类型.代码 | SSE.ETFO.10003961 | 与商品期权格式混用 | 商品期权格式为交易所.品种月份.方向.行权价,两者不同 |
| 股票期权 | 见基础文件中的合约定义 | 底层代码如 510050 | 期权代码手工拼接 | 期权类型与行权价在合约文件中定义,不要凭代码猜 |
数据源对照:官方封装了哪些,怎么选
官方的数据辅助模块用工厂模式封装了多个数据源的差异,取数接口只有三类。选数据源时按「要不要花钱、要不要注册、要什么粒度」判断。
| 数据源 | 费用 | 注册要求 | 可取粒度 | 已知限制 |
|---|---|---|---|---|
| tushare | 免费为主 | 需要账号与 token | 日线为主,分钟数据受接口限制 | 官方文档指出:部分数据需要积分才能下载,下载速度较慢 |
| baostock | 免费开源 | 无需注册 | 可取 5 分钟线 | 官方评价为下载速度较快,适合快速起步 |
| RQData | 收费 | 需要账号 | 1 分钟甚至更高频 | 官方说明:有 1 分钟或更高频需求时免源数据源无法满足,收费源是可行选择 |
| tqsdk(天勤) | 按官方政策 | 需要账号 | 期货行情与历史数据 | 来自 wtpy 更新日志 0.9.8 的新增项;具体权限以官方说明为准 |
| 自备 csv | 取决于来源 | 无 | 取决于文件 | 首次读取后会被转成自有压缩格式,后续更快 |
| 外部数据引擎(扩展加载器) | 取决于已有系统 | 无 | 取决于原系统 | 官方为跨平台迁移提供加载器与转储器两个扩展点,需要自己实现接口 |
数据组件从启动到收盘的四步
数据组件是整个实盘链路的第一环,通常要在开盘前启动。以下按官方文档描述的工作逻辑展开。
配置落地目录与广播端口
在数据组件配置里指定数据存储路径与写盘方式,并设置广播地址与端口;同时配置订阅查询端口,用于查询最新快照。异步落地适合订阅量大的场景,同步落地更适合期货。
配置行情通道与要录制的合约
在行情通道配置里填前置地址与账号,并用合约代码列表指定要录制的范围。留空表示按合约文件里的全部合约录制;填写时必须与合约文件中的代码一致。
开盘前启动数据组件
按官方实盘攻略,一般在开盘前启动,例如 9:20。启动后它会实时录制行情、写入实时文件,并通知策略接收数据。
收盘作业(默认 16:00)
交易日结束后触发盘后处理:把实时高频数据按天按代码压缩归档;把当日分钟级 K 线合并进历史数据;依据当日逐笔数据生成日 K 线并合并进历史日线。
数据层排查表
数据层的故障多半不报错,只表现为「策略没反应」。按现象倒查配置比读日志更快。
| 现象 | 可能原因 | 核对方法 | 处理方向 |
|---|---|---|---|
| 策略一直收不到行情 | 广播端口与接收端口不一致,或行情通道账号未登录 | 比对数据组件与交易进程的端口配置 | 统一端口后重启数据组件,再启交易进程 |
| 回测读不到数据 | 数据目录配置与落地目录不一致,或存储模式选错 | 确认存储模式与目录路径,检查目录内是否有对应文件 | 先用官方 demo 自带数据跑通,再切自己的数据 |
| 合约代码取不到数据 | 代码格式不符合标准,或郑商所月份未扩为 4 位 | 对照本文代码规则表逐段核对 | 改用标准三段式代码,主力合约用 HOT 结尾 |
| 主力合约历史数据不连续 | 主力规则文件未维护,或拼接规则与数据存在方式不符 | 检查主力规则文件是否覆盖当前月份 | 用官方提供的主力确定工具生成规则,而不是手工补 |
| 新增期货品种后引擎初始化报错 | 新增品种未同步维护品种映射文件 | 检查映射文件里是否有该品种的键 | 官方提示必须补全映射键,否则引擎初始化会失败 |
| 用海外品种或数字货币做 7×24 回放 | 收盘作业机制不适用于 7×24 交易 | 看官方文档对收盘作业与 7×24 品种的说明 | 该场景官方明确表示暂不能很好适应,需另找方案 |
常见问题
数据层的问题在官方文档「历史数据处理」与「基础文件详解」里基本都有出处,以下是常见追问。
数据一定要用自有文件存储吗?
实盘是,回测不是。官方明确:实盘环境只支持自有文件存储;回测环境额外支持直接从 csv 读取,但仅限历史 K 线数据。另外官方支持用 MySQL 存历史数据,方便在此基础上搭自有投研库,不过它属于扩展手段而非默认路径。
为什么历史数据要压缩、实时数据不压缩?
因为两者的读写模式不同。历史数据读多写少,用 zstd 压缩存放,读取时解压一次即可全部载入内存,省空间;实时数据需要频繁读写,压缩会显著增加开销,因此不压缩而是用内存映射文件直接读写,保证速度、避免丢数据。代价是实时文件占空间更大。
收盘作业是干什么的?为什么它会影响选型?
收盘作业是每个交易日结束后的盘后处理,官方默认在每天 16:00 执行三件事:把实时高频数据按天按代码压缩归档、把当日分钟 K 线合并进历史数据、依据当日逐笔数据生成日 K 线并合并进历史日线。正因为依赖这个机制,官方明确说明本框架目前不能很好适应 7×24 小时交易的品种,例如数字货币。
主力合约数据是怎么拼出来的?
框架会依据主力合约规则文件自动映射。读历史数据时,如果用的是文件存储,会先找以主力代码命名的数据文件,找不到再按规则读取各分月合约的数据拼接;如果是数据库存储,则先按主力代码查询,再按规则拼接分月数据。所以主力规则文件必须持续维护,官方也提供了自动确定主力与次主力的工具。
财务数据要自己准备吗?
是。官方明确表示平台层面暂不做财务数据的标准化,理由是财务数据相对静态、可从不同渠道获取,且主要服务于选股类场景,而该场景与本框架的关注维度差异较大。需要财务因子时,由使用者自己在数据层解决。
取数据这件事,EasyClaw 能帮上什么?
能帮上取数这一段。EasyClaw 本机技能里有财经数据类技能(如封装了多个公开数据源的行情与基本面取数能力,需按各自文档确认版本与凭据),可以先把数据拿到手做研究。但数据组件的实时录制、收盘作业、内存缓存与多组合广播这套伺服机制不在 EasyClaw 技能范围内,两者之间也没有已证实的集成关系。