Metadata-Version: 2.4
Name: top369
Version: 0.4.4
Summary: 股票数据API服务平台官方 Python SDK (tushare 风格)
Author: top369 platform
License-Expression: MIT
Keywords: stock,quant,tushare,finance,a-share,A股,量化,行情
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Natural Language :: Chinese (Simplified)
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: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25
Requires-Dist: pandas>=1.3
Provides-Extra: mcp
Requires-Dist: mcp<2,>=1.2; extra == "mcp"
Dynamic: license-file

# top369 Python SDK

股票数据API服务平台官方 Python SDK，tushare 风格封装——用过 `ts.pro_api()` 即可 10 秒上手。

## 安装

```bash
pip install top369          # Python SDK
pip install "top369[mcp]"   # 含 MCP Server: Claude/Cursor 直接查A股(需 Python 3.10+)
```

依赖仅 `requests` + `pandas`。

## 安装即测（不用写代码）

```bash
top369-demo                # 跑通全部接口演示; API Key 从环境变量 TOP369_API_KEY 读, 未设则交互粘贴
python -m top369.demo      # 等价写法
```

demo 按 Key 档位自适应：先显示账户档位与今日用量，档位达不到要求的接口会打印后端提示并跳过，不中断。

## 快速上手

```python
import top369 as gp

pro = gp.pro_api('sk-xxxx')   # 控制台获取 Key; 默认连 https://api.369.top

# 查询当前所有正常上市交易的股票列表 (对应 tushare 的 stock_basic)
data = pro.stock_basic(page=1, page_size=200,
                       fields='code,name,market,type')

# 或者通用调用风格
data = pro.query('stock_basic', page=1, fields='code,name')
```

## 标的代码：四种写法都认

后端统一收口，**不用自己改写**（tushare 迁移用户可直接粘 `ts_code`）：

| 写法 | 例子 | 说明 |
|---|---|---|
| 市场前缀 | `sh600519` | 平台内部/响应用法，**响应统一回这种** |
| 裸 6 位码 | `600519` | 同码多市场按 股票>ETF>可转债>指数 择优 |
| 点号前缀 | `sh.600519` | 等价于市场前缀 |
| 点号后缀 | `600519.SH` | tushare `ts_code` / AlphaFeed 习惯 |

```python
pro.stock_day(code='600519.SH')   # 四种写法完全等价; 显式写了市场则不做择优
                                  # (如 000300.SH 是沪深300指数, 不会判成深市股票)
```

本地转换/校验而不发请求时用 `symbols` 模块：

```python
from top369 import normalize, to_dot, to_plain, market_of

normalize('600519.SH')     # 'sh600519'  → 平台写法
to_dot('sz000001')         # '000001.SZ' → 喂 tushare 等外部库
to_plain('sh.600519')      # '600519'
market_of('000001.SZ')     # 'sz'
```

## 接口一览

| SDK 方法 | 对应 tushare | 说明 |
|---|---|---|
| `pro.stock_basic()` | `stock_basic` | 股票列表（`df.attrs['total']` 为总数） |
| `pro.stock_day()` / `pro.daily()` | `daily` | 日线 + 涨幅/赚钱效应 |
| `pro.adjust_factor(code, adjust)` | `adj_factor` | 复权因子序列（qfq 最新因子恒为 1.0；可据因子本地复权任意字段） |
| `pro.minute(code, date)` | `minute` | 分时数据 |
| `pro.tick(code, date)` | `tick` | 分笔成交 |
| `pro.financial(code)` | `financial` | 财务数据（约579字段宽表） |
| `pro.blocks(code)` | `concept` 类 | 所属板块（单列 blocks） |
| `pro.trade_calendar(start_date, end_date)` | `trade_cal` | 交易日历（单列 date，升序；缺省当年至今） |
| `pro.stock_info(code)` | — | 单票基本信息 |
| `pro.stock_st_list(date, sec_type)` | — | ST股名单（每日快照还原历史戴帽；`df.attrs['date'/'total']`） |
| `pro.stock_name_history(code)` | `namechange` 类 | 个股名称/ST/停牌时间线（快照自2026-09-01起） |
| `pro.kline(code, period)` / `pro.stk_mins(...)` | `stk_mins` | 1/5/15/30/60 分钟K线；`period=1` 可加 `merge_days=N`(1≤N≤10) 合并最近N个交易日（实盘用，实时行带 is_realtime 标记） |
| `pro.special_lists()` | — | 特殊名单清单+各自成员数（沪深港通/融资融券/指数成分/专精特新...） |
| `pro.special_list(name)` | — | 单个特殊名单全量成员（name 取值见 special_lists） |
| `pro.hsgt(market)` | — | 沪深港通标的（sh/sz/hk/all，扁平 market/code 列） |
| `pro.stock_lists(code)` | — | 个股当前所属特殊名单（单列 list_name） |
| `pro.f10(code, category, section)` | — | F10公司资料结构化（股东研究/分红扩股/股本/财务分析/高层治理等17栏目；category缺省=栏目清单；专业版） |
| `pro.lhb(date, start_date, end_date, code)` | `top_list` 类 | 龙虎榜每日明细（2023起，上榜原因/净买额；专业版） |
| `pro.lhb_detail(code, date)` | `top_inst` 类 | 个股买卖前5营业部席位明细（专业版） |
| `pro.lhb_history(code)` | — | 个股历次上榜记录（2021起；专业版） |
| `pro.margin(scope, code)` | `margin` 类 | 融资融券：scope=market 全市场余额序列 / scope=stock 个股全历史2010起（专业版） |
| `pro.trans_stats(code)` | `moneyflow` 类 | 每日内外盘主动买卖/大单统计（2026-08起；基础版） |
| `pro.zdt(view)` | — | 涨跌停：ladder 连板天梯·个股 / dt 跌停名单 / stat 涨停揭秘统计（专业版） |
| `pro.zdt_board_stat()` | — | 连板天梯·板块统计（板块涨停家数/高度；专业版） |
| `pro.quote_snapshot(code, date)` | — | 盘后五档快照（收盘价/量额/买卖五档；基础版） |
| `pro.market_breadth()` | — | 大盘涨跌分布（上涨/下跌家数+涨幅档位，1990起；基础版） |
| `pro.ah_premium(code)` | — | AH溢价表（A/H收盘价+港元汇率+溢价率；专业版） |
| `pro.account()` / `pro.usage()` | — | 当前 Key 的账户信息（档位/积分/配额）与今日用量；返回原始 dict |
| `pro.query('stock_day', ...)` | `query` 类 | 通用调用风格（未知名/未知参数直接报错） |

