Metadata-Version: 2.4
Name: finsight-data
Version: 1.0.1
Summary: Client SDK for FinSight read-only latest-trade-day data API
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.31.0

# FinSight Data SDK

FinSight 数据服务提供只读行情接口。实时接口只支持全市场统一快照，不支持按单个股票代码查询。

## 1. 安装

```bash
pip install finsight-data
```

## 2. 初始化

```python
from finsight_data import FinSightDataClient

client = FinSightDataClient(token="YOUR_DATA_API_TOKEN")
```

完整示例脚本见 `examples/finsight_data_demo.py`。

| 参数 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- |
| `token` | 是 | `str` | 数据接口 token |
| `timeout` | 否 | `int` | 请求超时秒数，默认 `20` |
| `allow_rebind` | 否 | `bool` | 初始化时是否允许将 token 迁移到当前设备，默认 `False` |

初始化会自动校验 token 并完成当前设备绑定。后续数据接口不需要再传设备绑定参数。

## 3. 最新交易日板块资金流向

```python
data = client.get_stock_sector_fund_flow_daily_latest(
    board_type="行业",
    keyword="半导体",
    limit=50,
    offset=0,
)
```

数据口径：按最新交易日返回板块资金流 Top50。`board_type` 为空时，返回行业、概念、板块三类各 Top50；指定类型时，返回该类型 Top50。

| 参数 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- |
| `board_type` | 否 | `str` | 板块类型：`行业`、`概念`、`板块`；为空表示不限 |
| `keyword` | 否 | `str` | 按板块代码或名称搜索 |
| `limit` | 否 | `int` | 返回条数，最大 `50`，默认 `50` |
| `offset` | 否 | `int` | 偏移量，默认 `0` |

输出：

```json
{
  "ok": true,
  "trade_date": "2026-05-18",
  "total": 86,
  "items": [
    {
      "code": "BK1036",
      "name": "半导体",
      "board_type": "行业",
      "pct_chg": 2.15,
      "main_net_inflow_amount": 123456789.0,
      "main_net_inflow_ratio": 4.32
    }
  ]
}
```

## 4. 最新交易日个股资金流向

```python
data = client.get_stock_individual_fund_flow_daily_latest(
    codes=["600519", "000858"],
    keyword="",
    limit=100,
    offset=0,
)
```

| 参数 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- |
| `codes` | 否 | `list[str]` | 股票代码列表；为空表示不限 |
| `keyword` | 否 | `str` | 按股票代码或名称搜索 |
| `limit` | 否 | `int` | 返回条数；不填返回筛选后的全部结果 |
| `offset` | 否 | `int` | 偏移量，默认 `0` |

输出：

```json
{
  "ok": true,
  "trade_date": "2026-05-18",
  "total": 2,
  "items": [
    {
      "code": "600519",
      "name": "贵州茅台",
      "latest_price": 1688.0,
      "pct_chg": 1.25,
      "main_net_inflow_amount": 123456789.0,
      "main_net_inflow_ratio": 3.21
    }
  ]
}
```

## 5. 最新交易日前复权日线

```python
data = client.get_stock_daily_kline_q_latest(
    codes=["600519"],
    keyword="",
    limit=100,
    offset=0,
)
```

| 参数 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- |
| `codes` | 否 | `list[str]` | 股票代码列表；为空表示不限 |
| `keyword` | 否 | `str` | 按股票代码搜索 |
| `limit` | 否 | `int` | 返回条数；不填返回筛选后的全部结果 |
| `offset` | 否 | `int` | 偏移量，默认 `0` |

输出：

```json
{
  "ok": true,
  "trade_date": "2026-05-18",
  "total": 1,
  "items": [
    {
      "code": "600519",
      "open_price": 1680.0,
      "close_price": 1688.0,
      "high_price": 1699.0,
      "low_price": 1666.0,
      "volume": 123456,
      "amount": 234567890.0,
      "pct_chg": 1.25
    }
  ]
}
```

## 6. 实时全市场个股快照

单次拉取：

```python
frame = client.get_realtime_full_market_snapshot(include_rows=True)
print(frame["seq"], frame["timestamp"], frame["returned_rows"])
```

持续接收：

```python
for frame in client.iter_realtime_full_market_snapshot():
    print(frame["seq"], frame["timestamp"], frame["returned_rows"])
```

模拟实盘：

```python
for frame in client.iter_realtime_full_market_snapshot(
    simulate_live=True,
    simulation_interval_seconds=1,
):
    print(frame["simulate_live"], frame["seq"])
```

| 参数 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- |
| `include_rows` | 否 | `bool` | 是否返回解压后的 `rows`，默认 `True` |
| `keep_packed_rows` | 否 | `bool` | 解压后是否保留 `rows_gzip_b64` |
| `simulate_live` | 否 | `bool` | 是否启用模拟实盘模式 |
| `simulation_interval_seconds` | 否 | `float` | 模拟实盘推送间隔 |
| `reconnect` | 否 | `bool` | SSE 断线后是否自动重连，仅持续接收接口支持 |
| `max_reconnects` | 否 | `int` | 最大自动重连次数，仅持续接收接口支持 |

输出：

```json
{
  "ok": true,
  "mode": "full_market_only",
  "data_key": "full_market",
  "seq": 123456,
  "timestamp": "2026-05-18 09:31:03",
  "total": 5300,
  "cols": ["code", "name", "price", "pct_chg", "zljlr"],
  "sorted_by": "zljlr_desc",
  "packed": true,
  "min_interval_seconds": 3,
  "token_scope": "data_api",
  "rows": [
    ["600000", "浦发银行", 10.25, 1.18, 28340000.0]
  ],
  "returned_rows": 5300
}
```

## 7. Token 用量

```python
usage = client.get_token_usage()
print(usage["summary"]["day"]["remaining"])
```

输出：

```json
{
  "ok": true,
  "service": "finsight-data",
  "token_scope": "data_api",
  "account": {
    "username": "demo_user",
    "is_admin": false
  },
  "device_binding": {
    "mode": "bind_on_first_use",
    "is_bound": true,
    "rebind_remaining": 1
  },
  "summary": {
    "day": {
      "limit": 100,
      "used": 2,
      "remaining": 98,
      "resets_at": "2026-05-19T00:00:00+08:00"
    }
  },
  "endpoints": []
}
```

## 8. 错误码

| 状态码 | 说明 |
| --- | --- |
| `400` | 参数错误 |
| `401` | token 缺失或无效 |
| `403` | token 无权限、设备不匹配或实时接口不在可用时段 |
| `429` | 频率、额度、并发或队列限制 |
| `503` | 服务滚动更新中，请稍后重试 |
