Metadata-Version: 2.4
Name: kdata-quant
Version: 1.1.2
Summary: K线数据下载与处理模块
Author-email: your name <you@example.com>
License: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=3.0.0
Requires-Dist: numpy>=1.22
Requires-Dist: baostock>=0.8.9
Requires-Dist: akshare>=1.18
Requires-Dist: efinance>=0.5.5
Requires-Dist: aiohttp>=3.13.2
Requires-Dist: requests>=2.32.5
Requires-Dist: lxml>=6.0.2
Requires-Dist: beautifulsoup4>=4.14.2
Requires-Dist: python-dateutil>=2.9.0
Requires-Dist: pytz>=2025.2
Requires-Dist: matplotlib>=3.10.0
Requires-Dist: mplfinance>=0.12.10b0
Requires-Dist: TA-Lib>=0.4.0
Requires-Dist: fear-and-greed>=0.4
Requires-Dist: build>=1.3.0
Requires-Dist: setuptools>=80.9.0
Requires-Dist: wheel>=0.45.1
Requires-Dist: pyyaml>=6.0
Requires-Dist: mootdx2>=1.0.8
Requires-Dist: ruamel-yaml>=0.18.17
Requires-Dist: py-mini-racer>=0.6.0
Requires-Dist: longport>=3.0.0
Requires-Dist: python-dotenv>=1.0.1
Requires-Dist: yfinance>=0.2.0
Requires-Dist: pandas-market-calendars>=5.4.0
Requires-Dist: pyarrow>=14.0.0
Provides-Extra: dev
Requires-Dist: pytest>=9.0.2; extra == "dev"
Dynamic: license-file

# kdata 模块核心 API 接口文档 (独立对外版)

`kdata` 是一个专注于量化行情数据获取和分析的 Python 本地开发包。它高度整合了多种行情数据源（如 Efinance, Akshare, Mootdx 等），为量化交易与数据分析提供一站式、高性能、自动本地缓存的极简接口。

本规范文档完全独立自包含，无需依赖其他说明文件即可独立查阅使用。

---

## 📖 快速开始与环境要求

* **Python 版本**: Python >= 3.11
* **安装与引用**:
  ```bash
  pip install kdata
  ```
  ```python
  import kdata
  ```

---

## 📌 数据规范与数据格式说明 (Data Specifications)

本项目统一使用 `pandas.DataFrame` 作为 K 线数据的手持结构，标准列名为 `open`, `high`, `low`, `close`, `volume`，索引 (Index) 为交易日期 `Date` (`DatetimeIndex`)。

### 1. 字段定义表

| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `Date` | `DatetimeIndex` | 交易日期，级别通常为日 (Daily) 或周 (Weekly)，统一归一化为北京时间 (UTC+8)。 |
| `open` | `float` | 开盘价：该周期内的第一笔成交价格。 |
| `high` | `float` | 最高价：该周期内的最高成交价格。 |
| `low` | `float` | 最低价：该周期内的最低成交价格。 |
| `close` | `float` | 收盘价：该周期的最后一笔成交价格。 |
| `volume` | `float` | 成交活跃度指标（**物理含义随标的资产类型自动适配**，详见下文）。 |

### 2. 关于 `volume` 列物理含义的统一说明

为了保持接口一致性，本库统一使用 `volume` 列名，但其物理含义根据标的自动切换：
1. **个股 (Stocks) & ETF**: `volume` 代表 **成交量 (Trading Volume)**，即成交的股数 (Shares) 或手数 (Lots)。
2. **大盘指数 (Indices)**: `volume` 代表 **成交金额 (Trading Amount / Turnover)**。因为大盘指数无实体发行股数，成交金额更能真实反映全市场的流动性与活跃度。

### 3. 复权与时区处理

* **复权规则**: 个股与 ETF 默认直接集成前复权 (`'qfq'`) 数据，指数使用不复权数据。
* **本地缓存**: 历史行情数据自动落地 CSV 本地缓存。缓存命中时不发起重复网络请求，避免受网络波动或频控影响。

---

## 🏷️ 标的代码命名规范 (Symbol Formats)