所有方法支持 tushare 风格的 `fields='col1,col2'` 列过滤（`account`/`usage` 除外）。

## 常用示例

```python
# 日线(默认最新100根不指定则全历史), 复权
df = pro.stock_day(code='sz000911', start_date='2026-01-01',
                   adjust='qfq', limit=100)
print(df.tail())          # date/open/high/low/close/volume/amount/turnover
print(df.attrs['name'])   # 股票名称等元信息

# 60分钟K线
df = pro.kline(code='sz000911', period=60)

# 分笔
df = pro.tick(code='sz000911', date='2026-08-28')

# 交易日历(按交易日循环, 不空跑节假日)
df = pro.trade_calendar(start_date='2026-01-01')
for d in df['date']:
    ...
```

## 不要 DataFrame？

```python
pro = gp.pro_api('sk-xxxx', to_dataframe=False)   # 全部接口返回原始结构(信封里的 data)
pro.to_dataframe = True                           # 也可运行时随时切换
```

（`to_dataframe=False` 时 `fields` 过滤不生效——原始结构上没有列可挑。）

## 认证与限流

- 认证走 `X-API-Key` 请求头，SDK 自动携带；网络错误自动重试 2 次（指数退避）
- 平台按**会员档位**控制可调用的接口（体验版注册即得 → 基础版/专业版/旗舰版）：
  低档调用高档接口返回 403，错误信息带所需档位与价格；
  会员到期自动回落体验版权益，不整体拦截。各档位不按次扣费，仅受 RPM/日配额约束
- `pro.account()` / `pro.usage()` 随时可查自己的档位与用量

## 错误处理

```python
from top369 import AuthError, GupiaoApiError, QuotaExceeded

try:
    df = pro.stock_day(code='sz000001', limit=10)
except AuthError as e:
    print('Key无效/档位不足, 勿重试:', e)      # 401/403
except QuotaExceeded as e:
    print('配额/频率超限, 策略降级:', e)        # 429
except GupiaoApiError as e:
    print(e)                      # 人话错误信息
    print(e.status_code)          # 401=Key无效 429=配额用尽 403=该接口需更高档位
```

## MCP 接入：让 Claude / Cursor 直接查A股数据

不用写代码——把平台作为 MCP Server 挂进 AI 编程助手，Agent 即可直接调用全部数据工具
（行情/K线/财务/**ST名单/名称历史/沪深港通**/F10公司资料/龙虎榜/涨跌停天梯/融资融券/AH溢价等 27 个）。

要求 Python 3.10+：

```bash
pip install "top369[mcp]"
```

**Claude Desktop**（`claude_desktop_config.json`）或 **Cursor**（`mcp.json`）：

```json
{
  "mcpServers": {
    "top369": {
      "command": "top369-mcp",
      "env": {
        "TOP369_API_KEY": "sk-xxxxxxxxxxxx"
      }
    }
  }
}
```

环境变量：

| 变量 | 说明 |
|---|---|
| `TOP369_API_KEY` | API Key（sk-开头，必填） |
| `TOP369_BASE_URL` | 服务地址，缺省 `https://api.369.top`（自建/联调时覆盖） |

工具与 SDK 方法**同名同参**（`stock_day` / `kline` / `stock_st_list` / `stock_name_history`
/ `special_list` / `hsgt` ...），SDK 文档的用法直接适用。行为约定：

- 结果为紧凑 JSON，行表默认最多 100 行（可传 `max_rows` 调整，硬上限 500），
  超出会带 `_truncated` 提示——收窄日期区间或用 `fields` 挑字段
- `stock_basic` 检索参数三层统一（HTTP / SDK / MCP）二选一：`name=`（股票名称
  模糊匹配）或 `code=`（四种代码写法都认，后端归一精确匹配）；互斥与
  “name 像代码”护栏由后端统一校验，违反返回 400
- 出错返回结构化 `{"error", "status", "hint"}`，例如档位不足的 403 会提示用
  `account` 工具查档位、429 会提示用 `usage` 查余量——Agent 可自我纠正

## 其他语言

SDK 只是薄封装，后端是标准 REST，任何语言直接调用：

```
GET /api/stock/day?code=sz000911&limit=10
X-API-Key: sk-xxxx
```

响应统一信封 `{code, message, data}`，接口文档见 `https://api.369.top/docs`。
