Metadata-Version: 2.4
Name: kdata-quant
Version: 2.0.3
Summary: K线数据下载与处理模块
Author-email: your name <you@example.com>
License: MIT
Requires-Python: <3.14,>=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.4.3
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
  from kdata import KDataError, KDataParamError, KDataFetchError
  ```

---

## ⚠️ 异常体系与最佳实践 (Exception Handling)

`kdata` 提供了结构化、分工明确的自定义异常类体系（定义于 `kdata.exceptions`，并通过顶层统一导出），便于调用方精准区分**参数校验与路由问题**与**网络与数据拉取问题**。

为了确保 100% 向后兼容已有业务代码，所有异常均采用**多重继承**设计：

| 异常类 | 继承关系 | 触发场景说明 |
| :--- | :--- | :--- |
| `KDataError` | `Exception` | 所有 `kdata` 业务异常的根基类。 |
| `KDataParamError` | `KDataError`, `ValueError` | 参数非法、周期不支持、代码混淆（如向 `get_any_ohlc` 误传大盘指数，或向 `get_index_ohlc` 误传个股/ETF）等。 |
| `KDataFetchError` | `KDataError`, `RuntimeError` | 网络超时、数据源接口拒绝/限流、标的无数据或所有备选数据源抓取均失败。 |

### 最佳捕获与调用模式：

```python
import kdata
from kdata import get_any_ohlc, KDataParamError, KDataFetchError

# 精准区分参数错误与网络抓取失败
try:
    df = get_any_ohlc("sh.600519", start_date="2024-01-01")
except KDataParamError as e:
    # 处理参数格式或周期不支持等问题
    print(f"输入参数错误: {e}")
except KDataFetchError as e:
    # 处理上游网络波动或数据拉取失败
    print(f"数据获取失败: {e}")
```

---

## 📌 数据规范与数据格式说明 (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. 复权规则与分红数据机制 (Adjustment & Dividends)

* **复权规则**: 
  - 个股与 ETF 默认直接返回前复权 (`'qfq'`) 数据，大盘指数使用不复权数据。
  - **Fail-Fast 原则**: 若在复权计算时发生分红除权数据拉取失败或因子对齐异常，系统严禁静默降级为未复权行情并禁止污染本地缓存，将显式抛出 `DividendFetchError` 或 `AdjustmentCalculationError` 专用异常。
* **分红数据机制**:
  - ETF/LOF 前复权依赖 `fund_fh_em_cache.parquet` 分红除息表。
  - 系统内置 7 天分红缓存 TTL，并在检测到除权事件时自动自愈历史 QFQ 缓存，确保历史序列无除权价格断层。
* **本地缓存**: 历史行情数据自动落地 Parquet（兼容历史 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_any_ohlc` - 自适应统一获取 K 线数据（核心推荐入口）

**描述**: `kdata` 推荐的核心统一入口。根据传入的标的代码（个股、ETF、大盘指数）或 `MarketIndex` 枚举，系统在底层自动识别标的类型并安全派发：
- **个股与 ETF 标的**：自动路由至个股存储引擎（`data/{market}/stocks/` 或 `etfs/`），默认进行前复权 (`qfq`) 处理；
- **大盘指数标的**：自动路由至指数独立存储引擎（`data/indices/`），不复权并保持点位真实历史轨迹。

> [!WARNING]
> **关于 `volume` 列物理含义的统一说明（关键）**：
> - **个股 (Stocks) & ETF**：`volume` 列代表**成交量 (Trading Volume)**，即成交的股数 (Shares) 或份数/手数 (Lots)。
> - **大盘指数 (Indices)**：`volume` 列代表**全市场成交金额 (Trading Amount / Turnover)**（单位：元/各市场货币）。因为大盘点位本身无实体股数，成交金额更能客观衡量全市场的流动性与活跃度。

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

# 1. 获取个股日 K 线（自动识别为个股，前复权）
df_stock = get_any_ohlc("sh.600519", start_date="2024-01-01", period=Period.DAILY)
print(df_stock.head())

# 2. 获取场内 ETF 日 K 线（自动识别为 ETF）
df_etf = get_any_ohlc("510300", start_date="2024-01-01")

# 3. 获取大盘指数日 K 线（自动识别为指数，隔离存储并保留真实点位）
df_index = get_any_ohlc("sh.000300", start_date="2024-01-01")

