jcdata 0.2.0__tar.gz → 0.2.2__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.
- jcdata-0.2.2/PKG-INFO +198 -0
- jcdata-0.2.2/README.md +168 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/__init__.py +78 -72
- {jcdata-0.2.0 → jcdata-0.2.2}/_arrow.py +5 -5
- {jcdata-0.2.0 → jcdata-0.2.2}/_http.py +472 -465
- {jcdata-0.2.0 → jcdata-0.2.2}/_ts.py +3 -1
- jcdata-0.2.2/config.py +18 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/data.py +935 -654
- jcdata-0.2.2/jcdata.egg-info/PKG-INFO +198 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/pyproject.toml +44 -44
- jcdata-0.2.0/PKG-INFO +0 -115
- jcdata-0.2.0/README.md +0 -85
- jcdata-0.2.0/config.py +0 -29
- jcdata-0.2.0/jcdata.egg-info/PKG-INFO +0 -115
- {jcdata-0.2.0 → jcdata-0.2.2}/_params.py +0 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/errors.py +0 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/jcdata.egg-info/SOURCES.txt +0 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/jcdata.egg-info/dependency_links.txt +0 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/jcdata.egg-info/requires.txt +0 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/jcdata.egg-info/top_level.txt +0 -0
- {jcdata-0.2.0 → jcdata-0.2.2}/setup.cfg +0 -0
jcdata-0.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jcdata
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Python client for JCDATA market data and factor APIs
|
|
5
|
+
Author: JiceQuant
|
|
6
|
+
License-Expression: LicenseRef-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://jicequant.com/
|
|
8
|
+
Project-URL: Documentation, https://jicequant.com/
|
|
9
|
+
Project-URL: Repository, https://pypi.org/project/jcdata/
|
|
10
|
+
Keywords: finance,quant,market-data,china,a-share
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Requires-Dist: httpx>=0.24
|
|
26
|
+
Requires-Dist: pandas>=1.3
|
|
27
|
+
Requires-Dist: pyarrow>=14
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
30
|
+
|
|
31
|
+
# jcdata
|
|
32
|
+
|
|
33
|
+
`jcdata` 是 JCDATA 的 Python 客户端,用于获取市场数据、证券基础信息、因子、财务、ETF、期权、利率和宏观数据
|
|
34
|
+
|
|
35
|
+
## 安装
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install jcdata
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 认证
|
|
42
|
+
|
|
43
|
+
使用访问令牌登录。请将令牌保存在环境变量或密钥管理系统中,禁止写入源码、笔记本、日志或版本控制系统。
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import jcdata
|
|
47
|
+
|
|
48
|
+
login_info = jcdata.login("YOUR_TOKEN")
|
|
49
|
+
if not login_info.get("user_name"):
|
|
50
|
+
raise PermissionError("令牌无效、已过期或无访问权限")
|
|
51
|
+
|
|
52
|
+
print(login_info["user_name"])
|
|
53
|
+
print(login_info["cell_quota_remaining"])
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
也可使用环境变量:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Linux / macOS
|
|
60
|
+
export JCDATA_TOKEN="YOUR_TOKEN"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
# Windows PowerShell
|
|
65
|
+
$env:JCDATA_TOKEN = "YOUR_TOKEN"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
jcdata.login()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
令牌查找顺序为:`login(token=...)` 参数、`JCDATA_TOKEN` 环境变量。`login()` 返回用户名、接口使用量和剩余配额;认证未通过时这些字段为 `None`。
|
|
73
|
+
|
|
74
|
+
## 基本使用
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import jcdata
|
|
78
|
+
|
|
79
|
+
jcdata.login()
|
|
80
|
+
|
|
81
|
+
bars = jcdata.get_market_data(
|
|
82
|
+
"600000.SH",
|
|
83
|
+
"2025-01-02",
|
|
84
|
+
"2025-01-10",
|
|
85
|
+
fields=["date", "open", "high", "low", "close", "volume"],
|
|
86
|
+
)
|
|
87
|
+
frame = bars["600000.SH"]
|
|
88
|
+
|
|
89
|
+
if not frame.empty:
|
|
90
|
+
print(frame.tail())
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
多数按证券代码查询的接口返回 `dict[str, pandas.DataFrame]`:字典 key 为请求代码,DataFrame 中不依赖 `symbol` 列分组。没有匹配数据时也会保留对应的空 DataFrame,因此请显式处理 `frame.empty`。
|
|
94
|
+
|
|
95
|
+
日期参数支持 `YYYY-MM-DD` 或 `YYYYMMDD`,例如 `2025-01-02` 或 `20250102`。
|
|
96
|
+
|
|
97
|
+
## 常用接口
|
|
98
|
+
|
|
99
|
+
| 分类 | 接口 |
|
|
100
|
+
|---|---|
|
|
101
|
+
| 日 K | `get_market_data`、`iter_market_data`、`iter_market_data_batches` |
|
|
102
|
+
| 基础信息 | `get_instrument`、`get_adj_factor`、`get_settlement`、`get_future_contract` |
|
|
103
|
+
| 股票扩展 | `get_factors`、`get_valuation`、`get_market_value`、`get_finance`、`get_money_flow`、`get_margin`、`get_leader_board` |
|
|
104
|
+
| 期权 | `get_market_data`、`get_option_greeks` |
|
|
105
|
+
| ETF | `get_etf_share`、`get_etf_tracking` |
|
|
106
|
+
| 日历与板块 | `get_trade_dates`、`get_all_sectors`、`get_stock_list_by_sector` |
|
|
107
|
+
| 利率与宏观 | `get_interest_rate`、`get_government_yield`、`get_macro_indicators` |
|
|
108
|
+
|
|
109
|
+
## 批量行情
|
|
110
|
+
|
|
111
|
+
直接传入代码列表即可查询多标的行情:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
symbols = ["600000.SH", "000001.SZ", "510300.SH"]
|
|
115
|
+
bars = jcdata.get_market_data(symbols, "2025-01-02", "2025-01-10", fields=["date", "close"])
|
|
116
|
+
|
|
117
|
+
for symbol, frame in bars.items():
|
|
118
|
+
print(symbol, len(frame))
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
混合查询不同资产时,各 DataFrame 只返回该资产适用的字段。请按单个 DataFrame 的实际列名处理,不要假设所有资产具有相同字段。
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
mixed = jcdata.get_market_data(["600000.SH", "IF2501.CFE"], "2025-01-02", "2025-01-10")
|
|
125
|
+
print(mixed["600000.SH"].columns.tolist())
|
|
126
|
+
print(mixed["IF2501.CFE"].columns.tolist())
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 复权
|
|
130
|
+
|
|
131
|
+
`get_market_data()` 支持股票、ETF 和可转债复权:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
adjusted = jcdata.get_market_data(
|
|
135
|
+
"600000.SH",
|
|
136
|
+
"2024-01-01",
|
|
137
|
+
"2025-01-31",
|
|
138
|
+
dividend_type="front",
|
|
139
|
+
fields=["date", "close"],
|
|
140
|
+
)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
可用 `dividend_type`:`none`、`front`、`back`、`point`。使用 `point` 时必须同时传 `adjust_date`。指数不参与复权。
|
|
144
|
+
|
|
145
|
+
## 大数据读取
|
|
146
|
+
|
|
147
|
+
代码数量较多但希望按代码处理时,使用 `iter_market_data()`:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
for chunk_symbols, frames in jcdata.iter_market_data(
|
|
151
|
+
symbols,
|
|
152
|
+
"2020-01-01",
|
|
153
|
+
"2025-01-01",
|
|
154
|
+
chunk_size=60,
|
|
155
|
+
fields=["date", "close", "volume"],
|
|
156
|
+
):
|
|
157
|
+
for symbol in chunk_symbols:
|
|
158
|
+
process(frames[symbol])
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
超长历史数据使用 `iter_market_data_batches()`,并在循环内及时处理结果:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
for present_symbols, frames in jcdata.iter_market_data_batches(
|
|
165
|
+
symbols,
|
|
166
|
+
"2015-01-01",
|
|
167
|
+
"2025-01-01",
|
|
168
|
+
fields=["date", "close"],
|
|
169
|
+
stream_batch_rows=65_536,
|
|
170
|
+
):
|
|
171
|
+
for symbol in present_symbols:
|
|
172
|
+
frames[symbol].to_parquet(f"{symbol}.parquet", index=False)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
同一代码可能跨多个批次出现。请不要将全部批次累积到内存中。
|
|
176
|
+
|
|
177
|
+
## 错误处理
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
try:
|
|
181
|
+
jcdata.login()
|
|
182
|
+
bars = jcdata.get_market_data("600000.SH", "2025-01-02", "2025-01-10")
|
|
183
|
+
except jcdata.CellQuotaExceededError as exc:
|
|
184
|
+
print("配额已用尽,剩余:", exc.cell_quota_remaining)
|
|
185
|
+
except jcdata.InvalidParameterError as exc:
|
|
186
|
+
print("参数错误:", exc.param, exc.value)
|
|
187
|
+
except PermissionError as exc:
|
|
188
|
+
print("认证或授权失败:", exc)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`CellQuotaExceededError` 是 `PermissionError` 的子类,因此应优先捕获。参数问题会引发 `InvalidParameterError`,可通过 `.param` 和 `.value` 定位。对于无效代码或正常无数据区间,按代码查询接口一般返回空 DataFrame,而非异常。
|
|
192
|
+
|
|
193
|
+
## 更多说明
|
|
194
|
+
|
|
195
|
+
- 代码格式通常为 `代码.市场后缀`,例如 `600000.SH`、`000001.SZ`、`IF2501.CFE`。
|
|
196
|
+
- 使用 `get_asset_type_by_symbol()` 可识别常见代码的资产类型。
|
|
197
|
+
- 使用 `fields` 限定实际需要的列,可减少传输量和处理成本。
|
|
198
|
+
- 如遇访问频率或配额限制,请控制并发、缩小查询范围并保存任务进度。
|
jcdata-0.2.2/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# jcdata
|
|
2
|
+
|
|
3
|
+
`jcdata` 是 JCDATA 的 Python 客户端,用于获取市场数据、证券基础信息、因子、财务、ETF、期权、利率和宏观数据
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install jcdata
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 认证
|
|
12
|
+
|
|
13
|
+
使用访问令牌登录。请将令牌保存在环境变量或密钥管理系统中,禁止写入源码、笔记本、日志或版本控制系统。
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import jcdata
|
|
17
|
+
|
|
18
|
+
login_info = jcdata.login("YOUR_TOKEN")
|
|
19
|
+
if not login_info.get("user_name"):
|
|
20
|
+
raise PermissionError("令牌无效、已过期或无访问权限")
|
|
21
|
+
|
|
22
|
+
print(login_info["user_name"])
|
|
23
|
+
print(login_info["cell_quota_remaining"])
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
也可使用环境变量:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Linux / macOS
|
|
30
|
+
export JCDATA_TOKEN="YOUR_TOKEN"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```powershell
|
|
34
|
+
# Windows PowerShell
|
|
35
|
+
$env:JCDATA_TOKEN = "YOUR_TOKEN"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
jcdata.login()
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
令牌查找顺序为:`login(token=...)` 参数、`JCDATA_TOKEN` 环境变量。`login()` 返回用户名、接口使用量和剩余配额;认证未通过时这些字段为 `None`。
|
|
43
|
+
|
|
44
|
+
## 基本使用
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import jcdata
|
|
48
|
+
|
|
49
|
+
jcdata.login()
|
|
50
|
+
|
|
51
|
+
bars = jcdata.get_market_data(
|
|
52
|
+
"600000.SH",
|
|
53
|
+
"2025-01-02",
|
|
54
|
+
"2025-01-10",
|
|
55
|
+
fields=["date", "open", "high", "low", "close", "volume"],
|
|
56
|
+
)
|
|
57
|
+
frame = bars["600000.SH"]
|
|
58
|
+
|
|
59
|
+
if not frame.empty:
|
|
60
|
+
print(frame.tail())
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
多数按证券代码查询的接口返回 `dict[str, pandas.DataFrame]`:字典 key 为请求代码,DataFrame 中不依赖 `symbol` 列分组。没有匹配数据时也会保留对应的空 DataFrame,因此请显式处理 `frame.empty`。
|
|
64
|
+
|
|
65
|
+
日期参数支持 `YYYY-MM-DD` 或 `YYYYMMDD`,例如 `2025-01-02` 或 `20250102`。
|
|
66
|
+
|
|
67
|
+
## 常用接口
|
|
68
|
+
|
|
69
|
+
| 分类 | 接口 |
|
|
70
|
+
|---|---|
|
|
71
|
+
| 日 K | `get_market_data`、`iter_market_data`、`iter_market_data_batches` |
|
|
72
|
+
| 基础信息 | `get_instrument`、`get_adj_factor`、`get_settlement`、`get_future_contract` |
|
|
73
|
+
| 股票扩展 | `get_factors`、`get_valuation`、`get_market_value`、`get_finance`、`get_money_flow`、`get_margin`、`get_leader_board` |
|
|
74
|
+
| 期权 | `get_market_data`、`get_option_greeks` |
|
|
75
|
+
| ETF | `get_etf_share`、`get_etf_tracking` |
|
|
76
|
+
| 日历与板块 | `get_trade_dates`、`get_all_sectors`、`get_stock_list_by_sector` |
|
|
77
|
+
| 利率与宏观 | `get_interest_rate`、`get_government_yield`、`get_macro_indicators` |
|
|
78
|
+
|
|
79
|
+
## 批量行情
|
|
80
|
+
|
|
81
|
+
直接传入代码列表即可查询多标的行情:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
symbols = ["600000.SH", "000001.SZ", "510300.SH"]
|
|
85
|
+
bars = jcdata.get_market_data(symbols, "2025-01-02", "2025-01-10", fields=["date", "close"])
|
|
86
|
+
|
|
87
|
+
for symbol, frame in bars.items():
|
|
88
|
+
print(symbol, len(frame))
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
混合查询不同资产时,各 DataFrame 只返回该资产适用的字段。请按单个 DataFrame 的实际列名处理,不要假设所有资产具有相同字段。
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
mixed = jcdata.get_market_data(["600000.SH", "IF2501.CFE"], "2025-01-02", "2025-01-10")
|
|
95
|
+
print(mixed["600000.SH"].columns.tolist())
|
|
96
|
+
print(mixed["IF2501.CFE"].columns.tolist())
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 复权
|
|
100
|
+
|
|
101
|
+
`get_market_data()` 支持股票、ETF 和可转债复权:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
adjusted = jcdata.get_market_data(
|
|
105
|
+
"600000.SH",
|
|
106
|
+
"2024-01-01",
|
|
107
|
+
"2025-01-31",
|
|
108
|
+
dividend_type="front",
|
|
109
|
+
fields=["date", "close"],
|
|
110
|
+
)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
可用 `dividend_type`:`none`、`front`、`back`、`point`。使用 `point` 时必须同时传 `adjust_date`。指数不参与复权。
|
|
114
|
+
|
|
115
|
+
## 大数据读取
|
|
116
|
+
|
|
117
|
+
代码数量较多但希望按代码处理时,使用 `iter_market_data()`:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
for chunk_symbols, frames in jcdata.iter_market_data(
|
|
121
|
+
symbols,
|
|
122
|
+
"2020-01-01",
|
|
123
|
+
"2025-01-01",
|
|
124
|
+
chunk_size=60,
|
|
125
|
+
fields=["date", "close", "volume"],
|
|
126
|
+
):
|
|
127
|
+
for symbol in chunk_symbols:
|
|
128
|
+
process(frames[symbol])
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
超长历史数据使用 `iter_market_data_batches()`,并在循环内及时处理结果:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
for present_symbols, frames in jcdata.iter_market_data_batches(
|
|
135
|
+
symbols,
|
|
136
|
+
"2015-01-01",
|
|
137
|
+
"2025-01-01",
|
|
138
|
+
fields=["date", "close"],
|
|
139
|
+
stream_batch_rows=65_536,
|
|
140
|
+
):
|
|
141
|
+
for symbol in present_symbols:
|
|
142
|
+
frames[symbol].to_parquet(f"{symbol}.parquet", index=False)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
同一代码可能跨多个批次出现。请不要将全部批次累积到内存中。
|
|
146
|
+
|
|
147
|
+
## 错误处理
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
try:
|
|
151
|
+
jcdata.login()
|
|
152
|
+
bars = jcdata.get_market_data("600000.SH", "2025-01-02", "2025-01-10")
|
|
153
|
+
except jcdata.CellQuotaExceededError as exc:
|
|
154
|
+
print("配额已用尽,剩余:", exc.cell_quota_remaining)
|
|
155
|
+
except jcdata.InvalidParameterError as exc:
|
|
156
|
+
print("参数错误:", exc.param, exc.value)
|
|
157
|
+
except PermissionError as exc:
|
|
158
|
+
print("认证或授权失败:", exc)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`CellQuotaExceededError` 是 `PermissionError` 的子类,因此应优先捕获。参数问题会引发 `InvalidParameterError`,可通过 `.param` 和 `.value` 定位。对于无效代码或正常无数据区间,按代码查询接口一般返回空 DataFrame,而非异常。
|
|
162
|
+
|
|
163
|
+
## 更多说明
|
|
164
|
+
|
|
165
|
+
- 代码格式通常为 `代码.市场后缀`,例如 `600000.SH`、`000001.SZ`、`IF2501.CFE`。
|
|
166
|
+
- 使用 `get_asset_type_by_symbol()` 可识别常见代码的资产类型。
|
|
167
|
+
- 使用 `fields` 限定实际需要的列,可减少传输量和处理成本。
|
|
168
|
+
- 如遇访问频率或配额限制,请控制并发、缩小查询范围并保存任务进度。
|
|
@@ -1,72 +1,78 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
JCDATA
|
|
4
|
-
|
|
5
|
-
使用前调用 ``jcdata.login("...")``(或设置环境变量 ``JCDATA_TOKEN``)::
|
|
6
|
-
|
|
7
|
-
import jcdata
|
|
8
|
-
|
|
9
|
-
jcdata.login("你的访问令牌")
|
|
10
|
-
df = jcdata.get_market_data("600000.SH", "2025-01-01", "2025-01-31")["600000.SH"]
|
|
11
|
-
"""
|
|
12
|
-
from __future__ import annotations
|
|
13
|
-
|
|
14
|
-
from ._http import current_user, login, whoami
|
|
15
|
-
from .errors import CellQuotaExceededError, ErrorCode, InvalidParameterError, RowQuotaExceededError
|
|
16
|
-
from .data import (
|
|
17
|
-
get_adj_factor,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
JCDATA Python 客户端:用于查询市场数据和相关数据集。
|
|
4
|
+
|
|
5
|
+
使用前调用 ``jcdata.login("...")``(或设置环境变量 ``JCDATA_TOKEN``)::
|
|
6
|
+
|
|
7
|
+
import jcdata
|
|
8
|
+
|
|
9
|
+
jcdata.login("你的访问令牌")
|
|
10
|
+
df = jcdata.get_market_data("600000.SH", "2025-01-01", "2025-01-31")["600000.SH"]
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from ._http import current_user, login, whoami
|
|
15
|
+
from .errors import CellQuotaExceededError, ErrorCode, InvalidParameterError, RowQuotaExceededError
|
|
16
|
+
from .data import (
|
|
17
|
+
get_adj_factor,
|
|
18
|
+
get_asset_type_by_symbol,
|
|
19
|
+
get_etf_share,
|
|
20
|
+
get_etf_tracking,
|
|
21
|
+
get_finance,
|
|
22
|
+
get_factors,
|
|
23
|
+
get_future_contract,
|
|
24
|
+
get_government_yield,
|
|
25
|
+
get_instrument,
|
|
26
|
+
get_interest_rate,
|
|
27
|
+
get_leader_board,
|
|
28
|
+
get_margin,
|
|
29
|
+
get_market_data,
|
|
30
|
+
iter_market_data,
|
|
31
|
+
iter_market_data_batches,
|
|
32
|
+
get_market_value,
|
|
33
|
+
get_macro_indicators,
|
|
34
|
+
get_money_flow,
|
|
35
|
+
get_option_greeks,
|
|
36
|
+
get_settlement,
|
|
37
|
+
get_all_sectors,
|
|
38
|
+
get_stock_list_by_sector,
|
|
39
|
+
get_trade_dates,
|
|
40
|
+
get_valuation,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
__version__ = "0.2.2"
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
"__version__",
|
|
47
|
+
"login",
|
|
48
|
+
"whoami",
|
|
49
|
+
"current_user",
|
|
50
|
+
"ErrorCode",
|
|
51
|
+
"CellQuotaExceededError",
|
|
52
|
+
"InvalidParameterError",
|
|
53
|
+
"RowQuotaExceededError",
|
|
54
|
+
"get_market_data",
|
|
55
|
+
"get_asset_type_by_symbol",
|
|
56
|
+
"iter_market_data",
|
|
57
|
+
"iter_market_data_batches",
|
|
58
|
+
"get_instrument",
|
|
59
|
+
"get_adj_factor",
|
|
60
|
+
"get_settlement",
|
|
61
|
+
"get_future_contract",
|
|
62
|
+
"get_valuation",
|
|
63
|
+
"get_market_value",
|
|
64
|
+
"get_government_yield",
|
|
65
|
+
"get_macro_indicators",
|
|
66
|
+
"get_finance",
|
|
67
|
+
"get_factors",
|
|
68
|
+
"get_trade_dates",
|
|
69
|
+
"get_all_sectors",
|
|
70
|
+
"get_stock_list_by_sector",
|
|
71
|
+
"get_option_greeks",
|
|
72
|
+
"get_money_flow",
|
|
73
|
+
"get_margin",
|
|
74
|
+
"get_leader_board",
|
|
75
|
+
"get_etf_share",
|
|
76
|
+
"get_etf_tracking",
|
|
77
|
+
"get_interest_rate",
|
|
78
|
+
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""解析行情数据响应。"""
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import io
|
|
@@ -36,14 +36,14 @@ def _split_by_symbol(df: pd.DataFrame) -> dict[str, pd.DataFrame]:
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def decode_arrow_by_symbol(data: bytes) -> dict[str, pd.DataFrame]:
|
|
39
|
-
"""
|
|
39
|
+
"""解析行情数据响应。"""
|
|
40
40
|
if not data:
|
|
41
41
|
return {}
|
|
42
42
|
return _split_by_symbol(normalize_datetimes(ipc.open_stream(io.BytesIO(data)).read_all().to_pandas()))
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
def iter_zstd_arrow_by_symbol(chunks: Iterable[bytes]) -> Iterator[dict[str, pd.DataFrame]]:
|
|
46
|
-
"""
|
|
46
|
+
"""逐批解析行情数据流。"""
|
|
47
47
|
buffer = bytearray()
|
|
48
48
|
expected: int | None = None
|
|
49
49
|
for chunk in chunks:
|
|
@@ -64,9 +64,9 @@ def iter_zstd_arrow_by_symbol(chunks: Iterable[bytes]) -> Iterator[dict[str, pd.
|
|
|
64
64
|
if frames:
|
|
65
65
|
yield frames
|
|
66
66
|
if expected is not None or buffer:
|
|
67
|
-
raise ValueError("
|
|
67
|
+
raise ValueError("行情数据流不完整")
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
def decode_bars_arrow(data: bytes) -> dict[str, pd.DataFrame]:
|
|
71
|
-
"""
|
|
71
|
+
"""解析行情数据。"""
|
|
72
72
|
return decode_arrow_by_symbol(data)
|