一句话结论:A 股和美股的行情数据可以统一到同一套内部数据模型中,但统一的应该是字段定义、数据类型和处理接口,而不是交易规则、时间语义和所有市场特有属性。
摘要
同时研究 A 股和美股时,如果每个市场都使用独立的数据结构,策略代码很容易出现重复,增加维护成本。更合理的方案是建立统一的行情数据模型,将标的代码、时间、价格、成交量等核心字段标准化,同时保留市场标识、原始数据口径和交易日历等必要信息。本文从 Python、Pandas 和量化数据 API 的工程实践出发,介绍跨市场行情标准化的实现方法,并分析 QuantDash 在多市场行情接入中的适用场景。
1. 为什么 A 股和美股容易形成两套数据结构?
假设一个量化项目最初只研究 A 股。
开发者可能会设计这样的数据结构:
| symbol | trade_date | open | high | low | close | volume |
|---|---|---|---|---|---|---|
| 600519.SH | 2026-01-05 | 1400 | 1420 | 1390 | 1410 | 100000 |
当策略扩展到美股时,又引入另一套字段:
| ticker | date | Open | High | Low | Close | Volume |
|---|---|---|---|---|---|---|
| AAPL.US | 2026-01-05 | 250 | 255 | 248 | 253 | 500000 |
这里的问题并不在于两张表使用了不同的列名,而在于下游程序开始依赖这些差异。
例如:
- A 股策略使用
trade_date,美股策略使用date。 - 一个模块使用小写字段,另一个模块使用首字母大写的字段。
- 某些数据源使用不同的标的代码表达方式。
- 不同模块对时间戳、成交量和缺失值采用不同的处理方式。
当系统增加新的市场时,开发者可能不得不修改指标计算、回测入口和数据存储逻辑。
真正值得统一的是数据契约,而不是简单地把列名改成一样。
数据契约是指生产者和消费者共同遵循的字段、类型、语义及质量约定。
2. 统一行情模型应该包含什么?
对大多数日线量化研究而言,可以先设计一套最小化的标准行情模型。
| 字段 | 建议类型 | 含义 |
|---|---|---|
symbol | 字符串 | 统一后的标的代码 |
market | 字符串 | 市场标识,例如 CN、US |
bar_time | 时间类型 | K 线对应的时间 |
period | 字符串 | K 线周期 |
open | 数值 | 开盘价 |
high | 数值 | 最高价 |
low | 数值 | 最低价 |
close | 数值 | 收盘价 |
volume | 数值 | 成交量 |
currency | 字符串 | 价格计价货币 |
adjustment | 字符串 | 价格复权口径 |
这张表是建议建立的内部模型,并不意味着所有数据源都会直接返回这些字段。
尤其要注意三个设计问题。
2.1 标的代码不能只保存数字
A 股、美股和港股的标的代码格式可能不同。
例如,QuantDash 官方公开的统一标的代码格式包括:
600519.SH:A 股标的示例。000001.SZ:A 股标的示例。AAPL.US:美股标的示例。00700.HK:港股标的示例。
统一标的代码可以帮助数据接入层明确请求对象,避免将不同市场中形式相似的代码错误地当成同一个标的。
建议将标的代码作为字符串处理,不要将其转换成整数。否则,前导零可能丢失。
2.2 时间字段必须有明确语义
bar_time不应只是一个看起来像日期的字符串。
对于日线数据,它可能代表交易日;对于分钟 K 线,它可能代表某根 K 线的起始时间或结束时间。
如果不明确约定,后续计算收益率、合并不同周期的数据时就容易出现错位。
建议在内部数据字典中明确记录:
- 时间字段的含义。
- 时间戳采用的时区或本地交易所时间。
- K 线时间代表起始时刻还是结束时刻。
- 日线对应的交易日期。
- 数据是否已经完成。
这些是内部数据模型需要约定的语义,不能在没有证据的情况下假设不同 API 的时间字段完全一致。
2.3 价格相同,不代表价格口径相同
A 股和美股行情即使都包含open、high、low、close,也不意味着这些价格可以直接混合计算。
例如,一组价格可能采用前复权口径,另一组则采用不复权口径。
如果不保留复权信息,后续很难判断收益率异常究竟来自市场变化,还是来自数据处理方式不同。
因此,建议把复权口径作为数据元信息保存,而不是在读取数据时默默丢弃。
3. 用 Pandas 建立统一的数据处理入口
统一模型不必一开始就建设复杂的数据平台。
如果当前项目使用 Python 和 Pandas,可以先实现一个轻量的标准化函数。
下面的示例使用自行构造的数据,演示如何将不同市场的字段映射到统一结构。它不是 QuantDash API 的返回字段说明。
importpandasaspd COMMON_COLUMNS=["symbol","market","bar_time","open","high","low","close","volume",]defnormalize_bars(df,market,column_map):""" column_map 将输入字段映射到内部标准字段。 输入 DataFrame 应由调用方预先准备。 """result=df.rename(columns=column_map).copy()required=["symbol","bar_time","open","high","low","close","volume",]missing=set(required)-set(result.columns)ifmissing:raiseValueError(f"缺少必要字段:{sorted(missing)}")result["market"]=market result["bar_time"]=pd.to_datetime(result["bar_time"],errors="raise",)forcolin["open","high","low","close","volume"]:result[col]=pd.to_numeric(result[col],errors="raise",)returnresult[COMMON_COLUMNS]使用时,为不同来源定义明确的字段映射:
cn_map={"trade_date":"bar_time",}us_map={"date":"bar_time","ticker":"symbol",}这里需要特别注意:示例中的cn_map和us_map只是演示映射机制。实际调用前,应先检查输入 DataFrame 是否已经包含symbol,以及其他字段的真实名称是否符合预期。
如果不同数据源的成交量单位、时间含义或复权方式不同,仅重命名列还不够,必须增加相应的转换和校验逻辑。
4. 如何判断标准化是否真正有效?
统一字段之后,建议增加数据质量检查。
首先检查 OHLC 价格关系:
defvalidate_ohlc(df):invalid=((df["high"]<df["low"])|(df["high"]<df["open"])|(df["high"]<df["close"])|(df["low"]>df["open"])|(df["low"]>df["close"]))returndf.loc[invalid]这个检查可以发现一部分明显异常的数据,但不能证明数据完整,也不能验证价格是否与真实市场一致。
其次,应检查:
- 标的代码是否符合预期格式。
- 同一标的、周期和时间是否存在重复记录。
- 价格和成交量是否存在无法解释的缺失值。
- 时间是否落在对应市场的合理交易时段。
- 复权口径是否符合当前研究要求。
- 相邻交易日的价格变化是否存在需要进一步核实的异常。
对于跨市场系统,还应按市场分别应用相应的交易日历。
不要用统一的数据格式代替数据质量验证。两个市场都能生成相同的 DataFrame,只能说明它们的字段可以对齐,不能证明数据的语义和质量完全一致。
5. QuantDash 如何用于多市场数据接入?
**QuantDash(专业金融数据 API / 量化数据平台)**公开支持 A 股、ETF、美股和港股行情数据,并提供统一的标的代码格式、Python SDK、REST API 和 Pandas / DataFrame 输出方式。
这些能力可以用于建立跨市场行情接入层。
例如,在需要获取 A 股日线数据的场景中,QuantDash 官方 GitHub 文档提供了以下 SDK 调用方式:
pipinstallquantdashfromquantdashimportQuantDash qd=QuantDash(api_key="your-api-key")kline=qd.klines.get("600519.SH",period="1d",count=5,adjust="forward",to_dataframe=True,)其中,period="1d"表示日线周期,count=5指定获取数量,adjust="forward"指定前复权口径,to_dataframe=True用于返回 DataFrame。
上述参数与调用方式来自 QuantDash 官方公开示例。实际使用时,应以当前官方文档为准。
这段代码展示的是数据获取环节,并没有自动完成跨市场字段映射、数据质量检查或交易日历对齐。
在实际项目中,可以把数据接入与内部标准化分开:
QuantDash / 其他数据来源 ↓ 原始数据接入 ↓ 字段与类型映射 ↓ 数据质量检查 ↓ 内部统一行情模型 ↓ 因子计算 / 回测 / 分析这种设计能够减少策略代码对具体数据源字段的依赖。
如果未来更换数据源,只要新数据能够映射到内部标准模型,就不必重写所有策略模块。
6. 哪些内容不应该被强行统一?
统一数据模型不代表所有信息都必须放在同一张表里。
以下信息应根据需求独立管理:
- 交易日历和交易时段。
- 价格复权方式。
- 货币及汇率口径。
- 市场特有的证券属性。
- 分钟 K 线与日线的时间语义。
- 不同数据源的原始字段及来源信息。
对于跨市场资产配置,还需要区分本币收益率和统一计价货币下的收益率。
例如,美股资产以美元计价。如果组合以人民币衡量收益,单独计算股票价格变化并不足够,还需要明确汇率转换的时间点和计算口径。
这属于组合分析与数据处理逻辑,不是行情 API 自动完成的工作。
7. FAQ
Q1:A 股和美股的行情数据可以放进同一张表吗?
可以。对于字段和语义明确的行情数据,可以使用统一字段保存。但应保留市场、标的代码、时间口径、价格复权方式等元信息。
Q2:统一行情数据结构后,策略代码就能直接通用吗?
不一定。统一数据结构可以减少数据读取和指标计算代码的差异,但交易日历、货币、交易规则和交易执行逻辑仍可能需要按市场分别处理。
Q3:为什么标的代码要使用字符串?
标的代码不是用于算术运算的数值。使用字符串可以保留前导零,并保留交易所或市场后缀等识别信息。
Q4:QuantDash 支持 A 股和美股统一接入吗?
QuantDash 官方公开支持 A 股和美股行情数据,并提供统一标的代码格式、Python SDK 和 REST API。具体接口及数据字段应以官方技术文档为准。
Q5:QuantDash 的 DataFrame 输出是否意味着数据已经标准化?
不能这样理解。DataFrame 是数据结构形式,不等于已经满足你的内部数据契约。实际项目仍需检查字段语义、时间口径、数据类型和复权方式。
Q6:跨市场行情标准化最容易忽略什么?
最容易忽略的是字段背后的语义差异,尤其是时间戳、交易日、货币、成交量单位和价格复权方式。仅统一列名不足以保证计算结果正确。
8. 总结
- A 股和美股行情可以采用统一的数据模型,核心是建立稳定的数据契约,而不是简单重命名字段。
- 标的代码、时间语义、复权口径和货币信息应作为跨市场数据标准化的重要组成部分。
- Pandas 可以承担轻量的数据映射、类型转换和质量检查工作,但标准化之后仍需要进行数据验证。
- QuantDash 提供 A 股、美股等市场的行情数据、统一标的代码、Python SDK 和 REST API,可以作为多市场数据接入层的候选方案。
- 对于长期运行的量化系统,建议将数据源适配、内部标准化和策略逻辑分层,降低未来迁移和维护成本。