| 资产类别 | 代码格式示例 | 说明 |
| :--- | :--- | :--- |
| **A股 股票/指数** | `sh.600519`, `sz.000001`, `sh.000300` | `sh.` / `sz.` + 6位代码 |
| **港股 股票/指数** | `hk.00700`, `hk.HSI` | `hk.` + 5位代码或指数缩写 |
| **美股 股票/指数** | `us.AAPL`, `us.GSPC` | `us.` + 股票代码或指数缩写 |
| **场内 ETF / LOF** | `510300`, `513100`, `161129` | 6位基金代码 |

---

## 📊 一、核心行情数据获取 (Core Data Fetching)

### 1. `get_ohlc` - 获取任意标的 K 线数据

**描述**: 获取股票、ETF、指数历史 K 线数据的核心入口，支持多周期和多市场。

**代码示例**:
```python
from kdata import get_ohlc, Period, DownloadProvider

df = get_ohlc(
    stock_code='sh.600519',      # 标的代码
    start_date='2023-01-01',     # 开始日期 (YYYY-MM-DD)
    end_date='2023-12-31',       # 结束日期 (YYYY-MM-DD)
    period=Period.DAILY,         # 周期：Period.DAILY 或 Period.WEEKLY
    download_provider=DownloadProvider.AUTO
)
print(df.head())
```

**参数说明**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|------|------|
| `stock_code` | str | **是** | - | 标的代码，如 `sh.600519`, `sz.000001`, `hk.HSI`, `us.AAPL` |
| `start_date` | str / datetime | 否 | `None` | 开始日期 (YYYY-MM-DD)，默认自动推导为各数据源最早日期 |
| `end_date` | str / datetime | 否 | `None` | 结束日期 (YYYY-MM-DD)，默认自动推导为最新交易日 |
| `period` | Period / str | 否 | `Period.DAILY` | K线周期，支持 `Period.DAILY` / `Period.WEEKLY` 或 `'d'` / `'w'` |
| `download_provider`| DownloadProvider / str| 否 | `DownloadProvider.AUTO` | 指定数据源，`AUTO` 模式自动进行备份源切换与降级 |

**返回值说明**: `pandas.DataFrame`
- **索引 (`Index`)**: `Date` (`DatetimeIndex`)
- **列 (`Columns`)**: `open`, `high`, `low`, `close`, `volume`

---

### 2. `get_index_ohlc` - 指数行情获取

**描述**: 使用大盘指数枚举值便捷获取核心指数的历史 K 线数据（内部自动完成代码转换并调用底层下载引擎）。

**代码示例**:
```python
from kdata import get_index_ohlc, MarketIndex

# 获取上证指数历史行情
df_sh = get_index_ohlc(
    index_enum=MarketIndex.SH, 
    start_date='2023-01-01', 
    end_date='2023-12-31'
)
print(df_sh.tail())
```

**参数说明**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|------|------|
| `index_enum` | MarketIndex | **是** | - | 大盘指数枚举值，如 `MarketIndex.SH`, `MarketIndex.SZ`, `MarketIndex.HS300` |
| `start_date` | str / datetime | 否 | `None` | 开始日期 (YYYY-MM-DD) |
| `end_date` | str / datetime | 否 | `None` | 结束日期 (YYYY-MM-DD) |
| `period` | Period / str | 否 | `Period.DAILY` | K线周期，支持 `Period.DAILY` 或 `Period.WEEKLY` |

**返回值说明**: `pandas.DataFrame`（列名: `open`, `high`, `low`, `close`, `volume`；索引: `Date`）

---

### 3. `generate_weekly_kdata` - 日K转换为周K数据

**描述**: 将日 K 线 DataFrame 自动重采样并合成为符合标准的周 K 线 DataFrame。

**代码示例**:
```python
from kdata import get_ohlc, generate_weekly_kdata, Period

daily_df = get_ohlc('sh.600519', start_date='2023-01-01', period=Period.DAILY)
weekly_df = generate_weekly_kdata(daily_df)
```

**参数说明**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `df` | pandas.DataFrame | **是** | 含有 `open`, `high`, `low`, `close`, `volume` 列及 `Date` 索引的日 K 线数据 |

**返回值说明**: `pandas.DataFrame`（周K线结构，按每周最后一个交易日聚合并重采样）

---

### 4. `get_market_breadth` - 市场广度指标

**描述**: 获取 A 股全市场多空家数与涨跌停历史统计数据。

