Metadata-Version: 2.4
Name: alphakit-sdk
Version: 0.2.3
Summary: AlphaKit — 简洁的金融数据 API 工具包
Author: AlphaKit Team
License: MIT
Project-URL: Homepage, https://github.com/yourusername/alphakit
Keywords: finance,data,api,quant,alpha
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: License :: OSI Approved :: MIT License
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28.0
Requires-Dist: pandas>=1.3.0

# AlphaKit SDK 使用指南

AlphaKit 是一个简洁的金融数据 API 工具包，提供便捷的 A 股市场数据访问接口。

## 快速开始

### 1. 安装

```bash
pip install alphakit-sdk
```

### 2. 获取 Token

Token 仅在创建时显示一次，请妥善保存；如果丢失，请联系管理员。

### 3. 基础使用

```python
import alphakit as ak

# 设置 token（全局配置，只需设置一次）
ak.set_token('your_token_here')

# 创建 API 客户端
api = ak.AlphaKit()

# 获取股票最近一年的日线数据（默认）
df = api.daily(ts_code='000001.SZ')
print(df)
```

## 客户端初始化

```python
import alphakit as ak

# 方式1：使用全局 token
ak.set_token('your_token_here')
api = ak.AlphaKit()

# 方式2：实例化时传入 token
api = ak.AlphaKit(token='your_token_here')
```

## API 接口说明

### 股票基础数据

#### 股票列表 - `stock_basic`

```python
# 获取所有股票基本信息
df = api.stock_basic()

# 获取指定股票信息
df = api.stock_basic(ts_code='000001.SZ')
```

#### 股票日线行情 - `daily` ⭐

```python
# 只传 ts_code 时，自动获取最近一年的数据（最常用）
df = api.daily(ts_code='000001.SZ')

# 获取指定股票指定日期的行情
df = api.daily(ts_code='000001.SZ', trade_date='20260613')

# 获取指定日期所有股票行情
df = api.daily(trade_date='20260613')

# 获取指定股票时间段行情
df = api.daily(ts_code='000001.SZ', start_date='20260601', end_date='20260630')
```

返回字段：`ts_code, trade_date, open, high, low, close, pre_close, change, pct_chg, vol, amount`

#### 每日基础指标 - `daily_basic`

获取每日估值指标（PE、PB、PS、总市值、换手率等）。

```python
df = api.daily_basic(ts_code='000001.SZ', trade_date='20260613')
df = api.daily_basic(ts_code='000001.SZ', start_date='20260601', end_date='20260630')
```

### 资金流向数据

#### 个股资金流向 - `moneyflow`

```python
df = api.moneyflow(ts_code='000001.SZ', trade_date='20260613')
df = api.moneyflow(ts_code='000001.SZ', start_date='20260601', end_date='20260630')
```

### 技术因子（v0.2.3 新增）

#### 股票技术因子 - `stk_factor` ⭐

```python
# 单股票最近一年技术因子
df = api.stk_factor(ts_code='000001.SZ', start_date='20260101', end_date='20260618')

# 单日全市场技术因子（5500+ 行）
df = api.stk_factor(trade_date='20260618')
```

返回字段（35 个）：包含 `open/close/high/low/vol`、5/10/20/30/60/90/250 日均线、KDJ、RSI、MACD、BOLL、CCI、BIAS、PSY、WR 等常见指标。

#### 复权因子 - `adj_factor`

```python
df = api.adj_factor(ts_code='000001.SZ', start_date='20260101', end_date='20260618')
```

### 两融数据（v0.2.3 新增专用方法）

```python
# 融资融券每日汇总
df = api.margin(trade_date='20260613')
df = api.margin(start_date='20260601', end_date='20260618')

# 融资融券每日明细
df = api.margin_detail(ts_code='000001.SZ', start_date='20260601', end_date='20260618')
```

### 指数行情（v0.2.3 新增专用方法）

```python
# 指数日线
df = api.index_daily(ts_code='000300.SH', start_date='20260101', end_date='20260618')

# 大盘指数每日指标（仅上证综指、深证成指、上证50、中证500等）
df = api.index_dailybasic(ts_code='000001.SH', trade_date='20260618')

# 申万行业日线
df = api.sw_daily(trade_date='20260618')
```

### 市场行为数据

#### 停复牌信息 - `suspend_d`