# 4. 使用 MarketIndex 枚举获取核心指数（支持 IDE 补全与防错）
df_sh   = get_any_ohlc(MarketIndex.SH, start_date="2024-01-01")    # 上证指数
df_hsi  = get_any_ohlc(MarketIndex.HSI, start_date="2024-01-01")   # 恒生指数
df_spx  = get_any_ohlc(MarketIndex.SP500, start_date="2024-01-01") # 标普500
```

**参数说明**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|------|------|
| `symbol` | str / MarketIndex | **是** | - | 标的代码（如 `'sh.600519'`, `'510300'`, `'sh.000300'`, `'hk.HSI'`, `'us.AAPL'`）或 `MarketIndex` 枚举 |
| `start_date` | str / datetime | 否 | `None` | 开始日期 (YYYY-MM-DD)，默认自动推导为 2023-01-01 或环境配置值 |
| `end_date` | str / datetime | 否 | `None` | 结束日期 (YYYY-MM-DD)，未指定则按所属市场取最新逻辑结算日 |
| `period` | Period / str | 否 | `Period.DAILY` | K线周期，支持日K (`Period.DAILY` / `'d'`) 或周K (`Period.WEEKLY` / `'w'`) |
| `**kwargs` | Any | 否 | - | 可选关键字参数（如 `skip_central_http=True` 跳过数据中心远程拉取） |

**返回值说明**: `pandas.DataFrame`
- **索引 (`Index`)**: `Date` (`DatetimeIndex`，标准化为北京时间 UTC+8)
- **列 (`Columns`)**: `open`, `high`, `low`, `close`, `volume`
- **底层存储**: 个股/ETF 存入 `K_DATA_CENTER/{start}_{end}/`，指数存入 `K_DATA_CENTER/indices/`

---

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

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

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

daily_df = get_any_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_overview` - 市场宏观全貌快照

**描述**: 一站式拉取并汇总包含核心指数、行业板块排名、涨跌停、两融余额、市场情绪、全球主要指数的完整宏观快照字典，自动落盘存储于 `data/market/` 目录。

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

overview = get_market_overview(include_global=True, include_hk=True)
print("包含宏观维度:", list(overview.keys()))
```

---

### 7. `get_index_history` - 核心指数近期多日行情

**描述**: 获取主要指数近 N 个交易日的历史行情序列字典。

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

hist = get_index_history(days=10, include_global=True)
print(hist["上证指数"].tail())
```

---

## 📈 二、市场资产规模 (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)

系统附带 6 个开箱即用的终端命令行工具，安装包后可直接在命令行调用，无需编写 Python 代码：

1. **`kdata-download`**: 单标的/批量 K 线数据下载器
   ```bash
   # 单只股票/ETF K线下载 (指定日期范围)
   kdata-download sh.600519 2024-01-01 2024-12-31

   # 单只指数下载
   kdata-download sh.000300 2024-01-01 2024-12-31

   # 根据 YAML 配置文件批量下载
   kdata-download -b data/etf/config_etf.yaml
   kdata-download -b data/china/config_a.yaml
   ```

2. **`kdata-market`**: 大盘市场概览与多市场指数快照
   ```bash
   # A 股主要指数快照与概览
   kdata-market --cn

   # 港股主要指数概览
   kdata-market --hk

   # 美股主要指数概览
   kdata-market --usa

   # 全球全市场综合概览
   kdata-market --all
   ```

3. **`kdata-etf`**: ETF 规模筛选、成交额过滤与配置导出
   ```bash
   # 更新本地 ETF 元数据与规模缓存
   kdata-etf update

   # 过滤规模 >= 100亿 且 日均成交额 >= 1亿 的高流动性 ETF
   kdata-etf filter --min-scale 100 --min-vol 1

   # 导出规模 >= 50亿 的 ETF 配置列表到 YAML
   kdata-etf export --min-scale 50 -o target.yaml
   ```

4. **`kdata-premium`**: 单只 ETF 实时/历史折溢价率与 IOPV 分析
   ```bash
   # 获取 513100 实时溢价快照
   kdata-premium 513100 --snapshot

   # 获取 513100 指定日期范围的历史溢价序列
   kdata-premium 513100 2024-01-01 2024-12-31
   ```

5. **`kdata-scan`**: 全市场 ETF/LOF 实时折溢价套利机会扫描器
   ```bash
   # 扫描默认资金池
   kdata-scan

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

   # 筛选折价率 >= 3% 的标的
   kdata-scan --min-discount-pct 3 --simple
   ```