**代码示例**:
```python
from kdata import get_market_breadth

df = get_market_breadth(days=5)
print(df)
```

**参数说明**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|------|------|
| `days` | int | 否 | `5` | 回溯的历史交易天数 |

**返回值说明**: `pandas.DataFrame`
- **列 (`Columns`)**: `日期`, `上涨家数`, `下跌家数`, `涨停家数`, `跌停家数`

---

### 5. `get_sector_ranking` - 行业板块排名

**描述**: 获取全市场行业板块领涨/领跌排名数据。

**代码示例**:
```python
from kdata import get_sector_ranking

# 返回元组: (领涨 TOP N 板块 DataFrame, 领跌 TOP N 板块 DataFrame)
top_sectors, bottom_sectors = get_sector_ranking(top_n=10)
```

**参数说明**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|------|------|
| `top_n` | int | 否 | `10` | 提取的前 N 个领涨/领跌板块数量 |

**返回值说明**: 包含两个 `pandas.DataFrame` 的元组 `(top_sectors, bottom_sectors)`
- **列 (`Columns`)**: `板块名称`, `涨跌幅%`, `上涨家数`, `下跌家数`, `领涨股票`, `领涨股票涨幅%`

---

### 6. `get_market_sentiment` - 市场情绪指标概览

**描述**: 一站式获取 A 股综合市场情绪快照字典。

**代码示例**:
```python
from kdata import get_market_sentiment

sentiment = get_market_sentiment()
print(sentiment)
```

**返回值说明 (`dict`)**:
```python
{
    'advances': 2345,          # 上涨家数 (int)
    'declines': 1567,          # 下跌家数 (int)
    'adv_dec_ratio': 1.5,      # 涨跌家数比 advances / declines (float)
    'limit_up': 89,            # 涨停家数 (int)
    'limit_down': 12,          # 跌停家数 (int)
    'margin_balance': 1520.45, # 两融余额，单位：亿元 (float)
    'margin_change_pct': 0.12  # 两融余额较前一日变动比例 % (float)
}
```

---

### 7. 大盘指数概览与明细 (`get_market_indices_overview` / `get_market_indices_details`)

**描述**: 批量获取国内 (A股)、港股、全球主要大盘指数的行情概览与历史明细数据。

**代码示例**:
```python
from kdata import get_market_indices_overview, get_market_indices_details

# 1. 核心指数最新摘要表 (含最新收盘、涨跌幅、成交额)
overview_df = get_market_indices_overview(show_cn=True, show_hk=True, show_usa=True)

# 2. 核心指数历史明细字典
details_dict = get_market_indices_details(show_cn=True, start_date='2024-01-01')
```

**参数说明 (`get_market_indices_overview`)**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|------|------|
| `show_cn` | bool | 否 | `True` | 是否展示 A 股核心指数 (如 上证、深证、创业板、沪深300) |
| `show_hk` | bool | 否 | `True` | 是否展示港股核心指数 (如 恒生指数、国企指数) |
| `show_usa` | bool | 否 | `True` | 是否展示美股及全球核心指数 (如 标普500、纳斯达克、道琼斯) |

---

## 📈 二、市场资产规模 (Market Asset Scale)

### 8. `get_etf_scale` - ETF 资产规模查询

**描述**: 获取 ETF 资产管理规模数据（单位：亿元）。

**代码示例**:
```python
from kdata import get_etf_scale

# 1. 单个代码：返回 float
scale = get_etf_scale('513120')                 # 返回: 114.2 

# 2. 代码列表：返回 {code: scale_float} 字典
scales_dict = get_etf_scale(['513120', '513100'])
```

**参数说明**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `symbol` | str / list / tuple / set | **是** | 单个 6 位 ETF 代码字符串，或 ETF 代码容器列表 |

**返回值说明**: 传入单个字符串返回 `float`（规模，亿元）；传入列表等容器返回 `Dict[str, float]`。

---

### 9. 大盘快照 `get_cn_indices` / `get_hk_indices` / `get_global_indices`

**描述**: 快速拉取国内、港股、全球主要大盘指数的最新行情快照 DataFrame。

```python
from kdata import get_cn_indices, get_hk_indices, get_global_indices

cn_df = get_cn_indices()        # 国内主要指数 DataFrame
hk_df = get_hk_indices()        # 港股核心指数 DataFrame
global_df = get_global_indices()# 全球核心指数 DataFrame
```