```python
# 查指定股票指定日期范围的停复牌记录
df = api.suspend_d(ts_code='000001.SZ', start_date='20260601', end_date='20260630')

# 只查复牌记录（suspend_type='R'）
df = api.suspend_d(suspend_type='R', start_date='20260601', end_date='20260618')

# 只查停牌记录（suspend_type='S'）
df = api.suspend_d(suspend_type='S', trade_date='20260601')

# 单股票指定日期
df = api.suspend_d(ts_code='000687.SZ', trade_date='20260520')
```

参数说明：
- `ts_code`: 股票代码
- `suspend_type`: 停复牌类型（`'S'`=停牌，`'R'`=复牌）
- `trade_date`: 交易日期（YYYYMMDD）
- `start_date` / `end_date`: 日期范围
- `suspend_date`: 已废弃，等同于 `trade_date`（保留参数仅做兼容）

返回字段：`ts_code, trade_date, suspend_timing, suspend_type`

> ⚠️ 数据范围：本地缓存仅保留最近半年的停复牌数据（更早数据透传上游）。

#### 涨跌停统计 - `limit_list_d`

```python
df = api.limit_list_d(trade_date='20260613')
df = api.limit_list_d(ts_code='000001.SZ', start_date='20260601', end_date='20260630')
```

#### 龙虎榜每日明细 - `top_list`

```python
df = api.top_list(trade_date='20260613')
```

#### 开盘啦涨停股池 - `kpl_list`

```python
df = api.query('kpl_list', trade_date='20260613')
```

### ETF 数据

```python
# ETF 列表
df = api.etf_basic()

# ETF 日线行情
df = api.etf_daily(ts_code='510300.SH', trade_date='20260613')
df = api.etf_daily(ts_code='510300.SH', start_date='20260601', end_date='20260630')

# ETF 净值
df = api.etf_nav(ts_code='510300.SH', nav_date='20260613')

# ETF 份额
df = api.etf_share(ts_code='510300.SH', trade_date='20260613')
```

### 期权数据

```python
# 期权基础信息
df = api.opt_basic(exchange='SSE')

# 期权日线
df = api.opt_daily(ts_code='10004355.SH', trade_date='20260613')
```

### 通用查询接口 - `query`

对于上述方法未覆盖的接口，使用通用查询：

```python
# 交易日历
df = api.query('trade_cal', exchange='SSE', start_date='20260101', end_date='20261231')

# 复权因子（也有专用方法 api.adj_factor()）
df = api.adj_factor(ts_code='000001.SZ', start_date='20260101', end_date='20260616')

# 融资融券（也有专用方法 api.margin() / api.margin_detail()）
df = api.margin(trade_date='20260613')
df = api.margin_detail(ts_code='000001.SZ', trade_date='20260613')

# 股票技术因子（也有专用方法 api.stk_factor()）
df = api.stk_factor(ts_code='000001.SZ', start_date='20260101', end_date='20260618')

# 行业资金流向
df = api.query('moneyflow_ind_dc', trade_date='20260613')   # 东财行业
df = api.query('moneyflow_ind_ths', trade_date='20260613')  # 同花顺行业
df = api.query('moneyflow_mkt_dc', trade_date='20260613')   # 大盘资金流向

# 申万行业日线
df = api.query('sw_daily', start_date='20260601', end_date='20260616')

# 指数数据
df = api.query('index_basic', market='SSE')
df = api.query('index_dailybasic', ts_code='000001.SH', trade_date='20260613')
df = api.query('index_global', trade_date='20260613')

# 财务数据（按报告期）
df = api.query('income', ts_code='000001.SZ', period='20251231')
df = api.query('balancesheet', ts_code='000001.SZ', period='20251231')
df = api.query('cashflow', ts_code='000001.SZ', period='20251231')
df = api.query('fina_indicator', ts_code='000001.SZ', period='20251231')

# 股票回购
df = api.query('repurchase', ts_code='000001.SZ', start_date='20260101', end_date='20260616')

# 机构调研
df = api.query('stk_surv', ts_code='000001.SZ', start_date='20260101', end_date='20260616')

# 周线/月线
df = api.query('weekly', ts_code='000001.SZ', start_date='20260101', end_date='20260616')
df = api.query('monthly', ts_code='000001.SZ', start_date='20260101', end_date='20260616')
```

## 完整示例

### 示例1：股票基本面 + 行情分析

```python
import alphakit as ak

ak.set_token('your_token_here')
api = ak.AlphaKit()

ts_code = '000001.SZ'

# 基本信息
info = api.stock_basic(ts_code=ts_code)
print("股票信息:")
print(info)

# 最近一年日线
daily_data = api.daily(ts_code=ts_code)  # 默认最近一年
print(f"\n日线数据: {len(daily_data)} 条")
print(daily_data.head())

# 估值指标
valuation = api.daily_basic(ts_code=ts_code, start_date='20260101', end_date='20260616')
print(f"\n估值数据: {len(valuation)} 条")
print(valuation[['trade_date', 'pe', 'pb', 'total_mv']].head())
```

