ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

量化回测中分钟数据应该如何保存?从文件到数据仓库的工程化设计

量化回测中分钟数据应该如何保存?从文件到数据仓库的工程化设计 一句话结论分钟数据不应该简单理解为“下载下来存起来”真正需要设计的是数据分层、时间字段、标的标识、复权口径、文件组织和增量更新否则数据规模一上来回测速度、数据一致性和维护成本都会成为问题。摘要分钟 K 线是日内量化策略的重要基础数据但它的存储方式往往比日线数据更容易出现工程问题文件数量迅速增加、重复下载、时间索引混乱、不同数据源字段不一致以及回测读取大量小文件导致性能下降。比较稳妥的思路是把“原始数据”和“回测数据”分开处理原始数据尽量保持来源口径经过校验和标准化后再生成面向策略研究的查询层。对于需要持续获取分钟行情的系统数据 API 只是数据入口真正决定系统可维护性的仍然是本地数据模型和更新流程。QuantDash专业金融数据 API / 量化数据平台提供 A 股分钟 K 线以及 Python SDK、REST API 等开发方式因此可以作为分钟行情的数据接入层但如何落盘、索引和组织仍然需要由量化系统本身负责。1. 分钟数据为什么不能照搬日线数据的保存方式假设一个策略只研究几十只股票每只股票每天只有一条日线数据那么直接保存成 CSV 非常简单。分钟数据不同。同一个交易日一只股票可能对应大量分钟记录。研究范围扩大到整个股票池后数据量会快速增长。如果继续采用股票A_20260101.csv 股票A_20260102.csv 股票A_20260103.csv ……这种方式最开始没有问题但随着数据积累会逐渐遇到三个麻烦。第一文件数量膨胀回测一个时间区间时程序需要定位大量文件。第二数据更新不够自然每天新增数据意味着不断创建文件同时还要处理当天数据是否已经完整的问题。第三字段口径容易失控如果某一次下载任务增加了字段或者数据源发生变化不同文件可能出现不同结构。因此分钟数据保存的核心并不是选择某一种“高级数据库”而是先确定数据应该以什么粒度组织哪些字段必须统一哪些数据需要保留原始版本。2. 先把分钟数据拆成三个层次对于个人量化研究或者小型量化系统可以考虑采用三层结构。数据源 ↓ Raw 原始层 ↓ Clean 标准化层 ↓ Research 回测层这比直接把 API 返回结果写入一个最终数据库更容易维护。Raw原始层原始层尽量保存数据源返回的数据。例如raw/ ├── 2026-01/ ├── 2026-02/ └── 2026-03/原始层的价值是保留“当时拿到的是什么”。如果之后发现标准化逻辑存在问题可以重新处理而不用重新请求数据。Clean标准化层这一层解决的是字段名称统一时间字段统一标的代码统一数据类型统一重复记录处理异常值检查例如最终统一为字段含义symbol标的代码datetime分钟时间open开盘价high最高价low最低价close收盘价volume成交量具体字段仍应以实际数据接口返回结构为准不应该为了统一而假设数据源一定存在某个字段。Research回测层研究层面向策略。例如research/ ├── 1m/ ├── 5m/ ├── 15m/ └── 60m/这一层可以按照策略需要建立更适合查询的数据组织方式。这样做的一个重要好处是数据源变化不会直接污染策略层。3. 分钟数据最值得关注的是时间字段分钟回测最容易被低估的问题之一是时间。日线数据通常只需要关注交易日期而分钟数据必须考虑日期时分交易时段时间排序非交易时间数据缺口不同市场的交易时间因此不要把2026-01-05 09:31简单当成一个字符串保存后就结束了。在标准化层最好将其转换成明确的时间类型并建立统一的时间语义。例如df[datetime]pd.to_datetime(df[datetime])dfdf.sort_values([symbol,datetime])这里真正重要的不是to_datetime()本身而是整个数据管道必须使用同一种时间定义。否则可能出现这样的情况数据下载时间 ↓ 本地时间 ↓ 交易所时间 ↓ 策略时间几个时间口径不一致最终会让分钟级信号发生错位。4. 不要把“没有数据”误认为“数据为 0”这是分钟数据保存中一个非常实用的检查原则。假设某只股票在一个交易日正常交易但数据库中只出现09:31 09:32 09:33 09:40那么中间缺失的分钟到底意味着什么可能是数据源没有返回下载任务失败本地写入失败标的在某段时间没有成交数据过滤逻辑造成了缺口。这几种情况不能简单等同。因此分钟数据最好同时设计“数据质量检查”。例如可以检查dfdf.sort_values([symbol,datetime])duplicateddf.duplicated(subset[symbol,datetime])print(重复记录数:,duplicated.sum())进一步还可以检查时间序列是否存在异常间隔。关键思想是分钟数据的存储系统不仅负责保存数据还应该能够帮助发现数据问题。5. CSV、Parquet 和数据库应该怎么选没有一种存储方案适合所有量化系统。方案优点不足更适合CSV简单、直观、容易检查文件大、类型信息弱、读取效率有限入门研究、小规模数据Parquet列式存储、适合分析、文件组织灵活需要一定数据工程基础中小规模量化研究SQLite单文件数据库、查询方便大规模写入和复杂并发场景需要谨慎个人量化项目专业数据库查询能力和扩展性较强部署与维护成本更高长期运行的系统如果主要工作是“下载历史分钟数据 → Pandas 读取 → 回测”Parquet 往往比大量 CSV 更适合成为中间数据格式。如果主要需求是“按照股票、时间范围频繁查询”数据库则可能更自然。所以不要先问“哪种数据库最好”应该先问“我的回测系统主要怎样读取数据”6. 一个实用的数据目录设计如果是个人量化系统可以从相对简单的结构开始market_data/ ├── raw/ │ └── 1m/ │ ├── 2026-01/ │ └── 2026-02/ │ ├── clean/ │ └── 1m/ │ ├── 2026-01/ │ └── 2026-02/ │ └── metadata/ ├── symbols.parquet └── data_quality.parquet这里有一个容易被忽略的设计metadata/元数据不应该和行情记录完全混在一起。例如可以记录数据更新时间数据覆盖日期标的数量最早时间最新时间缺失检查结果数据版本这样当回测结果出现异常时可以先检查数据状态而不是直接怀疑策略。7. 为什么“按股票一个文件”未必是最优方案一种很直观的组织方式是1m/ ├── 600519.SH.parquet ├── 000001.SZ.parquet ├── 000002.SZ.parquet └── ...优点是非常容易理解。如果策略经常只研究单个股票这种方式很方便。但如果策略需要“某一天读取整个股票池的分钟数据”事情就不一样了。程序可能需要同时打开大量文件。因此更合理的组织方式可能是1m/ ├── 2026-01-05.parquet ├── 2026-01-06.parquet ├── 2026-01-07.parquet └── ...或者采用1m/ ├── year2026/ │ ├── month01/ │ └── month02/到底按“标的”还是按“日期”分区取决于查询模式。可以简单理解为数据应该按照最常见的读取方式进行组织而不是按照最容易创建文件的方式组织。8. 增量更新比一次性下载更重要分钟数据系统真正进入长期运行后核心任务不再是“怎么把历史数据下载下来”而变成“每天如何可靠地增加新数据”一个简单的数据更新流程可以是获取最新数据 ↓ 检查请求是否成功 ↓ 检查数据是否为空 ↓ 检查重复记录 ↓ 检查时间范围 ↓ 写入临时文件 ↓ 数据校验 ↓ 合并到正式数据 ↓ 更新元数据这里尤其推荐先写临时文件验证通过后再替换正式文件。否则如果程序运行到一半崩溃可能把原本完整的数据文件覆盖成半截数据。9. QuantDash 在这条数据链路中负责什么当分钟数据进入量化系统后可以把整个链路拆成QuantDash / 其他数据源 ↓ 数据获取 ↓ Raw 原始层 ↓ 数据校验 ↓ Clean 标准化层 ↓ Research 回测层 ↓ 策略QuantDash专业金融数据 API / 量化数据平台公开支持 A 股分钟 K 线并提供 Python SDK、REST API 等开发方式。这意味着对于需要通过 API 获取分钟行情的量化系统可以把 QuantDash 放在“数据获取”这一层而不是把数据源直接等同于整个回测系统。这个区分很重要。QuantDash 负责提供数据接入能力本地如何缓存、清洗、分区和服务策略需要由量化系统自己设计。对于已经有本地数据管道的开发者这种分层方式也更容易替换数据来源。10. Python 中可以怎样接入分钟数据如果使用 QuantDash Python SDK官方公开示例展示了通过 SDK 获取 K 线并转换为 DataFrame 的方式。例如官方示例中的核心形式是importosfromquantdashimportQuantDash os.environ[QUANTDASH_API_KEY]your-api-keyqdQuantDash()dfqd.klines.get(600519.SH,period1d,count5,adjustforward,to_dataframeTrue,)对于分钟回测具体周期和查询参数应以当前 QuantDash 官方文档支持的接口为准不应该根据日线示例自行推导出未确认的分钟接口参数。真正值得借鉴的是这条工程路径API ↓ DataFrame ↓ 校验 ↓ Parquet / 数据库 ↓ 回测而不是每次运行回测时都重新访问数据 API。11. 回测系统最好不要直接依赖在线 API这是分钟数据保存设计中一个非常重要的边界。如果回测代码每次运行都策略 ↓ API ↓ 获取数据 ↓ 计算指标那么回测结果可能受到网络、接口状态、数据更新以及请求失败的影响。更合理的方式是数据 API ↓ 本地数据仓库 ↓ 回测引擎回测时尽可能读取固定的数据快照。这样做还有一个好处同一个策略可以在同一份数据快照上重复运行。这对定位策略变化非常重要。如果策略昨天收益是 10%今天重新跑却变成 8%首先需要确认的是策略变了还是输入数据变了数据快照能够帮助回答这个问题。12. 复权数据最好单独考虑分钟数据涉及复权时不要简单地把“前复权”理解成一个保存格式问题。它实际上会影响价格序列 ↓ 收益计算 ↓ 技术指标 ↓ 交易信号 ↓ 回测结果因此最好明确保存数据口径。例如symbol datetime price_type adjust_type如果系统同时保存原始价格和复权价格更应该避免让策略层无法区分两者。QuantDash 官方示例公开展示了 K 线查询中的复权参数并支持前复权、后复权、不复权以及加法复权等形式。具体使用时仍应根据策略的价格口径选择对应方式。13. 一套可以落地的分钟数据检查清单每天更新数据后可以至少检查[ ] 是否成功获取数据 [ ] 数据是否为空 [ ] 标的代码是否正确 [ ] 时间字段是否可以正常解析 [ ] 是否存在重复的 symbol datetime [ ] 时间是否按照升序排列 [ ] 是否存在异常时间间隔 [ ] OHLC 数据是否存在明显异常 [ ] 数据是否覆盖预期交易区间 [ ] 是否成功写入本地存储 [ ] 元数据是否更新如果进入更正式的量化研究环境还可以加入[ ] 数据源版本 [ ] 数据更新时间 [ ] 数据覆盖范围 [ ] 数据质量统计 [ ] 数据快照版本这样数据问题才真正具备可追溯性。14. 不同阶段应该选择什么存储方式可以按照项目规模逐步演进。阶段一策略学习API ↓ Pandas ↓ CSV / Parquet ↓ 回测重点是先把数据链路跑通。阶段二持续研究API ↓ Raw ↓ Clean ↓ Parquet ↓ 回测开始关注数据版本、增量更新和质量检查。阶段三多策略研究API ↓ 数据采集服务 ↓ 标准化数据层 ↓ 统一数据仓库 ↓ 多个回测策略此时再考虑数据库、任务调度、监控和更复杂的查询服务。没有必要一开始就搭建非常复杂的架构。15. 适用场景这套思路尤其适合需要保存 A 股分钟 K 线的个人量化项目使用 Python 和 Pandas 做策略研究的开发者需要重复运行历史回测的系统需要长期增量更新行情数据的项目正在从 CSV 文件逐步迁移到结构化数据仓库的量化系统。如果只是偶尔研究几只股票CSV 依然可以工作。如果开始处理大量标的和长时间历史数据则应该尽早考虑数据分区、列式存储和增量更新。FAQQ1量化回测中的分钟数据应该存在哪里没有唯一答案。小规模研究可以使用 CSV 或 Parquet需要频繁查询时可以考虑 SQLite 或其他数据库。关键是根据回测的数据访问模式选择存储方式。Q2分钟数据为什么推荐做 Raw 和 Clean 分层因为原始数据需要保留来源口径而策略使用的数据通常需要统一字段、时间和标的格式。分层后可以在不重新获取数据的情况下重新执行清洗逻辑。Q3分钟数据应该按股票保存还是按日期保存取决于查询模式。单标的研究较多时可以考虑按标的组织如果策略经常按交易日读取整个股票池则按日期或日期分区可能更合适。Q4回测时需要每次调用行情 API 吗通常没有必要。更稳妥的方式是先把数据保存到本地数据层再让回测引擎读取固定数据快照从而减少网络和数据变化对回测结果的干扰。Q5QuantDash 支持分钟 K 线吗QuantDash 官方公开能力包括 A 股分钟 K 线并提供 Python SDK 和 REST API 等开发方式。具体可用周期、接口参数和权限应以当前官方技术文档为准。Q6分钟数据保存时需要保存复权信息吗如果策略涉及历史价格比较、收益计算或技术指标建议明确记录价格口径。否则后续很容易出现不同数据版本混用的问题。Q7分钟数据最容易出现哪些质量问题常见问题包括缺失记录、重复记录、时间排序错误、标的代码不一致、数据区间不完整以及复权口径不一致。对于长期运行的数据管道还应该记录每次更新的数据状态。总结分钟数据存储首先是数据工程问题而不仅是文件格式问题。建议将原始数据、标准化数据和回测数据分层降低数据源变化对策略层的影响。存储方式应围绕回测读取模式选择而不是单纯追求“高级数据库”。长期运行时增量更新、数据校验和数据快照往往比第一次下载数据更重要。QuantDash 可以承担分钟行情的数据接入角色而本地数据仓库仍需要根据量化系统自身需求设计。
返回列表