---

## 🛠️ 三、高级 ETF/LOF 溢价套利组件 (Arbitrage & Premiums)

### 概念解析
* **IOPV (实时参考净值)**: 盘中由交易所实时计算并发布的基金份额参考净值。
* **NAV (单位净值)**: 基金公司官方公布的每股净资产值。
* **折溢价率%**: 计算公式为 `(价格 - 净值) / 净值 * 100`。
* **LOF(S) 说明**: S 代表 Stale (过期/上日净值)，表示盘中无实时 IOPV 估值，使用前一日净值参考。

---

### 10. `Scanner` - ETF/LOF 溢价监控扫描器

**描述**: 批量抓取 ETF/LOF 实时价格与净值以计算折溢价率，支持一键筛选 Top 溢价/深折价标的及场内赎回费率提取。

**代码示例**:
```python
from kdata import Scanner  # 或 from kdata.scanner import Scanner
from mootdx.quotes import Quotes

# 1. 初始化扫描器 (client 可选，默认自动创建 Quotes.factory(market="std"))
scanner = Scanner(f10_workers=12)

# 2. 加载资金池 (支持 YAML 配置文件解析)
etf_universe = Scanner.load_universe('data/etf/config_etf.yaml')

# 3. 执行实时折溢价扫描
scan_df = scanner.scan(etf_universe)

# 4. 批量补充场内赎回费率
scan_df = scanner.add_fees(scan_df)
print(scan_df.head())

# 5. 快捷获取 Top 10 溢价/折价标的 (自动异步补全 F10 标的/官方/赎回费)
all_df, top_premium, top_discount = scanner.scan_prospects(
    etf_universe, top_n=10, simple=False
)
```

**`Scanner` 构造函数与方法说明**:
| 方法/属性 | 参数类型 | 返回值 | 说明 |
| :--- | :--- | :--- | :--- |
| `Scanner(client=None, f10_workers=12)` | `client`:  Quotes 实例<br>`f10_workers`: int | `Scanner` | 创建扫描器引擎。`f10_workers` 设置 F10 并行下载线程数（0 表示禁用预取）。 |
| `Scanner.load_universe(yaml_path)` | `yaml_path`: str | `list[dict]` | 从 YAML 文件解析加载 ETF/LOF 资金池。返回 `[{"code": "510300", "name": "300ETF"}, ...]` |
| `scanner.scan(etf_universe)` | `etf_universe`: list[dict] | `DataFrame` | 对资金池标的执行实时报价与净值扫描，计算溢价率。 |
| `scanner.add_fees(df)` | `df`: DataFrame | `DataFrame` | 从 F10 解析场内赎回费规则并补充 `'赎回费'` 列（就地修改并返回）。 |
| `scanner.scan_prospects(...)` | `top_n`: int<br>`simple`: bool<br>`min_discount_pct`: float | `tuple[DF, DF, DF]` | 一键返回 `(全量数据, Top溢价表, Top折价表)`，内部自动提取并补充 F10 信息。 |

**`scan` 返回的 DataFrame 列结构**:
| 列名 | 说明 |
| :--- | :--- |
| `代码` | 证券代码 (如 `'513100'`) |
| `名称` | 基金简称 (如 `'纳指100ETF'`) |
| `价格` | 盘口实时现价 |
| `净值` | IOPV 估算净值或上日官方净值 |
| `溢价率%` | 实时折溢价率 (%) |
| `标的` | 跟踪标的指数名称 |
| `官方` | 是否为官方/标准指数 (`'是'`, `'否'`, `'未知'`) |
| `时间` | 报价更新时间戳 (`'HH:MM:SS'`) |
| `类型` | `'ETF'`, `'LOF'`, `'LOF(S)'` |
| `T+0` | 是否支持 T+0 交易 (`'是'`, `'否'`) |
| `赎回费` | 场内赎回费率规则 (调用 `add_fees` 追加) |

---

### 11. `get_etf_premium_data` - ETF 估算溢价率数据序列

**描述**: 获取指定 ETF 历史价格及最新估算净值的溢价率数据序列。

