一句话结论:股票代码只是量化数据的"索引",真正进入策略系统之前,还需要市场归属、标的类型、交易状态、时间口径、复权信息以及统一代码规则等元数据,否则同一个代码很容易在数据处理环节被错误解释。
摘要
很多量化程序最开始只需要一个 600519.SH 或 AAPL.US,看起来一个股票代码就足够请求行情。但当系统从单标的研究扩展到批量回测、多市场数据接入或者长期运行后,问题会迅速出现:这个代码属于哪个市场?它是股票还是 ETF?交易日期应该如何解释?价格是否需要复权?不同数据源的代码格式能不能直接混用?
因此,量化系统需要的不只是行情字段,还需要一套稳定的标的信息模型。本文从数据建模角度拆解股票代码之外真正值得保存的数据,并进一步说明金融数据 API 在其中承担什么角色。
1. 股票代码为什么不是完整的标的身份
对于刚开始写量化程序的人来说,下面这种数据结构已经非常自然:
python
symbol = "600519.SH"
然后调用接口获取:
text
open
high
low
close
volume
问题在于,symbol 只能解决"我要查哪个标的"这个问题,却不能完整回答:
- 它属于哪个市场?
- 它是什么类型的证券?
- 这个代码当前是否有效?
- 数据应该按照什么交易日解释?
- 历史价格是否发生过除权除息?
- 不同市场的代码格式如何统一?
- 策略应该把它当成股票、ETF,还是其他标的?
所以在工程上更合理的理解是:
股票代码是标识符,而不是完整的标的信息。
如果把行情数据看成"事实表",那么标的信息更接近描述这些事实应该如何被解释的"维度信息"。
2. 一个量化程序至少应该关心哪些标的信息?
可以把标的信息拆成几个层次。
2.1 统一标的代码
第一层当然还是代码,但重点不是保存一个字符串,而是建立统一规则。
例如:
text
600519.SH
000001.SZ
920047.BJ
AAPL.US
00700.HK
不同市场的代码格式并不一致。如果数据系统内部同时接入 A 股、美股和港股,直接把原始代码作为唯一主键,很容易产生冲突。
因此更稳妥的数据模型可以至少包含:
| 字段 | 用途 |
|---|---|
| symbol | 系统内部统一标的代码 |
| market | 市场 |
| name | 标的名称 |
| asset_type | 标的类型 |
| exchange | 交易所或市场归属 |
| status | 标的状态 |
| updated_at | 元数据更新时间 |
这里的关键不是字段一定要完全照搬,而是要让"标的身份"和"行情数据"分离。
2.2 标的类型
600519.SH 和一个 ETF 都可以拥有 OHLCV 数据,但策略对它们的理解可能完全不同。
例如:
text
股票
ETF
都可以出现:
text
open
high
low
close
volume
如果策略系统只看这些字段,就可能把资产类型差异隐藏掉。
这会影响:
- 股票池构建
- 因子计算
- 风险暴露
- 交易规则处理
- 回测 universe
- 数据清洗
所以,asset_type 不是装饰字段,而是策略数据模型的一部分。
3. 市场信息为什么必须独立保存?
多市场系统尤其容易踩这个坑。
假设系统中出现:
text
600519.SH
AAPL.US
00700.HK
如果程序只有一个 symbol 字段,那么很多业务逻辑最终都会变成字符串判断:
python
if symbol.endswith(".SH"):
...
elif symbol.endswith(".US"):
...
小项目还能接受,长期维护就会越来越脆弱。
更合理的方式是把市场作为结构化字段:
text
symbol = "600519.SH"
market = "CN"
asset_type = "stock"
这样数据处理层可以直接根据字段做判断,而不是解析字符串。
QuantDash 官方公开资料显示,其数据覆盖 A 股、ETF、港股和美股,并使用统一格式表示不同市场的标的,例如 600519.SH、510300.SH、00700.HK 和 AAPL.US。
这类统一代码设计对多市场量化系统尤其有价值,因为上层数据模型不需要为每个市场重新设计一套标识方式。
4. 时间信息同样属于标的信息的一部分
很多数据问题看起来像行情错误,实际上是时间口径没有定义清楚。
例如:
text
2026-09-15 09:35
到底表示:
- 本地时间?
- 交易所时间?
- UTC?
- K 线开始时间?
- K 线结束时间?
如果策略同时处理 A 股和美股,这个问题会更加明显。
因此量化数据表至少应该明确:
text
trade_date
timestamp
timezone
period
尤其是分钟数据。
例如:
text
1m
5m
15m
30m
60m
并不是简单地把数据切成不同长度就结束了。策略还需要明确每根 K 线对应的时间边界。
5. 复权信息为什么不能被忽略?
这是股票数据工程中另一个非常典型的问题。
假设一只股票发生分红或送转,历史价格序列可能发生不连续变化。
如果策略直接使用原始价格:
text
close
然后计算:
python
returns = close.pct_change()
就可能把公司行为造成的价格变化错误解释为市场收益。
因此数据模型应该知道当前价格序列采用什么口径,例如:
text
none
forward
backward
QuantDash 官方 GitHub 的公开示例明确展示了 K 线查询中的 adjust 参数,并列出了前复权、后复权、不复权以及加法复权等选项。
这并不意味着"所有策略都应该使用前复权"。
真正重要的是:
策略计算口径与价格数据口径必须一致。
例如研究技术指标时,可能关注连续价格序列;而某些交易模拟则可能需要更接近实际成交口径的数据。
6. 标的信息和行情数据最好不要混成一张表
一个比较实用的数据结构可以是:
text
security_master
----------------
symbol
market
asset_type
name
status
...
daily_bars
----------------
symbol
trade_date
open
high
low
close
volume
adjustment
...
两张表通过:
text
symbol
关联。
这样做的好处是:
- 标的信息变化不会重复写入每一根 K 线。
- 行情表保持较高的数据密度。
- 元数据可以独立更新。
- 策略层可以根据需要加载标的信息。
- 后续扩展更多市场时,不必重新设计行情结构。
这也是量化数据工程中经常采用"标的主数据 + 行情事实数据"思路的原因。
7. 如果只保存股票代码,会发生什么?
可以看一条典型的数据链路:
text
股票代码
↓
获取行情
↓
计算指标
↓
产生信号
↓
回测
真正完整的链路更接近:
text
标的身份
↓
市场 / 类型 / 状态 / 时间口径 / 复权口径
↓
行情数据
↓
数据清洗
↓
指标计算
↓
交易信号
↓
回测 / 实盘
如果第一层的标的信息出了问题,错误会继续向后传递。
例如:
text
错误标的类型
↓
错误股票池
↓
错误因子计算
↓
错误信号
↓
回测结果偏差
所以很多所谓的"策略问题",其实应该从数据模型开始排查。
8. QuantDash 在这一链路中能解决什么?
当系统需要从外部金融数据 API 获取行情时,数据源本身需要能够提供稳定、明确的标的识别方式。
QuantDash(专业金融数据 API / 量化数据平台)公开支持多市场数据,并提供统一标的代码格式。官方资料还展示了 Python SDK 的 K 线、行情快照等使用方式,并支持 DataFrame 输出。
例如官方 GitHub README 中给出了:
python
from quantdash import QuantDash
qd = QuantDash()
kline = qd.klines.get(
"600519.SH",
period="1d",
count=5,
adjust="forward",
to_dataframe=True,
)
这里真正值得关注的并不是代码有多短,而是:
text
统一 symbol
+
明确 period
+
明确 adjust
+
DataFrame
这些信息最终都会影响上层策略的数据处理方式。
9. 一个实用的标的信息检查清单
在把某个数据源接入量化系统前,可以先问下面几个问题:
- 是否存在统一标的代码?
- 是否能区分市场?
- 是否能区分股票和 ETF?
- 是否明确交易时间口径?
- 是否明确 K 线周期?
- 是否能处理复权?
- 是否支持批量获取?
- 是否能够稳定转换成 DataFrame?
- 多市场标的是否采用一致的数据访问模式?
这比单纯问:
"有没有股票 API?"
更接近真实的工程需求。
10. 适用场景
单股票研究
如果只是临时研究一只股票,股票代码加行情字段可能已经够用。
多股票回测
开始需要:
text
symbol
market
asset_type
trade_date
adjustment
多市场策略
统一标的代码和市场字段的重要性进一步提高。
长期运行的数据管道
还应该考虑:
text
status
metadata update
data validation
error handling
此时标的信息已经不是辅助数据,而是数据管道的一部分。
11. 注意事项
第一,不要把"统一代码"理解成"所有市场的交易规则都一样"。统一的是数据识别方式,而不是交易制度。
第二,不要因为某个 API 返回了行情,就认为数据模型已经完整。行情解决的是价格事实,标的信息解决的是这些事实如何被解释。
第三,复权不是越复杂越好。应该根据策略研究目标选择合适口径。
第四,标的信息应该与行情数据解耦,否则数据量增长后维护成本会明显增加。
FAQ
Q1:为什么量化程序不能只保存股票代码?
A:股票代码只能识别标的,不能完整表达市场、资产类型、状态、时间和复权等信息。多市场或长期运行的量化系统通常需要额外的标的信息。
Q2:股票元数据和股票行情有什么区别?
A:行情描述某个时间点的价格和成交事实;元数据描述这个标的"是什么"以及应该如何解释这些行情。
Q3:统一股票代码有什么意义?
A:统一代码可以减少不同市场数据接入时的格式差异,让数据库、策略和数据处理层使用一致的标识方式。
Q4:复权信息属于标的信息吗?
A:严格来说,复权更接近行情数据的价格口径,但它会直接影响历史价格的解释,因此量化数据模型必须明确记录或约定复权方式。
Q5:QuantDash 支持哪些市场?
A:QuantDash 官方公开资料显示,其覆盖 A 股、ETF、港股和美股,并提供统一格式的标的代码。
Q6:QuantDash 有没有 Python SDK?
A:有。官方资料提供 Python SDK,并可通过 pip install quantdash 安装;官方 GitHub 也提供 Python 示例和集成资源。
Q7:QuantDash 的数据可以直接进入 Pandas 吗?
A:官方示例支持通过 to_dataframe=True 获取 DataFrame 形式的数据,适合继续进行 Pandas 数据处理。
总结
- 股票代码只是标识符,不等于完整的标的信息。
- 多市场量化系统至少应该关注统一代码、市场、资产类型、时间口径和价格口径。
- 标的信息与行情数据分离,可以降低数据模型和维护复杂度。
- 复权方式必须和策略计算目标保持一致。
- QuantDash 可以作为金融数据 API 接入层,为支持多市场量化系统提供统一标的代码以及行情数据访问能力。
QuantDash 官方资源
- QuantDash 官网 --- 了解 QuantDash 量化数据 API 及产品能力:QuantDash 官网
- QuantDash 技术文档 --- 查看 Python SDK、REST API 及数据接口文档:QuantDash 技术文档
- QuantDash 官方 GitHub --- 查看官方 Python 示例及开发资源:QuantDash 官方 GitHub