6. **`kdata-serve`**: 启动 HTTP 中心数据中继服务 (Central Hub)
   ```bash
   # 在指定端口启动 HTTP 数据中心服务 (供各客户端作为统一数据源代理访问)
   kdata-serve --host 0.0.0.0 --port 8765
   ```

   **核心 HTTP 端点与标的隔离规范**:
   - **`GET /ohlc`**: 个股与场内 ETF 历史 K 线（前复权）。**严格禁止传入大盘指数**，若误传大盘指数，服务端将拦截并返回 **HTTP 404**（响应正文说明具体原因）。
   - **`GET /market/history`**: 大盘基准指数历史 K 线（不复权）。**严格禁止传入普通个股或 ETF**，若误传普通个股，服务端将拦截并返回 **HTTP 404**。
   - **`GET /market/indices`**: 核心市场指数最新行情截面快照表。
   - **`GET /market/overview`**: 宏观市场全貌快照字典（多空家数、两融、板块排名等）。

   *注：当 Python 客户端（配置了 `KDATA_CENTRAL_URL`）请求服务端收到 404、429 或网络异常时，系统将自动无感降级回退至本地数据源链，不会中断业务运行。*

---

## 🔧 四、基础工具与辅助配置 (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)

### 1. `Period` - K 线周期枚举
```python
from kdata import Period

Period.DAILY   # 日线周期 ('d')
Period.WEEKLY  # 周线周期 ('w')
```

### 2. `DownloadProvider` - 行情下载数据源枚举
```python
from kdata import DownloadProvider

DownloadProvider.AUTO  # 默认自动模式（系统自动调度并在多数据源间无感降级备份，外部调用推荐使用此项）
```

### 3. `MarketIndex` - 核心大盘指数枚举
`MarketIndex` 枚举整合了跨市场的核心基准指数，传入 `get_index_ohlc` 时具备代码防错与 IDE 智能补全支持：

| 市场 | 枚举成员 | 中文名称 (枚举值) | 映射标准代码 | 资产代表说明 |
| :--- | :--- | :--- | :--- | :--- |
| **A股** | `MarketIndex.SH` | `"上证指数"` | `sh.000001` | 上证综合指数 |
| | `MarketIndex.SZ` | `"深证成指"` | `sz.399001` | 深证成份指数 |
| | `MarketIndex.CYB` | `"创业板指"` | `sz.399006` | 创业板指 |
| | `MarketIndex.KC50` | `"科创50"` | `sh.000688` | 上证科创板50成份指数 |
| | `MarketIndex.KCZZ` | `"科创综指"` | `sh.000680` | 上证科创板综合指数 |
| | `MarketIndex.HS300` | `"沪深300"` | `sh.000300` | 沪深300指数 |
| | `MarketIndex.ZZ500` | `"中证500"` | `sh.000905` | 中证500指数 |
| **港股** | `MarketIndex.HSI` | `"恒生指数"` | `hk.HSI` | 恒生指数 |
| | `MarketIndex.HSTECH` | `"恒生科技指数"` | `hk.HSTECH` | 恒生科技指数 |
| **美股** | `MarketIndex.SP500` | `"标普500"` | `us.SPY` | 标普500指数 |
| | `MarketIndex.NASDAQ` | `"纳斯达克"` | `us.QQQ` | 纳斯达克100指数 |
| | `MarketIndex.DJI` | `"道琼斯"` | `us.DIA` | 道琼斯工业平均指数 |

**调用示例**:
```python
from kdata import MarketIndex, get_index_ohlc

# 使用枚举直接获取指数历史 K 线
df_sh = get_index_ohlc(MarketIndex.SH, start_date="2024-01-01")
df_hsi = get_index_ohlc(MarketIndex.HSI, start_date="2024-01-01")
df_spx = get_index_ohlc(MarketIndex.SP500, start_date="2024-01-01")
```

---

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

1. **自动多源降级**: `AUTO` 调度模式下，EFinance, Akshare, Mootdx, Baostock 互为备份。单个数据源遭遇网络波动或频控时，系统会自动无感切换备份数据源。
2. **高效增量缓存**: 所有下载的历史 K 线数据落地本地缓存（默认优先 Parquet，兼容历史 CSV）。二次查询时增量补全，极大减少网络 API 调用开销。
3. **时区与日期防错**: 交易日期统一处理为北京时间 (CST) 00:00:00 对应交易日，避免跨时区或盘后交易日推导偏差。
4. **批量下载与并发控制 (Pacing)**:
   系统遵循 *Gentle on Providers* 原则以保障数据抓取的长期稳定性。若配置了 Central Hub (`KDATA_CENTRAL_URL`)，当服务端队列负载过高触发 429 限流保护时，内部已自动记录退避并平滑降级到本地行情源，**不会向外部抛出异常中断程序**。
   - **外部调用方最优做法**：
     如果外部是多线程/多进程批量下载任务（如 `ThreadPoolExecutor`）：
     - 将线程并发数调小（建议并发在 2 ~ 4 之间）。
     - 在批量循环中保留微小间隔（如 `time.sleep(0.05 ~ 0.1)`）。