**代码示例**:
```python
from kdata import get_etf_premium_data  # 或 from kdata.premium import get_etf_premium_data

df = get_etf_premium_data(
    symbol='513100', 
    start_date='2026-07-01', 
    end_date='2026-07-24'
)
print(df.tail())
```

**参数说明**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `symbol` | str | **是** | ETF / LOF 代码，如 `'513100'`, `'513120'` |
| `start_date` | str | **是** | 开始日期 `'YYYY-MM-DD'` |
| `end_date` | str | **是** | 结束日期 `'YYYY-MM-DD'` |

**返回值与列说明**: `pandas.DataFrame`
- **索引 (`Index`)**: `Date` (`DatetimeIndex`)
- **列 (`Columns`)**:
  - `close`: 每日收盘价 (`float`)
  - `NAV(IOPV_时间)`: 单位净值/IOPV（列名含时间戳后缀，如 `NAV(IOPV_15:30:00)`）
  - `premium`: 绝对折溢价差额 = `close - NAV` (`float`)
  - `premium_rate`: 折溢价率(%) = `(premium / NAV) * 100` (`float`)

---

### 12. `get_latest_etf_premium` - 单只 ETF 最新溢价快照

**描述**: 获取单只 ETF 实时最新价格、净值和折溢价快照字典。

**代码示例**:
```python
from kdata import get_latest_etf_premium  # 或 from kdata.premium import get_latest_etf_premium

info = get_latest_etf_premium('513100')
print(info)
```

**参数说明**:
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `symbol` | str | **是** | ETF / LOF 代码，如 `'513100'`, `'513120'` |

**返回字典字段解析 (`dict`)**:
```python
{
    'code': '513100',              # 证券代码 (str)
    'name': '纳指100ETF',          # 基金简称 (str)
    'price': 2.104,                # 实时盘口现价 (float)
    'nav': 2.085,                  # 单位净值/IOPV (float 或 None)
    'premium_rate': 0.911,         # 实时折溢价率 % (float 或 None)
    'updated': '2026-07-24'        # 净值更新日期/时间戳 (str 或 None)
}
```

---

### 13. 命令行终端工具 (CLI Commands)

系统附带开箱即用的终端命令行工具，无需编写 Python 代码：

1. **`kdata-premium`**: 单只 ETF 溢价分析
   ```bash
   # 获取 513100 实时溢价快照
   kdata-premium 513100 --snapshot

   # 获取 513100 指定日期范围的历史溢价序列
   kdata-premium 513100 2026-07-01 2026-07-24
   ```

2. **`kdata-scan`**: 批量 ETF/LOF 折溢价扫描
   ```bash
   # 扫描默认资金池
   kdata-scan

   # 简易加速模式 (跳过 F10 拉取)
   kdata-scan --simple
   ```

---

## 🔧 四、基础工具与辅助配置 (Utils & Env)

### 14. `init_env` / `get_data_dir`

**描述**: 管理 `kdata` 本地缓存数据目录与环境初始化。

```python
from kdata import init_env, get_data_dir

data_dir = get_data_dir()  # 返回缓存目录路径，默认: ~/.kdata
init_env(force=True)       # 强制重置并重建本地缓存索引结构
```

---

### 15. `get_name_from_code`

**描述**: 通过代码反查股票、ETF 或大盘指数的官方中文名称。

```python
from kdata import get_name_from_code

name = get_name_from_code('sh.600519')  # 返回: '贵州茅台'
```

---

## 📋 五、枚举与常量定义 (Constants)

```python
from kdata import Period, MarketIndex, DownloadProvider

Period.DAILY          # 日线周期枚举 ('d')
Period.WEEKLY         # 周线周期枚举 ('w')
MarketIndex.SH        # 上证指数枚举值
DownloadProvider.AUTO # 自动多源调度
```

---

## 💡 六、最佳实践与设计原理

1. **自动多源降级**: `AUTO` 调度模式下，EFinance, Akshare, Mootdx, Baostock 互为备份。单个数据源遭遇网络波动或频控时，系统会自动无感切换备份数据源。
2. **高效增量缓存**: 所有下载的历史 K 线数据落地本地 CSV。二次查询时增量补全，极大减少网络 API 调用开销。
3. **时区与日期防错**: 交易日期统一处理为北京时间 (CST) 00:00:00 对应交易日，避免跨时区或盘后交易日推导偏差。