### 示例2：每日市场扫描

```python
import alphakit as ak

ak.set_token('your_token_here')
api = ak.AlphaKit()

trade_date = '20260613'

# 涨跌停统计
limit_stats = api.limit_list_d(trade_date=trade_date)
print(f"涨跌停股票数: {len(limit_stats)}")

# 龙虎榜
top_stocks = api.top_list(trade_date=trade_date)
print(f"龙虎榜股票数: {len(top_stocks)}")

# 开盘啦涨停池
kpl = api.query('kpl_list', trade_date=trade_date)
print(f"开盘啦涨停: {len(kpl)} 只")
```

### 示例3：ETF 组合分析

```python
import alphakit as ak

ak.set_token('your_token_here')
api = ak.AlphaKit()

# ETF 列表
etf_list = api.etf_basic()
print(f"ETF 总数: {len(etf_list)}")

ts_code = '510300.SH'

# 日线 + 净值
etf_daily = api.etf_daily(ts_code=ts_code, start_date='20260101', end_date='20260616')
etf_nav = api.etf_nav(ts_code=ts_code, start_date='20260101', end_date='20260616')

print(f"\n{ts_code} 行情:")
print(etf_daily[['trade_date', 'close', 'vol', 'amount']].head())

print(f"\n{ts_code} 净值:")
print(etf_nav[['nav_date', 'unit_nav', 'accum_nav']].head())
```

### 示例4：财务指标对比

```python
import alphakit as ak
import pandas as pd

ak.set_token('your_token_here')
api = ak.AlphaKit()

# 获取 2025 年报数据
ts_codes = ['000001.SZ', '000002.SZ', '600000.SH']
results = []

for code in ts_codes:
    df = api.query('fina_indicator', ts_code=code, period='20251231')
    if not df.empty:
        results.append(df)

if results:
    combined = pd.concat(results, ignore_index=True)
    print(combined[['ts_code', 'eps', 'roe', 'netprofit_yoy']])
```

## 错误处理

```python
import alphakit as ak
from alphakit.exceptions import AlphaKitError

ak.set_token('your_token_here')
api = ak.AlphaKit()

try:
    df = api.daily(ts_code='000001.SZ', trade_date='20260613')
    print(f"获取成功: {len(df)} 条数据")
except AlphaKitError as e:
    print(f"API 错误 [{e.code}]: {e.message}")
except Exception as e:
    print(f"其他错误: {e}")
```

### 错误码说明

| 错误码 | HTTP | 说明 | 解决方案 |
|--------|------|------|----------|
| 1001 | 401 | Token 缺失/无效/吊销/过期 | 检查 Token 是否正确，是否已过期 |
| 1002 | 403 | 当前等级无权访问该接口 | 联系管理员升级等级 |
| 1003 | 403 | IP 限制（封禁或超过绑定上限） | 联系管理员检查 IP 绑定 |
| 1004 | 429 | 触发限频（每分钟请求次数过多） | 降低请求频率，稍后重试 |
| 1005 | 429 | 当日配额已用尽 | 等待次日重置或联系管理员提升配额 |
| 1006 | 400 | 请求参数错误 | 检查参数名和值是否正确 |
| 1500 | 500 | 服务器内部错误 | 联系管理员排查 |
| 9999 | - | 网络请求失败（SDK 端） | 检查网络和服务地址 |

## 最佳实践

### 1. Token 安全管理

```python
import os
import alphakit as ak

# 从环境变量读取 token（推荐，避免硬编码）
token = os.getenv('ALPHAKIT_TOKEN')
if not token:
    raise RuntimeError('请设置环境变量 ALPHAKIT_TOKEN')

ak.set_token(token)
api = ak.AlphaKit()
```

### 2. 利用智能默认

```python
# ❌ 不必要的样板代码
from datetime import datetime, timedelta
end = datetime.now().strftime('%Y%m%d')
start = (datetime.now() - timedelta(days=365)).strftime('%Y%m%d')
df = api.daily(ts_code='000001.SZ', start_date=start, end_date=end)

# ✅ 使用智能默认
df = api.daily(ts_code='000001.SZ')  # 自动取最近一年
```

### 3. 批量查询优化

