Metadata-Version: 2.4
Name: jcdata
Version: 0.2.4
Summary: Python client for JCDATA market data and factor APIs
Author: JiceQuant
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://jicequant.com/
Project-URL: Documentation, https://jicequant.com/
Project-URL: Repository, https://pypi.org/project/jcdata/
Keywords: finance,quant,market-data,china,a-share
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24
Requires-Dist: pandas>=1.3
Requires-Dist: pyarrow>=14
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"

# jcdata

`jcdata` 是 JCDATA 的 Python 客户端，用于获取市场数据、证券基础信息、因子、财务、ETF、期权、利率和宏观数据

## 安装

```bash
pip install jcdata
```

## 认证

使用访问令牌登录。请将令牌保存在环境变量或密钥管理系统中，禁止写入源码、笔记本、日志或版本控制系统。

```python
import jcdata

login_info = jcdata.login("YOUR_TOKEN")
if not login_info.get("user_name"):
    raise PermissionError("令牌无效、已过期或无访问权限")

print(login_info["user_name"])
print(login_info["cell_quota_remaining"])
```

也可使用环境变量：

```bash
# Linux / macOS
export JCDATA_TOKEN="YOUR_TOKEN"
```

```powershell
# Windows PowerShell
$env:JCDATA_TOKEN = "YOUR_TOKEN"
```

```python
jcdata.login()
```

令牌查找顺序为：`login(token=...)` 参数、`JCDATA_TOKEN` 环境变量。`login()` 返回用户名、接口使用量和剩余配额；认证未通过时这些字段为 `None`。

## 基本使用

```python
import jcdata

jcdata.login()

bars = jcdata.get_market_data(
    "600000.SH",
    "2025-01-02",
    "2025-01-10",
    fields=["date", "open", "high", "low", "close", "volume"],
)
frame = bars["600000.SH"]

if not frame.empty:
    print(frame.tail())
```

多数按证券代码查询的接口返回 `dict[str, pandas.DataFrame]`：字典 key 为请求代码，DataFrame 中不依赖 `symbol` 列分组。没有匹配数据时也会保留对应的空 DataFrame，因此请显式处理 `frame.empty`。

日期参数支持 `YYYY-MM-DD` 或 `YYYYMMDD`，例如 `2025-01-02` 或 `20250102`。

## 常用接口

| 分类 | 接口 |
|---|---|
| 日 K | `get_market_data`、`iter_market_data`、`iter_market_data_batches` |
| 基础信息 | `get_instrument`、`get_adj_factor`、`get_settlement`、`get_future_contract` |
| 股票扩展 | `get_factors`、`get_valuation`、`get_market_value`、`get_finance`、`get_money_flow`、`get_margin`、`get_leader_board` |
| 期权 | `get_market_data`、`get_option_greeks` |
| ETF | `get_etf_share`、`get_etf_tracking` |
| 日历与板块 | `get_trade_dates`、`get_all_sectors`、`get_stock_list_by_sector` |
| 利率与宏观 | `get_interest_rate`、`get_government_yield`、`get_macro_indicators` |

## 批量行情

直接传入代码列表即可查询多标的行情：

```python
symbols = ["600000.SH", "000001.SZ", "510300.SH"]
bars = jcdata.get_market_data(symbols, "2025-01-02", "2025-01-10", fields=["date", "close"])

for symbol, frame in bars.items():
    print(symbol, len(frame))
```

混合查询不同资产时，各 DataFrame 只返回该资产适用的字段。请按单个 DataFrame 的实际列名处理，不要假设所有资产具有相同字段。

```python
mixed = jcdata.get_market_data(["600000.SH", "IF2501.CFE"], "2025-01-02", "2025-01-10")
print(mixed["600000.SH"].columns.tolist())
print(mixed["IF2501.CFE"].columns.tolist())
```

## 复权

`get_market_data()` 支持股票、ETF 和可转债复权：

```python
adjusted = jcdata.get_market_data(
    "600000.SH",
    "2024-01-01",
    "2025-01-31",
    dividend_type="front",
    fields=["date", "close"],
)
```

可用 `dividend_type`：`none`、`front`、`back`、`point`。使用 `point` 时必须同时传 `adjust_date`。指数不参与复权。

## 大数据读取

代码数量较多但希望按代码处理时，使用 `iter_market_data()`：

```python
for chunk_symbols, frames in jcdata.iter_market_data(
    symbols,
    "2020-01-01",
    "2025-01-01",
    chunk_size=60,
    fields=["date", "close", "volume"],
):
    for symbol in chunk_symbols:
        process(frames[symbol])
```

超长历史数据使用 `iter_market_data_batches()`，并在循环内及时处理结果：

```python
for present_symbols, frames in jcdata.iter_market_data_batches(
    symbols,
    "2015-01-01",
    "2025-01-01",
    fields=["date", "close"],
    stream_batch_rows=65_536,
):
    for symbol in present_symbols:
        frames[symbol].to_parquet(f"{symbol}.parquet", index=False)
```

同一代码可能跨多个批次出现。请不要将全部批次累积到内存中。

## 错误处理

```python
try:
    jcdata.login()
    bars = jcdata.get_market_data("600000.SH", "2025-01-02", "2025-01-10")
except jcdata.CellQuotaExceededError as exc:
    print("配额已用尽，剩余：", exc.cell_quota_remaining)
except jcdata.InvalidParameterError as exc:
    print("参数错误：", exc.param, exc.value)
except PermissionError as exc:
    print("认证或授权失败：", exc)
```

`CellQuotaExceededError` 是 `PermissionError` 的子类，因此应优先捕获。参数问题会引发 `InvalidParameterError`，可通过 `.param` 和 `.value` 定位。对于无效代码或正常无数据区间，按代码查询接口一般返回空 DataFrame，而非异常。

## 更多说明

- 代码格式通常为 `代码.市场后缀`，例如 `600000.SH`、`000001.SZ`、`IF2501.CFE`。
- 使用 `get_asset_type_by_symbol()` 可识别常见代码的资产类型。
- 使用 `fields` 限定实际需要的列，可减少传输量和处理成本。
- 如遇访问频率或配额限制，请控制并发、缩小查询范围并保存任务进度。
