libfinance 0.1.2__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- libfinance-0.1.3/PKG-INFO +228 -0
- libfinance-0.1.3/README.md +215 -0
- libfinance-0.1.3/VERSION +1 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/exfactor.py +1 -1
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/get_price.py +2 -2
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/index_components.py +1 -1
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/instrument.py +4 -4
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/live_quote.py +7 -4
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/subscribe/md_protocol.py +71 -115
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/subscribe/quote_api.py +14 -16
- libfinance-0.1.3/libfinance.egg-info/PKG-INFO +228 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/test/test_client_api_contract.py +9 -9
- {libfinance-0.1.2 → libfinance-0.1.3}/test/test_subscribe_live.py +25 -15
- libfinance-0.1.2/PKG-INFO +0 -170
- libfinance-0.1.2/README.md +0 -157
- libfinance-0.1.2/VERSION +0 -1
- libfinance-0.1.2/libfinance.egg-info/PKG-INFO +0 -170
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/__init__.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/__init__.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/calendar.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/corporate_actions.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/factors.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/financials.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/industry.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/shares.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/api/theme.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/client.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/subscribe/__init__.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/utils/__init__.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/utils/cache.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/utils/datetime_func.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/utils/decorators.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/utils/utils.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance/utils/validators.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance.egg-info/SOURCES.txt +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance.egg-info/dependency_links.txt +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance.egg-info/requires.txt +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/libfinance.egg-info/top_level.txt +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/pyproject.toml +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/setup.cfg +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/setup.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/test/test_client_reconnect.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/test/test_contract.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/test/test_docs_contract.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/test/test_rpc_contract.py +0 -0
- {libfinance-0.1.2 → libfinance-0.1.3}/test/test_version.py +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: libfinance
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: libfinance is a modern finance API
|
|
5
|
+
Description-Content-Type: text/markdown
|
|
6
|
+
Requires-Dist: lz4
|
|
7
|
+
Requires-Dist: msgpack
|
|
8
|
+
Requires-Dist: pandas
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
Requires-Dist: pyarrow
|
|
11
|
+
Requires-Dist: six
|
|
12
|
+
Requires-Dist: python-dateutil
|
|
13
|
+
|
|
14
|
+
<div align="center">
|
|
15
|
+
|
|
16
|
+
<picture>
|
|
17
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/StateOfTheArt-quant/libfinance/main/docs/_shared/_static/img/libfinance_logo_dark.svg">
|
|
18
|
+
<img alt="libfinance" src="https://raw.githubusercontent.com/StateOfTheArt-quant/libfinance/main/docs/_shared/_static/img/libfinance_logo.svg" width="300">
|
|
19
|
+
</picture>
|
|
20
|
+
|
|
21
|
+
**面向量化研究与回测的金融数据接口 —— A 股与美股一套术语,Python 与 C++ 一套函数**
|
|
22
|
+
|
|
23
|
+
[](https://pypi.org/project/libfinance/)
|
|
24
|
+
[](https://libfinance.readthedocs.io/zh-cn/latest/)
|
|
25
|
+
[](https://libfinance.readthedocs.io/en/latest/)
|
|
26
|
+
|
|
27
|
+
[📘 中文文档](https://libfinance.readthedocs.io/zh-cn/latest/) ·
|
|
28
|
+
[📗 English documentation](https://libfinance.readthedocs.io/en/latest/) ·
|
|
29
|
+
[💻 示例代码](https://github.com/StateOfTheArt-quant/libfinance/tree/main/example) ·
|
|
30
|
+
[🚀 快速开始](https://libfinance.readthedocs.io/zh-cn/latest/getting_started/quickstart.html) ·
|
|
31
|
+
[🧭 概念设计](https://libfinance.readthedocs.io/zh-cn/latest/concepts/security_identifiers.html) ·
|
|
32
|
+
[📑 API 参考](https://libfinance.readthedocs.io/zh-cn/latest/reference/contracts.html)
|
|
33
|
+
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
量化研究的结论依赖历史数据,而历史数据有三类常见的失真:证券代码会更名、复用,不同市场之间还会重号;财务报表在披露后会被修订,回测若读取最新版本,就用上了当时无从获得的信息;分红、拆股等公司行动改变价格的可比性,复权口径不一致会直接扭曲收益。研究与生产又常常分别使用 Python 与 C++,两套接口的细微差别会让同一策略在迁移后得到不同的结果。
|
|
39
|
+
|
|
40
|
+
`libfinance` 是面向量化研究与回测的金融数据客户端,覆盖 A 股与美股,提供 Python 与 C++ 两种实现。它以统一的证券标识、按时点(point-in-time)的数据版本和逐事件计算的复权因子组织行情、证券目录、交易日历、公司行动、股本、财务、行业 / 指数 / 主题成分与日频因子等数据;两个市场、两种语言遵循同一份接口契约,调用方式一致,差异只来自数据本身。
|
|
41
|
+
|
|
42
|
+
数据设计的四条约定:
|
|
43
|
+
|
|
44
|
+
- **统一的证券标识符** —— `<trading_code>.<namespace>`,如 `600000.XSHG`、`000001.XSHE`、`AAPL.US`。命名空间区分不同市场的同号代码,代码按历史时点解析,更名与代码复用不会串到别的证券。
|
|
45
|
+
- **point-in-time 机制 `as_of`** —— 按历史时点还原证券池、选取当时已披露的财务版本,避免未来信息与幸存者偏差。
|
|
46
|
+
- **高质量的复权因子 `exfactor`** —— 由公司行动逐事件计算,提供不复权、前复权、后复权三种口径;`get_ex_factor` 给出单次与累计因子,价格的每一次调整都可追溯。
|
|
47
|
+
- **Python 与 C++ 统一的函数设计** —— 两种客户端按同一份契约(`contract/contract.json`)实现,函数名、参数顺序与默认值、校验与报错、返回的列一一对应;同一组调用经两种客户端发给同一服务端逐项比对。
|
|
48
|
+
|
|
49
|
+
## 安装
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install libfinance
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
从源码安装:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/StateOfTheArt-quant/libfinance.git
|
|
59
|
+
cd libfinance/python
|
|
60
|
+
pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> [!TIP]
|
|
64
|
+
> **使用 C++?** C++ 客户端与 Python 版函数一一对应,通过 CMake `FetchContent` 引入项目,依赖 Apache Arrow C++。安装、构建与示例见 [cpp/README.md](https://github.com/StateOfTheArt-quant/libfinance/blob/main/cpp/README.md)。
|
|
65
|
+
|
|
66
|
+
## 快速开始
|
|
67
|
+
|
|
68
|
+
按[安装与连接说明](https://libfinance.readthedocs.io/zh-cn/latest/getting_started/installation.html)配置服务后即可查询。以下输出均为真实运行结果,数据持续更新,行数与数值可能不同。
|
|
69
|
+
|
|
70
|
+
**证券目录** —— 两个市场在同一张表里,列相同:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from libfinance import all_instruments
|
|
74
|
+
|
|
75
|
+
stocks = all_instruments(type="stock")
|
|
76
|
+
stocks.set_index("order_book_id").loc[
|
|
77
|
+
["600000.XSHG", "000001.XSHE", "AAPL.US", "NVDA.US"], ["market", "exchange", "name"]]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
market exchange name
|
|
82
|
+
order_book_id
|
|
83
|
+
600000.XSHG CN XSHG 浦发银行
|
|
84
|
+
000001.XSHE CN XSHE 平安银行
|
|
85
|
+
AAPL.US US XNAS Apple Inc. - Common Stock
|
|
86
|
+
NVDA.US US XNAS NVIDIA Corporation - Common Stock
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**交易日** —— 区间按自然日给,返回其中的交易日(美股传 `market="us"`):
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from libfinance import get_trading_dates
|
|
93
|
+
|
|
94
|
+
get_trading_dates("2024-05-11", "2024-05-20")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
DatetimeIndex(['2024-05-13', '2024-05-14', '2024-05-15', '2024-05-16',
|
|
99
|
+
'2024-05-17', '2024-05-20'],
|
|
100
|
+
dtype='datetime64[us]', freq=None)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**行情** —— 一次调用混查两个市场;美股没有涨跌停,`limit_up` 为 `NaN`,表结构不变:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from libfinance import get_price
|
|
107
|
+
|
|
108
|
+
get_price(["600000.XSHG", "AAPL.US"], "2024-03-01", "2024-03-05",
|
|
109
|
+
fields=["open", "close", "volume", "limit_up"], adjust_type="none")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
open close volume limit_up
|
|
114
|
+
order_book_id datetime
|
|
115
|
+
600000.XSHG 2024-03-01 7.13 7.11 29431801 7.87
|
|
116
|
+
2024-03-04 7.12 7.07 27855963 7.82
|
|
117
|
+
2024-03-05 7.05 7.16 41756232 7.78
|
|
118
|
+
AAPL.US 2024-03-01 179.55 179.66 73563100 NaN
|
|
119
|
+
2024-03-04 176.15 175.10 81510101 NaN
|
|
120
|
+
2024-03-05 170.76 170.12 95132400 NaN
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`adjust_type="none"` 取当天的真实成交价;不传时默认前复权(`"pre"`),见[价格口径](https://libfinance.readthedocs.io/zh-cn/latest/data/price.html)。
|
|
124
|
+
|
|
125
|
+
**因子** —— 库名 `system/alpha158` 展开为 158 个因子,每个因子一列:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from libfinance import get_factor_exposure
|
|
129
|
+
|
|
130
|
+
f = get_factor_exposure(["600000.XSHG", "000001.XSHE"], "system/alpha158", "2026-09-07", "2026-09-10")
|
|
131
|
+
f.iloc[:, :6].rename(columns=lambda c: c.rsplit("/", 1)[1]).round(4) # 前 6 列,列名只留因子名
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
KMID KLEN KMID2 KUP KUP2 KLOW
|
|
136
|
+
order_book_id date
|
|
137
|
+
600000.XSHG 2026-09-07 -0.0212 0.0286 -0.7407 0.0032 0.1111 0.0042
|
|
138
|
+
2026-09-08 0.0076 0.0141 0.5385 0.0065 0.4615 0.0000
|
|
139
|
+
2026-09-09 -0.0022 0.0086 -0.2500 0.0043 0.5000 0.0022
|
|
140
|
+
2026-09-10 0.0141 0.0184 0.7647 0.0011 0.0588 0.0033
|
|
141
|
+
000001.XSHE 2026-09-07 -0.0143 0.0194 -0.7391 0.0008 0.0435 0.0042
|
|
142
|
+
2026-09-08 0.0103 0.0137 0.7500 0.0026 0.1875 0.0009
|
|
143
|
+
2026-09-09 -0.0051 0.0085 -0.6000 0.0026 0.3000 0.0009
|
|
144
|
+
2026-09-10 0.0146 0.0171 0.8500 0.0009 0.0500 0.0017
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
逐步说明见[快速开始](https://libfinance.readthedocs.io/zh-cn/latest/getting_started/quickstart.html)。
|
|
148
|
+
|
|
149
|
+
## A 股与美股共用一套术语
|
|
150
|
+
|
|
151
|
+
统一体现在三个层面。
|
|
152
|
+
|
|
153
|
+
| 层面 | 统一的内容 | 例 |
|
|
154
|
+
| --- | --- | --- |
|
|
155
|
+
| 证券标识 | 写法都是 `<trading_code>.<namespace>`;命名空间的粒度取决于该市场消除歧义所需的范围 | `600000.XSHG`、`AAPL.US` |
|
|
156
|
+
| 函数与参数 | 两个市场调用同一组函数,参数名相同,`as_of` 与 `adjust_type` 的含义一致 | `get_price`、`instruments`、`get_dividends` |
|
|
157
|
+
| 返回结构 | 列名与索引一致;某个市场不适用或未提供的字段取 `NaN`,不另设一张表 | 美股的 `turnover`、`limit_up`、`limit_down` |
|
|
158
|
+
|
|
159
|
+
需要显式指定市场的,只有不涉及具体证券的查询:交易日历、全市场目录、数据覆盖范围。按证券查询时,命名空间已经给出了市场信息,列表里也可以混合两个市场的代码。
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from libfinance import instruments, get_trading_dates
|
|
163
|
+
|
|
164
|
+
instruments(["000001.XSHE", "AAPL.US"]) # 命名空间已给出市场
|
|
165
|
+
get_trading_dates("2024-01-01", "2024-01-31", market="us") # 不涉及具体证券
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
统一的是术语和调用约定,数据本身的差异依然存在。下表的「市场」一列标出了每类数据实际覆盖的市场,逐个接口的情况见[查美股](https://libfinance.readthedocs.io/zh-cn/latest/howto/us_market.html)。
|
|
169
|
+
|
|
170
|
+
## 数据覆盖
|
|
171
|
+
|
|
172
|
+
| 数据 | 市场 | 主要函数 | 说明 |
|
|
173
|
+
| --- | --- | --- | --- |
|
|
174
|
+
| 交易日历 | CN · US | `get_trading_dates` | 交易日、区间取日、前后推 N 个交易日 |
|
|
175
|
+
| 证券目录 | CN · US | `all_instruments`、`instruments` | 股票、指数、行业、主题;代码、名称、上市与退市日期 |
|
|
176
|
+
| 日频行情 | CN · US | `get_price` | 开高低收、成交量额、涨跌停价,可复权 |
|
|
177
|
+
| 复权因子 | CN · US | `get_ex_factor` | 逐除权日的单次及累计因子 |
|
|
178
|
+
| 股本 | CN · US | `get_shares` | 逐交易日的总股本与流通股本 |
|
|
179
|
+
| 分红 / 拆股 / 配股 | CN · US | `get_dividends`、`get_splits`、`get_allotments` | 除权事件;配股只有 A 股 |
|
|
180
|
+
| 分拆 | US | `get_spinoffs` | A 股不产生这类事件 |
|
|
181
|
+
| 财务报表(PIT) | CN · US | `get_pit_financials_ex` | 按季度取,带修订历史 |
|
|
182
|
+
| 财务衍生指标 | CN · US | `get_financial_metrics` | 按交易日的财务衍生指标 |
|
|
183
|
+
| 行业分类 | CN · US | `get_instrument_industry`、`get_industry_constituents`、`get_industry_weights` | 申万、GICS 等分类体系 |
|
|
184
|
+
| 指数成分与权重 | CN · US | `get_index_constituents`、`get_index_weights` | 中证、标普等 |
|
|
185
|
+
| 主题成分与权重 | CN | `get_theme_constituents`、`get_theme_weights` | THS 主题 |
|
|
186
|
+
| 日频因子 | CN | `get_factor_exposure`、`list_factor_libraries`、`list_factors` | alpha158、qlib,Barra CNE5 风格 / 行业因子,CNE5 与 CNE6 描述符;见[因子数据](https://libfinance.readthedocs.io/zh-cn/latest/data/factors.html)与[因子字典](https://libfinance.readthedocs.io/zh-cn/latest/reference/factor_dictionary.html) |
|
|
187
|
+
| 实时行情 | CN | `get_last_quotes`、`QuoteApi` | 最新快照与订阅推送 |
|
|
188
|
+
|
|
189
|
+
覆盖到哪一年、更新到哪一天,取决于你连的那个服务。**不要照抄文档里的日期**,用[数据新鲜度](https://libfinance.readthedocs.io/zh-cn/latest/data/freshness.html)里的两个函数自己查。
|
|
190
|
+
|
|
191
|
+
## 概念设计
|
|
192
|
+
|
|
193
|
+
| 主题 | 解决的问题 |
|
|
194
|
+
| --- | --- |
|
|
195
|
+
| [统一的证券标识符](https://libfinance.readthedocs.io/zh-cn/latest/concepts/security_identifiers.html) | 区分市场、证券身份及历史代码,准确关联不同数据 |
|
|
196
|
+
| [point-in-time 机制 as_of](https://libfinance.readthedocs.io/zh-cn/latest/concepts/point_in_time.html) | 还原历史证券池与可见财报,避免未来信息和幸存者偏差 |
|
|
197
|
+
| [高质量的复权因子 exfactor](https://libfinance.readthedocs.io/zh-cn/latest/concepts/exfactor.html) | 理解公司行动对价格的影响,以及三种价格口径的计算和用途 |
|
|
198
|
+
| [Python 与 C++ 统一的函数设计](https://libfinance.readthedocs.io/zh-cn/latest/concepts/python_cpp.html) | 一份契约约束两种客户端:函数、参数、报错与返回列一一对应,并逐项核对 |
|
|
199
|
+
|
|
200
|
+
## 文档与示例
|
|
201
|
+
|
|
202
|
+
| | |
|
|
203
|
+
| --- | --- |
|
|
204
|
+
| [📘 中文文档](https://libfinance.readthedocs.io/zh-cn/latest/) | 概念设计、数据说明、操作指南与 API 参考 |
|
|
205
|
+
| [📗 English documentation](https://libfinance.readthedocs.io/en/latest/) | The same documentation tree in English |
|
|
206
|
+
| [💻 示例代码](https://github.com/StateOfTheArt-quant/libfinance/tree/main/example) | 按数据族排序的可运行示例(Python 与 C++ 一一对应),与 API 参考对照阅读 |
|
|
207
|
+
| [🧩 操作指南](https://libfinance.readthedocs.io/zh-cn/latest/howto/index.html) | 取行情面板、PIT 回测、订阅实时行情等成套做法 |
|
|
208
|
+
| [🩺 故障排查](https://libfinance.readthedocs.io/zh-cn/latest/howto/troubleshooting.html) | 按**症状**编排:看到什么现象,就从哪一行开始 |
|
|
209
|
+
|
|
210
|
+
API 参考按合约信息和交易日历、行情、基本面、行业与指数和主题、公司行动、实时行情、因子分组,每个函数附 Python 与 C++ 两种写法的示例及其真实输出。
|
|
211
|
+
|
|
212
|
+
## 社区
|
|
213
|
+
|
|
214
|
+
问题与需求请提 [Issue](https://github.com/StateOfTheArt-quant/libfinance/issues)。关注公众号获取更新:
|
|
215
|
+
|
|
216
|
+
<div align="center">
|
|
217
|
+
<img alt="微信公众号二维码" src="https://raw.githubusercontent.com/StateOfTheArt-quant/libfinance/main/docs/_shared/_static/img/code.png" width="600" height="220">
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
## 仓库结构
|
|
221
|
+
|
|
222
|
+
| 目录 | 内容 |
|
|
223
|
+
| --- | --- |
|
|
224
|
+
| `contract/` | 各语言客户端共同遵守的契约:公开函数(名称、参数顺序与默认值、返回)与它们调用的服务端函数 |
|
|
225
|
+
| `contract/conformance/` | 同一组调用分别经 Python 与 C++ 客户端发给同一个服务端,逐项比对答案 |
|
|
226
|
+
| `python/` | Python 客户端(PyPI 上的 `libfinance`) |
|
|
227
|
+
| `cpp/` | C++ 客户端 |
|
|
228
|
+
| `docs/` | 文档(中英双语) |
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/StateOfTheArt-quant/libfinance/main/docs/_shared/_static/img/libfinance_logo_dark.svg">
|
|
5
|
+
<img alt="libfinance" src="https://raw.githubusercontent.com/StateOfTheArt-quant/libfinance/main/docs/_shared/_static/img/libfinance_logo.svg" width="300">
|
|
6
|
+
</picture>
|
|
7
|
+
|
|
8
|
+
**面向量化研究与回测的金融数据接口 —— A 股与美股一套术语,Python 与 C++ 一套函数**
|
|
9
|
+
|
|
10
|
+
[](https://pypi.org/project/libfinance/)
|
|
11
|
+
[](https://libfinance.readthedocs.io/zh-cn/latest/)
|
|
12
|
+
[](https://libfinance.readthedocs.io/en/latest/)
|
|
13
|
+
|
|
14
|
+
[📘 中文文档](https://libfinance.readthedocs.io/zh-cn/latest/) ·
|
|
15
|
+
[📗 English documentation](https://libfinance.readthedocs.io/en/latest/) ·
|
|
16
|
+
[💻 示例代码](https://github.com/StateOfTheArt-quant/libfinance/tree/main/example) ·
|
|
17
|
+
[🚀 快速开始](https://libfinance.readthedocs.io/zh-cn/latest/getting_started/quickstart.html) ·
|
|
18
|
+
[🧭 概念设计](https://libfinance.readthedocs.io/zh-cn/latest/concepts/security_identifiers.html) ·
|
|
19
|
+
[📑 API 参考](https://libfinance.readthedocs.io/zh-cn/latest/reference/contracts.html)
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
量化研究的结论依赖历史数据,而历史数据有三类常见的失真:证券代码会更名、复用,不同市场之间还会重号;财务报表在披露后会被修订,回测若读取最新版本,就用上了当时无从获得的信息;分红、拆股等公司行动改变价格的可比性,复权口径不一致会直接扭曲收益。研究与生产又常常分别使用 Python 与 C++,两套接口的细微差别会让同一策略在迁移后得到不同的结果。
|
|
26
|
+
|
|
27
|
+
`libfinance` 是面向量化研究与回测的金融数据客户端,覆盖 A 股与美股,提供 Python 与 C++ 两种实现。它以统一的证券标识、按时点(point-in-time)的数据版本和逐事件计算的复权因子组织行情、证券目录、交易日历、公司行动、股本、财务、行业 / 指数 / 主题成分与日频因子等数据;两个市场、两种语言遵循同一份接口契约,调用方式一致,差异只来自数据本身。
|
|
28
|
+
|
|
29
|
+
数据设计的四条约定:
|
|
30
|
+
|
|
31
|
+
- **统一的证券标识符** —— `<trading_code>.<namespace>`,如 `600000.XSHG`、`000001.XSHE`、`AAPL.US`。命名空间区分不同市场的同号代码,代码按历史时点解析,更名与代码复用不会串到别的证券。
|
|
32
|
+
- **point-in-time 机制 `as_of`** —— 按历史时点还原证券池、选取当时已披露的财务版本,避免未来信息与幸存者偏差。
|
|
33
|
+
- **高质量的复权因子 `exfactor`** —— 由公司行动逐事件计算,提供不复权、前复权、后复权三种口径;`get_ex_factor` 给出单次与累计因子,价格的每一次调整都可追溯。
|
|
34
|
+
- **Python 与 C++ 统一的函数设计** —— 两种客户端按同一份契约(`contract/contract.json`)实现,函数名、参数顺序与默认值、校验与报错、返回的列一一对应;同一组调用经两种客户端发给同一服务端逐项比对。
|
|
35
|
+
|
|
36
|
+
## 安装
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install libfinance
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
从源码安装:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/StateOfTheArt-quant/libfinance.git
|
|
46
|
+
cd libfinance/python
|
|
47
|
+
pip install -e .
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> [!TIP]
|
|
51
|
+
> **使用 C++?** C++ 客户端与 Python 版函数一一对应,通过 CMake `FetchContent` 引入项目,依赖 Apache Arrow C++。安装、构建与示例见 [cpp/README.md](https://github.com/StateOfTheArt-quant/libfinance/blob/main/cpp/README.md)。
|
|
52
|
+
|
|
53
|
+
## 快速开始
|
|
54
|
+
|
|
55
|
+
按[安装与连接说明](https://libfinance.readthedocs.io/zh-cn/latest/getting_started/installation.html)配置服务后即可查询。以下输出均为真实运行结果,数据持续更新,行数与数值可能不同。
|
|
56
|
+
|
|
57
|
+
**证券目录** —— 两个市场在同一张表里,列相同:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from libfinance import all_instruments
|
|
61
|
+
|
|
62
|
+
stocks = all_instruments(type="stock")
|
|
63
|
+
stocks.set_index("order_book_id").loc[
|
|
64
|
+
["600000.XSHG", "000001.XSHE", "AAPL.US", "NVDA.US"], ["market", "exchange", "name"]]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
market exchange name
|
|
69
|
+
order_book_id
|
|
70
|
+
600000.XSHG CN XSHG 浦发银行
|
|
71
|
+
000001.XSHE CN XSHE 平安银行
|
|
72
|
+
AAPL.US US XNAS Apple Inc. - Common Stock
|
|
73
|
+
NVDA.US US XNAS NVIDIA Corporation - Common Stock
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**交易日** —— 区间按自然日给,返回其中的交易日(美股传 `market="us"`):
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from libfinance import get_trading_dates
|
|
80
|
+
|
|
81
|
+
get_trading_dates("2024-05-11", "2024-05-20")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
DatetimeIndex(['2024-05-13', '2024-05-14', '2024-05-15', '2024-05-16',
|
|
86
|
+
'2024-05-17', '2024-05-20'],
|
|
87
|
+
dtype='datetime64[us]', freq=None)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**行情** —— 一次调用混查两个市场;美股没有涨跌停,`limit_up` 为 `NaN`,表结构不变:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from libfinance import get_price
|
|
94
|
+
|
|
95
|
+
get_price(["600000.XSHG", "AAPL.US"], "2024-03-01", "2024-03-05",
|
|
96
|
+
fields=["open", "close", "volume", "limit_up"], adjust_type="none")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
open close volume limit_up
|
|
101
|
+
order_book_id datetime
|
|
102
|
+
600000.XSHG 2024-03-01 7.13 7.11 29431801 7.87
|
|
103
|
+
2024-03-04 7.12 7.07 27855963 7.82
|
|
104
|
+
2024-03-05 7.05 7.16 41756232 7.78
|
|
105
|
+
AAPL.US 2024-03-01 179.55 179.66 73563100 NaN
|
|
106
|
+
2024-03-04 176.15 175.10 81510101 NaN
|
|
107
|
+
2024-03-05 170.76 170.12 95132400 NaN
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`adjust_type="none"` 取当天的真实成交价;不传时默认前复权(`"pre"`),见[价格口径](https://libfinance.readthedocs.io/zh-cn/latest/data/price.html)。
|
|
111
|
+
|
|
112
|
+
**因子** —— 库名 `system/alpha158` 展开为 158 个因子,每个因子一列:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from libfinance import get_factor_exposure
|
|
116
|
+
|
|
117
|
+
f = get_factor_exposure(["600000.XSHG", "000001.XSHE"], "system/alpha158", "2026-09-07", "2026-09-10")
|
|
118
|
+
f.iloc[:, :6].rename(columns=lambda c: c.rsplit("/", 1)[1]).round(4) # 前 6 列,列名只留因子名
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
KMID KLEN KMID2 KUP KUP2 KLOW
|
|
123
|
+
order_book_id date
|
|
124
|
+
600000.XSHG 2026-09-07 -0.0212 0.0286 -0.7407 0.0032 0.1111 0.0042
|
|
125
|
+
2026-09-08 0.0076 0.0141 0.5385 0.0065 0.4615 0.0000
|
|
126
|
+
2026-09-09 -0.0022 0.0086 -0.2500 0.0043 0.5000 0.0022
|
|
127
|
+
2026-09-10 0.0141 0.0184 0.7647 0.0011 0.0588 0.0033
|
|
128
|
+
000001.XSHE 2026-09-07 -0.0143 0.0194 -0.7391 0.0008 0.0435 0.0042
|
|
129
|
+
2026-09-08 0.0103 0.0137 0.7500 0.0026 0.1875 0.0009
|
|
130
|
+
2026-09-09 -0.0051 0.0085 -0.6000 0.0026 0.3000 0.0009
|
|
131
|
+
2026-09-10 0.0146 0.0171 0.8500 0.0009 0.0500 0.0017
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
逐步说明见[快速开始](https://libfinance.readthedocs.io/zh-cn/latest/getting_started/quickstart.html)。
|
|
135
|
+
|
|
136
|
+
## A 股与美股共用一套术语
|
|
137
|
+
|
|
138
|
+
统一体现在三个层面。
|
|
139
|
+
|
|
140
|
+
| 层面 | 统一的内容 | 例 |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| 证券标识 | 写法都是 `<trading_code>.<namespace>`;命名空间的粒度取决于该市场消除歧义所需的范围 | `600000.XSHG`、`AAPL.US` |
|
|
143
|
+
| 函数与参数 | 两个市场调用同一组函数,参数名相同,`as_of` 与 `adjust_type` 的含义一致 | `get_price`、`instruments`、`get_dividends` |
|
|
144
|
+
| 返回结构 | 列名与索引一致;某个市场不适用或未提供的字段取 `NaN`,不另设一张表 | 美股的 `turnover`、`limit_up`、`limit_down` |
|
|
145
|
+
|
|
146
|
+
需要显式指定市场的,只有不涉及具体证券的查询:交易日历、全市场目录、数据覆盖范围。按证券查询时,命名空间已经给出了市场信息,列表里也可以混合两个市场的代码。
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from libfinance import instruments, get_trading_dates
|
|
150
|
+
|
|
151
|
+
instruments(["000001.XSHE", "AAPL.US"]) # 命名空间已给出市场
|
|
152
|
+
get_trading_dates("2024-01-01", "2024-01-31", market="us") # 不涉及具体证券
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
统一的是术语和调用约定,数据本身的差异依然存在。下表的「市场」一列标出了每类数据实际覆盖的市场,逐个接口的情况见[查美股](https://libfinance.readthedocs.io/zh-cn/latest/howto/us_market.html)。
|
|
156
|
+
|
|
157
|
+
## 数据覆盖
|
|
158
|
+
|
|
159
|
+
| 数据 | 市场 | 主要函数 | 说明 |
|
|
160
|
+
| --- | --- | --- | --- |
|
|
161
|
+
| 交易日历 | CN · US | `get_trading_dates` | 交易日、区间取日、前后推 N 个交易日 |
|
|
162
|
+
| 证券目录 | CN · US | `all_instruments`、`instruments` | 股票、指数、行业、主题;代码、名称、上市与退市日期 |
|
|
163
|
+
| 日频行情 | CN · US | `get_price` | 开高低收、成交量额、涨跌停价,可复权 |
|
|
164
|
+
| 复权因子 | CN · US | `get_ex_factor` | 逐除权日的单次及累计因子 |
|
|
165
|
+
| 股本 | CN · US | `get_shares` | 逐交易日的总股本与流通股本 |
|
|
166
|
+
| 分红 / 拆股 / 配股 | CN · US | `get_dividends`、`get_splits`、`get_allotments` | 除权事件;配股只有 A 股 |
|
|
167
|
+
| 分拆 | US | `get_spinoffs` | A 股不产生这类事件 |
|
|
168
|
+
| 财务报表(PIT) | CN · US | `get_pit_financials_ex` | 按季度取,带修订历史 |
|
|
169
|
+
| 财务衍生指标 | CN · US | `get_financial_metrics` | 按交易日的财务衍生指标 |
|
|
170
|
+
| 行业分类 | CN · US | `get_instrument_industry`、`get_industry_constituents`、`get_industry_weights` | 申万、GICS 等分类体系 |
|
|
171
|
+
| 指数成分与权重 | CN · US | `get_index_constituents`、`get_index_weights` | 中证、标普等 |
|
|
172
|
+
| 主题成分与权重 | CN | `get_theme_constituents`、`get_theme_weights` | THS 主题 |
|
|
173
|
+
| 日频因子 | CN | `get_factor_exposure`、`list_factor_libraries`、`list_factors` | alpha158、qlib,Barra CNE5 风格 / 行业因子,CNE5 与 CNE6 描述符;见[因子数据](https://libfinance.readthedocs.io/zh-cn/latest/data/factors.html)与[因子字典](https://libfinance.readthedocs.io/zh-cn/latest/reference/factor_dictionary.html) |
|
|
174
|
+
| 实时行情 | CN | `get_last_quotes`、`QuoteApi` | 最新快照与订阅推送 |
|
|
175
|
+
|
|
176
|
+
覆盖到哪一年、更新到哪一天,取决于你连的那个服务。**不要照抄文档里的日期**,用[数据新鲜度](https://libfinance.readthedocs.io/zh-cn/latest/data/freshness.html)里的两个函数自己查。
|
|
177
|
+
|
|
178
|
+
## 概念设计
|
|
179
|
+
|
|
180
|
+
| 主题 | 解决的问题 |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| [统一的证券标识符](https://libfinance.readthedocs.io/zh-cn/latest/concepts/security_identifiers.html) | 区分市场、证券身份及历史代码,准确关联不同数据 |
|
|
183
|
+
| [point-in-time 机制 as_of](https://libfinance.readthedocs.io/zh-cn/latest/concepts/point_in_time.html) | 还原历史证券池与可见财报,避免未来信息和幸存者偏差 |
|
|
184
|
+
| [高质量的复权因子 exfactor](https://libfinance.readthedocs.io/zh-cn/latest/concepts/exfactor.html) | 理解公司行动对价格的影响,以及三种价格口径的计算和用途 |
|
|
185
|
+
| [Python 与 C++ 统一的函数设计](https://libfinance.readthedocs.io/zh-cn/latest/concepts/python_cpp.html) | 一份契约约束两种客户端:函数、参数、报错与返回列一一对应,并逐项核对 |
|
|
186
|
+
|
|
187
|
+
## 文档与示例
|
|
188
|
+
|
|
189
|
+
| | |
|
|
190
|
+
| --- | --- |
|
|
191
|
+
| [📘 中文文档](https://libfinance.readthedocs.io/zh-cn/latest/) | 概念设计、数据说明、操作指南与 API 参考 |
|
|
192
|
+
| [📗 English documentation](https://libfinance.readthedocs.io/en/latest/) | The same documentation tree in English |
|
|
193
|
+
| [💻 示例代码](https://github.com/StateOfTheArt-quant/libfinance/tree/main/example) | 按数据族排序的可运行示例(Python 与 C++ 一一对应),与 API 参考对照阅读 |
|
|
194
|
+
| [🧩 操作指南](https://libfinance.readthedocs.io/zh-cn/latest/howto/index.html) | 取行情面板、PIT 回测、订阅实时行情等成套做法 |
|
|
195
|
+
| [🩺 故障排查](https://libfinance.readthedocs.io/zh-cn/latest/howto/troubleshooting.html) | 按**症状**编排:看到什么现象,就从哪一行开始 |
|
|
196
|
+
|
|
197
|
+
API 参考按合约信息和交易日历、行情、基本面、行业与指数和主题、公司行动、实时行情、因子分组,每个函数附 Python 与 C++ 两种写法的示例及其真实输出。
|
|
198
|
+
|
|
199
|
+
## 社区
|
|
200
|
+
|
|
201
|
+
问题与需求请提 [Issue](https://github.com/StateOfTheArt-quant/libfinance/issues)。关注公众号获取更新:
|
|
202
|
+
|
|
203
|
+
<div align="center">
|
|
204
|
+
<img alt="微信公众号二维码" src="https://raw.githubusercontent.com/StateOfTheArt-quant/libfinance/main/docs/_shared/_static/img/code.png" width="600" height="220">
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
## 仓库结构
|
|
208
|
+
|
|
209
|
+
| 目录 | 内容 |
|
|
210
|
+
| --- | --- |
|
|
211
|
+
| `contract/` | 各语言客户端共同遵守的契约:公开函数(名称、参数顺序与默认值、返回)与它们调用的服务端函数 |
|
|
212
|
+
| `contract/conformance/` | 同一组调用分别经 Python 与 C++ 客户端发给同一个服务端,逐项比对答案 |
|
|
213
|
+
| `python/` | Python 客户端(PyPI 上的 `libfinance`) |
|
|
214
|
+
| `cpp/` | C++ 客户端 |
|
|
215
|
+
| `docs/` | 文档(中英双语) |
|
libfinance-0.1.3/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.3
|
|
@@ -22,7 +22,7 @@ def get_ex_factor(
|
|
|
22
22
|
:param end_date: 结束除权日,含当日;省略则查询至数据截止日。
|
|
23
23
|
代码按该日有效的身份解析,省略时按当前代码解析
|
|
24
24
|
:returns: 以 ex_date 为 DatetimeIndex 的 DataFrame,包含 order_book_id、
|
|
25
|
-
|
|
25
|
+
ex_factor、ex_cum_factor。ex_factor 是单个除权日因子,同日行动已合成;
|
|
26
26
|
ex_cum_factor 是从数据版本内该证券首个事件前以 1 为基准的累计因子。
|
|
27
27
|
已覆盖证券在窗口内无记录时返回保留索引和列结构的空表。
|
|
28
28
|
|
|
@@ -129,7 +129,7 @@ def get_price(
|
|
|
129
129
|
指数原样返回
|
|
130
130
|
:param adjust_orig: 前复权的基准日;省略时为 ``end_date``\ :价格换算到查询区间最后一天的口径,
|
|
131
131
|
区间之后的除权不影响结果(point-in-time)
|
|
132
|
-
:returns: 以 ``(order_book_id, datetime)`` 为索引的 DataFrame
|
|
132
|
+
:returns: 以 ``(order_book_id, datetime)`` 为索引的 DataFrame,列为所选字段。
|
|
133
133
|
|
|
134
134
|
复权规则:成交量随复权反向缩放,成交额 ``turnover`` 不受复权影响。
|
|
135
135
|
"""
|
|
@@ -167,7 +167,7 @@ def get_price(
|
|
|
167
167
|
|
|
168
168
|
|
|
169
169
|
def _to_panel(frame):
|
|
170
|
-
r"""daybar 的扁平表(\ ``order_book_id,
|
|
170
|
+
r"""daybar 的扁平表(\ ``order_book_id, session_date, 字段...``\ )还原成
|
|
171
171
|
``(order_book_id, datetime)`` 索引。不认识的形状原样返回,让调用方看见真实的列。"""
|
|
172
172
|
if not isinstance(frame, pd.DataFrame) or not {"order_book_id", "session_date"} <= set(frame.columns):
|
|
173
173
|
return frame
|
|
@@ -50,7 +50,7 @@ def get_index_weights(order_book_id: str, as_of=None) -> pd.DataFrame:
|
|
|
50
50
|
|
|
51
51
|
:param order_book_id: 指数代码,如 ``"000300.XSHG"``
|
|
52
52
|
:param as_of: 那一天的事实;省略则取指数已确认的最新日期
|
|
53
|
-
:returns: pandas.DataFrame,包含 order_book_id(成分证券)、
|
|
53
|
+
:returns: pandas.DataFrame,包含 order_book_id(成分证券)、weight、methodology、source(指数发布机构)、
|
|
54
54
|
basis(origin 数据源发布 / reconstructed 按编制方法重构)、date(权重所在的日子)、quality_flags。
|
|
55
55
|
权重是月末快照:其余交易日取之前最近一期、按各成分的复权收益率漂移,date 为 as_of,quality_flags 带 DRIFTED。
|
|
56
56
|
"""
|
|
@@ -5,8 +5,8 @@ r"""证券目录:股票、指数、行业、主题在同一个 instrument 聚
|
|
|
5
5
|
签名与列名取自后端 instrument 数据族(\ ``instrument.all_instruments`` /
|
|
6
6
|
``instrument.instruments``\ ),本模块只做参数检查、按数据版本缓存与结果的形状。
|
|
7
7
|
|
|
8
|
-
* ``order_book_id`` 是代码(\ ``600000.XSHG``\ 、\ ``000300.XSHG``\ 、\ ``AAPL.US``\
|
|
9
|
-
``
|
|
8
|
+
* ``order_book_id`` 是代码(\ ``600000.XSHG``\ 、\ ``000300.XSHG``\ 、\ ``AAPL.US``\ ),也是客户端唯一的证券标识;
|
|
9
|
+
``name`` 是名称。
|
|
10
10
|
* ``type`` 取 ``stock`` / ``index`` / ``industry`` / ``theme``\ 。
|
|
11
11
|
* ``source`` 是定义并编号证券的机构:股票的交易所(XSHG、XNAS)、指数的发布机构
|
|
12
12
|
(CSI、SPDJI)、行业的分类体系(SW、GICS)、主题的 THS;\ ``exchange`` 只有股票有。
|
|
@@ -25,7 +25,7 @@ from libfinance.utils.validators import ensure_list_of_string
|
|
|
25
25
|
VALID_TYPES = ("stock", "index", "industry", "theme")
|
|
26
26
|
|
|
27
27
|
#: all_instruments 的列,按后端的顺序。
|
|
28
|
-
COLUMNS = ("order_book_id", "
|
|
28
|
+
COLUMNS = ("order_book_id", "type", "market", "name", "exchange", "source")
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
class Instrument(object):
|
|
@@ -90,7 +90,7 @@ def all_instruments(
|
|
|
90
90
|
:param as_of: 给出则为该日的历史视图;省略时各类型取各自的当前状态。某类型不覆盖的日期
|
|
91
91
|
报 CoverageError 并写明类型,缩小 ``type`` 或 ``source`` 即可。
|
|
92
92
|
:param cached: 是否使用按服务端数据版本更新的缓存;显式指定市场时直接查询。
|
|
93
|
-
:returns: DataFrame,列为 ``order_book_id,
|
|
93
|
+
:returns: DataFrame,列为 ``order_book_id, type, market, name, exchange, source``\ 。
|
|
94
94
|
"""
|
|
95
95
|
types = _normalize_types(type)
|
|
96
96
|
sources = _optional_strings(source, "source")
|
|
@@ -8,8 +8,7 @@ from libfinance.subscribe.md_protocol import Quote
|
|
|
8
8
|
Quote 的字段集与订阅路径统一(定义见 libfinance/subscribe/md_protocol.py,对齐 dynamics):
|
|
9
9
|
|
|
10
10
|
data_time: int
|
|
11
|
-
|
|
12
|
-
instrument_type: int # InstrumentType 枚举
|
|
11
|
+
order_book_id: str # 如 600000.XSHG(协议 v4 起唯一的标的字段)
|
|
13
12
|
pre_close_price / pre_settlement_price / last_price / volume / turnover
|
|
14
13
|
pre_open_interest / open_interest
|
|
15
14
|
open_price / high_price / low_price / upper_limit_price / lower_limit_price
|
|
@@ -17,13 +16,16 @@ Quote 的字段集与订阅路径统一(定义见 libfinance/subscribe/md_prot
|
|
|
17
16
|
total_bid_volume / total_ask_volume / total_trade_num
|
|
18
17
|
bid_price / ask_price / bid_volume / ask_volume # 均为 list[float],10 档
|
|
19
18
|
trading_phase_code: str
|
|
20
|
-
order_book_id: str # 只读属性 = f"{instrument_id}.{exchange_id}"
|
|
21
19
|
|
|
22
20
|
注意:本函数走 RPC(8080),与行情网关是两条独立通路,只是复用同一个 Quote 类型。
|
|
23
21
|
服务端返回体的字段名须与上面一致;下面用 __dict__ 注入,多余的键会原样带上,
|
|
24
22
|
缺失的键则在访问时才报 AttributeError。
|
|
25
23
|
"""
|
|
26
24
|
|
|
25
|
+
#: 协议 v4 之前的标的字段:order_book_id 已包含全部信息,旧服务端送来也丢掉。
|
|
26
|
+
_RETIRED = frozenset(("instrument_id", "exchange_id", "instrument_type"))
|
|
27
|
+
|
|
28
|
+
|
|
27
29
|
def dict_to_quotes_ultrafast(raw_data) -> dict[str, Quote]:
|
|
28
30
|
result = {}
|
|
29
31
|
for k, v in raw_data.items():
|
|
@@ -39,7 +41,8 @@ def dict_to_quotes_ultrafast(raw_data) -> dict[str, Quote]:
|
|
|
39
41
|
|
|
40
42
|
# 🧹 3. 是 dict 时快速清洗内部 None 值,防止下游量价计算报 TypeError
|
|
41
43
|
# 字典推导式在 CPython 底层由 C 循环驱动,性能损耗 < 5%
|
|
42
|
-
clean_v = {fk: fv for fk, fv in v.items() if fv is not None}
|
|
44
|
+
clean_v = {fk: fv for fk, fv in v.items() if fv is not None and fk not in _RETIRED}
|
|
45
|
+
clean_v.setdefault("order_book_id", k) # 键就是 order_book_id;旧服务端不带这个字段
|
|
43
46
|
|
|
44
47
|
# 🚀 4. 绕过 __init__ 参数绑定,直接注入对象内存
|
|
45
48
|
q = object.__new__(Quote)
|