```python
import alphakit as ak

ak.set_token('your_token_here')
api = ak.AlphaKit()

# 优先使用日期范围批量获取，减少请求次数
# ❌ 不推荐：逐日查询
for d in date_list:
    df = api.daily(ts_code='000001.SZ', trade_date=d)

# ✅ 推荐：一次取整段
df = api.daily(ts_code='000001.SZ', start_date='20260101', end_date='20260616')

# 多股票场景，控制并发避免触发限频
import time
stock_codes = ['000001.SZ', '000002.SZ', '600000.SH']
results = [api.daily(ts_code=c) for c in stock_codes]
# 默认每分钟 60 次限频，正常使用不会触发
```

### 4. 数据缓存

```python
import alphakit as ak
import pickle
from pathlib import Path

ak.set_token('your_token_here')
api = ak.AlphaKit()

cache_dir = Path('data_cache')
cache_dir.mkdir(exist_ok=True)

def get_cached(cache_file, fetch_func, *args, **kwargs):
    """带缓存的数据获取"""
    cache_path = cache_dir / cache_file
    if cache_path.exists():
        with open(cache_path, 'rb') as f:
            return pickle.load(f)
    data = fetch_func(*args, **kwargs)
    with open(cache_path, 'wb') as f:
        pickle.dump(data, f)
    return data

# 用法：股票列表变化少，适合缓存
df = get_cached('stock_basic.pkl', api.stock_basic)
```

### 5. 异常重试

```python
import alphakit as ak
from alphakit.exceptions import AlphaKitError
import time

def safe_query(func, *args, max_retries=3, **kwargs):
    """带指数退避的安全查询"""
    for attempt in range(max_retries):
        try:
            return func(*args, **kwargs)
        except AlphaKitError as e:
            # 限频和服务器错误才重试，认证错误直接抛出
            if e.code in (1004, 1500, 9999) and attempt < max_retries - 1:
                wait = 2 ** attempt
                print(f"重试 {attempt + 1}/{max_retries}（{wait}秒后）: {e.message}")
                time.sleep(wait)
            else:
                raise
    return None

# 使用
ak.set_token('your_token_here')
api = ak.AlphaKit()
df = safe_query(api.daily, ts_code='000001.SZ')
```

## 数据范围

- **日线行情、估值指标、资金流向、龙虎榜、涨跌停**：自 2020-01-02 起，每个交易日 18:00 自动更新
- **股票技术因子（stk_factor）**：自 2020-01-02 起，35 个常用指标，每个交易日 18:00 自动更新（v0.2.3 起完整覆盖）
- **复权因子、融资融券**：每个交易日 18:00 自动更新
- **指数日线**：每个交易日更新（部分历史数据可能不完整）
- **财务数据**：按季度更新（季度末日期：03-31, 06-30, 09-30, 12-31）
- **ETF 数据（日线、净值、份额）**：每个交易日更新
- **期权数据**：每个交易日更新



## 版本历史

### v0.2.3（2026-06-21）
- 🆕 新增便捷方法：`stk_factor()`（股票技术因子，35 个指标）、`adj_factor()`（复权因子）、`margin()` / `margin_detail()`（融资融券）、`index_daily()` / `index_dailybasic()` / `sw_daily()`
- 🚀 服务端拉取性能大幅优化：去掉无谓限速、INSERT 改用 `execute_values` 真正批量插入，单日 5500 行从 18s 降到 < 1s
- 📊 数据回填完成：`stk_factor` 已从 2025-11-10 一路补齐到最新交易日，覆盖全市场 5500+ 股票
- 🛠️ 服务端 schema 修复：`etf_nav` / `etf_basic` / `etf_share` / `opt_basic` 加上上游 API 新增的字段
- 🔄 启动补漏机制：服务重启 60 秒后自动检查所有日表数据是否落后，自动追加缺失日期的数据

### v0.2.2（2026-06-18）
- 🆕 `suspend_d()` 新增 `suspend_type` 参数，可按停牌（'S'）/复牌（'R'）过滤
- 🔧 修复 `suspend_d` 的服务端日期字段映射错误（`suspend_date` → `trade_date`）
- 📝 旧的 `suspend_date` 参数保留作为向后兼容，但已被 `trade_date` 替代
- 🗄️ 更新 suspend_d 缓存数据（最近半年）

### v0.2.1（2026-06）
- `daily()` 新增智能默认：只传 `ts_code` 时自动取最近一年数据
- 修复默认 base_url（改为 38080 端口）
- 修复 `daily` API 与本地缓存表（stock_daily）的映射

### v0.2.0
- 支持 ETF、期权等更多数据接口
- 优化错误处理

### v0.1.0
- 初始版本
- 支持基础股票数据接口
