# Quotes Source: https://docs.tickflow.org/api-reference/websockets/quotes 旧版行情推送接口,仅推送行情数据,不支持市场深度。 新接入建议使用 `/v1/ws/stream`。 # Stream Source: https://docs.tickflow.org/api-reference/websockets/stream 统一推送接口,按频道(channel)订阅行情和市场深度。 支持频道: `quotes`(需 WebSocket 实时行情权限)、`depth`(需市场深度权限)。 # API 概述 Source: https://docs.tickflow.org/zh-Hans/api-reference/introduction TickFlow API 认证与使用说明 ## 认证方式 所有 API 接口需要通过 `x-api-key` 请求头传递 API Key 进行认证: ```bash theme={null} curl -H "x-api-key: your-api-key" https://api.tickflow.org/v1/klines?symbol=600000.SH ``` 请妥善保管您的 API Key,不要在客户端代码中暴露。 ## 速率限制 根据 API Key 配置,可能会有请求频率限制。超出限制时返回 `429 Too Many Requests`。 ## 批量查询 部分接口同时支持 GET 和 POST 方法: * **GET**: 通过 URL 参数传递,适合少量数据 * **POST**: 通过 JSON Body 传递,适合大批量查询,不受 URL 长度限制 ## API 版本 当前 API 版本为 `v1`,所有接口路径以 `/v1` 开头。 例如:`https://api.tickflow.org/v1/klines` ## OpenAPI 规范 完整的 OpenAPI 规范文件可通过以下地址获取: ``` https://api.tickflow.org/openapi.json ``` 你可以在接下来的页面中交互式地查看和测试每一个 API。 # WebSocket 实时推送 Source: https://docs.tickflow.org/zh-Hans/api-reference/websocket 通过 WebSocket 订阅实时行情和市场深度推送 ## 概述 TickFlow 提供两个 WebSocket 接口: | 接口 | 地址 | 说明 | | ------------ | --------------- | ------------------------------------ | | **统一推送**(推荐) | `/v1/ws/stream` | 按频道订阅,支持 `quotes`(行情)和 `depth`(五档盘口) | | 行情推送 | `/v1/ws/quotes` | 仅推送行情数据,兼容旧版 | WebSocket 为付费功能,需要订阅包含 WebSocket 实时行情的套餐(如 **Expert**)或单独开启。市场深度频道额外需要「市场深度」权限。 *** ## 统一推送 `/v1/ws/stream` ### 连接地址 ``` wss://api.tickflow.org/v1/ws/stream?api_key=YOUR_API_KEY ``` 通过 `api_key` 查询参数认证。认证失败返回 HTTP 401/403,客户端应**停止重连**。 所有消息使用 **JSON** 文本帧。 ### 客户端命令 #### subscribe — 订阅频道 按**频道**(`channel`)+ **标的列表**(`symbols`)订阅。可多次调用追加。 ```json theme={null} {"op": "subscribe", "channel": "quotes", "symbols": ["600000.SH", "000001.SZ"]} {"op": "subscribe", "channel": "depth", "symbols": ["600000.SH"]} ``` 服务端返回该频道的 `subscribed` 确认,并**立即推送**新增标的的缓存快照。 支持的频道: | 频道 | 说明 | 所需权限 | | -------- | ------ | -------------- | | `quotes` | 实时行情 | WebSocket 实时行情 | | `depth` | 五档市场深度 | 市场深度 | #### unsubscribe — 退订频道 ```json theme={null} {"op": "unsubscribe", "channel": "depth", "symbols": ["600000.SH"]} ``` ### 服务端消息 #### subscribed — 频道订阅状态 ```json theme={null} {"op": "subscribed", "channel": "quotes", "symbols": ["600000.SH", "000001.SZ"], "total": 2} ``` #### quotes — 行情推送 ```json theme={null} { "op": "quotes", "data": [ { "symbol": "600000.SH", "region": "CN", "last_price": 9.72, "prev_close": 9.78, "open": 9.78, "high": 9.78, "low": 9.68, "volume": 426585, "amount": 422430500, "timestamp": 1776754802000, "ext": { "type": "cn_equity", "name": "浦发银行", "change_pct": -0.006135, "change_amount": -0.06, "amplitude": 0.010225, "turnover_rate": 0.001281 } } ] } ``` #### depth — 市场深度推送 ```json theme={null} { "op": "depth", "data": [ { "symbol": "600000.SH", "region": "CN", "timestamp": 1776754802000, "bid_prices": [9.72, 9.71, 9.7, 9.69, 9.68], "bid_volumes": [3192, 3870, 26168, 5849, 5480], "ask_prices": [9.73, 9.74, 9.75, 9.76, 9.77], "ask_volumes": [74, 1602, 1148, 1209, 1109] } ] } ``` | 字段 | 说明 | | ------------- | ------------- | | `bid_prices` | 买入价(买1-买5,降序) | | `bid_volumes` | 买入量 | | `ask_prices` | 卖出价(卖1-卖5,升序) | | `ask_volumes` | 卖出量 | #### error — 错误消息 ```json theme={null} {"op": "error", "message": "no permission for channel: depth"} ``` 常见错误: * `no permission for channel: ...` — 无该频道权限 * `unknown channel: ...` — 未知频道名 * `exceeded max N symbols` — 标的数超出套餐上限 * `invalid message: ...` — JSON 格式不正确 ### 命令总览 | 客户端命令 | 说明 | 服务端响应 | | ------------- | ----- | ------------------------ | | `subscribe` | 按频道订阅 | `subscribed` + 对应频道的缓存快照 | | `unsubscribe` | 按频道退订 | `subscribed` | | 服务端推送 | 说明 | 触发条件 | | ------------ | ------ | ---------------------------- | | `subscribed` | 频道订阅状态 | 每次 subscribe / unsubscribe 后 | | `quotes` | 实时行情数据 | 已订阅标的有行情更新时 | | `depth` | 五档市场深度 | 已订阅标的盘口变化时 | | `error` | 错误信息 | 操作失败时 | *** ## 行情推送 `/v1/ws/quotes`(旧版) 旧版接口仅推送行情数据,不支持市场深度。新接入建议使用 `/v1/ws/stream`。 ### 连接地址 ``` wss://api.tickflow.org/v1/ws/quotes?api_key=YOUR_API_KEY ``` ### 协议 与统一推送的 `quotes` 频道行为一致,但不使用 `channel` 字段: ```json theme={null} {"op": "subscribe", "symbols": ["600000.SH", "000001.SZ"]} {"op": "unsubscribe", "symbols": ["600000.SH"]} ``` 服务端推送 `quotes`、`subscribed`、`error` 消息,格式与统一推送相同。 *** ## 连接保活 服务端每 **30 秒**发送一次 Ping 帧,客户端需回复 Pong 帧。大多数 WebSocket 库会自动处理。 ## 连接管理 * **断开清理**:连接断开后该连接的所有订阅自动清除 * **重连恢复**:客户端断线重连后需重新发送 `subscribe` 恢复订阅 * **认证错误**:收到 HTTP 401/403 时不应自动重连,请检查 API Key 和套餐权限 ## 代码示例 使用 [websockets](https://pypi.org/project/websockets/) 库连接统一推送: ```bash theme={null} pip install websockets ``` ```python theme={null} import asyncio import json import websockets API_KEY = "your-api-key" URL = f"wss://api.tickflow.org/v1/ws/stream?api_key={API_KEY}" async def main(): async with websockets.connect(URL) as ws: # 订阅行情和盘口 await ws.send(json.dumps({"op": "subscribe", "channel": "quotes", "symbols": ["600000.SH", "000001.SZ"]})) await ws.send(json.dumps({"op": "subscribe", "channel": "depth", "symbols": ["600000.SH"]})) async for raw in ws: msg = json.loads(raw) if msg["op"] == "subscribed": print(f"[{msg['channel']}] 已订阅 {msg['total']} 个标的") elif msg["op"] == "quotes": for q in msg["data"]: print(f"{q['symbol']}: {q['last_price']}") elif msg["op"] == "depth": for d in msg["data"]: print(f"[盘口] {d['symbol']} 买1:{d['bid_prices'][0]} 卖1:{d['ask_prices'][0]}") elif msg["op"] == "error": print(f"错误: {msg['message']}") asyncio.run(main()) ``` ```javascript theme={null} const API_KEY = "your-api-key"; const URL = `wss://api.tickflow.org/v1/ws/stream?api_key=${API_KEY}`; const ws = new WebSocket(URL); ws.onopen = () => { ws.send(JSON.stringify({ op: "subscribe", channel: "quotes", symbols: ["600000.SH"] })); ws.send(JSON.stringify({ op: "subscribe", channel: "depth", symbols: ["600000.SH"] })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.op === "subscribed") { console.log(`[${msg.channel}] 已订阅 ${msg.total} 个标的`); } else if (msg.op === "quotes") { for (const q of msg.data) { console.log(`${q.symbol}: ${q.last_price}`); } } else if (msg.op === "depth") { for (const d of msg.data) { console.log(`[盘口] ${d.symbol} 买1:${d.bid_prices[0]} 卖1:${d.ask_prices[0]}`); } } else if (msg.op === "error") { console.error("错误:", msg.message); } }; ws.onerror = (err) => console.error("WebSocket error:", err); ws.onclose = (e) => console.log("连接关闭:", e.code, e.reason); ``` TickFlow Python SDK 封装了连接管理、自动重连和订阅恢复: ```bash theme={null} pip install "tickflow[all]" --upgrade ``` ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") stream = tf.stream @stream.on_quotes def on_quotes(quotes): for q in quotes: print(f"{q['symbol']}: {q['last_price']}") @stream.on_depth def on_depth(depths): for d in depths: print(f"[盘口] {d['symbol']} 买1:{d['bid_prices'][0]}×{d['bid_volumes'][0]}") @stream.on_error def on_error(msg): print(f"错误: {msg}") stream.subscribe("quotes", ["600000.SH", "000001.SZ"]) stream.subscribe("depth", ["600000.SH"]) stream.connect() # 阻塞直到 close() 或 Ctrl+C ``` 非阻塞模式: ```python theme={null} stream.connect(block=False) # 后台线程运行 stream.subscribe("quotes", ["AAPL.US"]) # 动态追加订阅 ``` 如果只需获取某一时刻的行情快照,使用 REST 接口更为简单。WebSocket 适合需要持续接收行情更新的场景。 # 常见问题 Source: https://docs.tickflow.org/zh-Hans/faq 使用 TickFlow 过程中的常见问题和解决方法 ## K 线数据 `klines.get()` 默认返回最近 **100** 根 K 线。如需更多数据,请显式设置 `count` 参数: ```python theme={null} # 默认只返回 100 根 df = tf.klines.get("600000.SH", period="1d", as_dataframe=True) print(len(df)) # 100 # 设置 count 获取更多 df = tf.klines.get("600000.SH", period="1d", count=10000, as_dataframe=True) print(len(df)) # 取决于该标的可用数据量 ``` 也可以通过 `start_time` 和 `end_time` 指定时间范围来获取数据。 TickFlow 支持 **5 种**复权方式,通过 `adjust` 参数指定: | `adjust` 值 | 说明 | 算法 | | --------------------- | -------------- | --------------- | | `"none"` | 不复权 | 原始价格 | | `"forward"` | 前复权-比例(**默认**) | 乘除法,价格 × 累计复权因子 | | `"backward"` | 后复权-比例 | 乘除法,价格 × 累计复权因子 | | `"forward_additive"` | 前复权-差值 | 加减法,价格 ± 累计差值 | | `"backward_additive"` | 后复权-差值 | 加减法,价格 ± 累计差值 | **东方财富、同花顺等软件默认使用的是差值前复权**(加减法),对应 `adjust="forward_additive"`。 TickFlow 的默认值 `"forward"` 是比例前复权(乘除法),两者结果不同。如需与这些软件的价格对齐,请使用 `"forward_additive"`。 ```python theme={null} # 比例前复权(TickFlow 默认) df_ratio = tf.klines.get("600000.SH", period="1d", count=1000, adjust="forward", as_dataframe=True) # 差值前复权(东方财富/同花顺默认,价格与这些软件一致) df_additive = tf.klines.get("600000.SH", period="1d", count=1000, adjust="forward_additive", as_dataframe=True) # 不复权 df_raw = tf.klines.get("600000.SH", period="1d", count=1000, adjust="none", as_dataframe=True) # 比例后复权 df_back = tf.klines.get("600000.SH", period="1d", count=1000, adjust="backward", as_dataframe=True) # 差值后复权 df_back_add = tf.klines.get("600000.SH", period="1d", count=1000, adjust="backward_additive", as_dataframe=True) ``` **比例 vs 差值的区别**:比例复权保持涨跌幅不变(适合收益率计算),差值复权保持价差不变(适合与行情软件对比价格)。 如需查看除权因子: ```python theme={null} factors = tf.klines.ex_factors(["600000.SH"], as_dataframe=True) print(factors) ``` 付费订阅一般不会触发频率限制。如果遇到,大概率是**用法问题**——逐只标的循环调用单只接口会产生大量请求。 **推荐使用批量接口**,一次请求获取多只标的的数据: ```python theme={null} # ❌ 不推荐:逐只调用,100 只标的 = 100 次请求 for symbol in symbols: df = tf.klines.get(symbol, period="1d", count=1000, as_dataframe=True) # ✅ 推荐:批量接口,100 只标的 = 1 次请求 dfs = tf.klines.batch( symbols, period="1d", count=1000, as_dataframe=True, show_progress=True, ) # dfs 是 dict[str, DataFrame] print(dfs["600000.SH"].tail()) ``` 日内分钟线同理: ```python theme={null} # ✅ 批量获取日内分钟 K 线 dfs = tf.klines.intraday_batch(symbols, as_dataframe=True, show_progress=True) ``` | 周期 | 参数值 | 说明 | | ----- | ----- | ------- | | 1 分钟 | `1m` | 需付费订阅 | | 5 分钟 | `5m` | 从 1m 聚合 | | 15 分钟 | `15m` | 从 1m 聚合 | | 30 分钟 | `30m` | 从 1m 聚合 | | 60 分钟 | `60m` | 从 1m 聚合 | | 日线 | `1d` | 免费服务可用 | | 周线 | `1w` | 从日线聚合 | | 月线 | `1M` | 从日线聚合 | | 季线 | `1Q` | 从日线聚合 | | 年线 | `1Y` | 从日线聚合 | 免费服务仅支持日线及以上周期,分钟级 K 线需付费订阅。 ## 行情数据 请依次检查: **1. 确认标的代码格式正确** 标的代码格式为 `代码.市场后缀`,例如 `600000.SH`、`AAPL.US`、`00700.HK`。 常见错误: * `600000` — 缺少市场后缀 * `SH600000` — 后缀位置错误 * `600000.sh` — 后缀必须大写 **2. 确认系统中存在该标的** 使用标的信息查询接口确认: ```python theme={null} inst = tf.instruments.get("600000.SH") if inst: print(f"找到标的: {inst['symbol']} - {inst['name']}") else: print("标的不存在,请检查代码是否正确") ``` **3. 确认标的属于已支持的市场** 目前支持的市场后缀:`SH`、`SZ`、`BJ`(A 股)、`US`(美股)、`HK`(港股)。 **4. 确认数据时段** * 实时行情仅在交易时段有更新 * 免费服务的日 K 数据为盘后更新,盘中不会实时变动 | | 免费服务 | 付费服务 | | ------------ | ------ | ---------------------- | | 实时行情 | ❌ | ✅ 盘中实时更新 | | 分钟 K 线 | ❌ | ✅ | | 日 K 线 | ✅ 盘后更新 | ✅ 盘中实时更新 | | WebSocket 推送 | ❌ | ✅ 需开启 WebSocket 实时行情功能 | | 频率限制 | 较严格 | 宽松 | 免费服务地址:`https://free-api.tickflow.org` ```python theme={null} tf = TickFlow.free() # 使用免费服务 ``` ## 标的代码 使用标的池接口查看: ```python theme={null} # 列出所有标的池 universes = tf.universes.list() for u in universes: print(f"{u['id']}: {u['name']} ({u['symbol_count']} 只)") # 获取某个标的池的全部标的 a_shares = tf.universes.get("CN_Equity_A") print(f"A 股共 {len(a_shares['symbols'])} 只") ``` 格式为 **`代码.市场后缀`**(英文点号分隔),后缀必须大写。 | 后缀 | 市场 | 示例 | | ---- | ------- | ----------- | | `SH` | 上海证券交易所 | `600000.SH` | | `SZ` | 深圳证券交易所 | `000001.SZ` | | `BJ` | 北京证券交易所 | `920662.BJ` | | `US` | 美股 | `AAPL.US` | | `HK` | 港股 | `00700.HK` | ## 连接问题 可在 [https://status.tickflow.org](https://status.tickflow.org) 查看服务器状态。 如果在使用 TickFlow API 时遇到连接超时(timeout)、连接被拒绝(connection refused)等问题: 推荐使用 [端点延迟测试工具](https://tickflow.org/dashboard/latency/) 快速测试各端点延迟,选择最优端点。 **如何选择最优端点?** 前往 [端点延迟测试](https://tickflow.org/dashboard/latency/) 页面,一键测试你的网络到各个端点的实时延迟,选择延迟最低的端点。 **确定端点后如何切换?** ```python theme={null} from tickflow import TickFlow # 使用延迟最低的端点,例如香港端点 tf = TickFlow(api_key="your-api-key", base_url="https://hk-api.tickflow.org") ``` ```bash theme={null} # Linux / macOS export TICKFLOW_BASE_URL="https://api.tickflow.org" # Windows PowerShell $env:TICKFLOW_BASE_URL="https://api.tickflow.org" ``` 设置后 SDK 会自动使用该端点,无需修改代码: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 自动读取 TICKFLOW_BASE_URL ``` ```bash theme={null} # 将请求地址替换为目标端点即可 curl https://api.tickflow.org/v1/klines?symbol=600000.SH&period=1d \ -H "Authorization: Bearer your-api-key" ``` ## WebSocket 实时行情 WebSocket 实时行情是独立的付费功能,需要: * 订阅 **Expert** 套餐(已包含 WebSocket 实时行情),或 * 在**自定义**套餐中单独开启「WebSocket 实时行情」功能 每个连接的最大订阅标的数由套餐决定(Expert 默认 100 个标的)。 * **401**:API Key 无效或过期,请检查 Key 是否正确 * **403**:当前套餐不包含 WebSocket 实时行情功能,需升级套餐 遇到 401/403 时**不应自动重连**,请先检查 API Key 和套餐权限。 不会。连接断开后服务端自动清除该连接的所有订阅。重连后需要重新发送 `subscribe` 恢复订阅。 使用 Python SDK 时,SDK 会自动处理断线重连和订阅恢复。 # TickFlow 简介 Source: https://docs.tickflow.org/zh-Hans/index 稳定、易用的行情数据服务,支持 A股、ETF、美股、港股 ## 简介 TickFlow 是一个稳定、易用的行情数据服务,为量化交易和金融分析提供 A 股、美股、港股的实时行情和历史 K 线数据。 支持 A股(沪深京)、ETF、指数、美股、港股 低延迟、高吞吐,轻松应对大规模行情数据获取 支持单个/批量查询,多种 K 线周期 RESTful API,OpenAPI 规范,易于集成 ## 核心功能 ### K 线数据 获取历史 K 线(OHLCV)数据,支持多种周期: * **日线** (`1d`) — A 股、美股、港股均支持 * 分钟线 (`1m`, `5m`, `15m`, `30m`, `60m`) — 仅 A 股 * 其他周期 (`1w`, `1M`, `1Q`, `1Y`) — A 股、美股、港股均支持 ### 实时行情 获取最新的实时行情快照,包含: * 最新价、涨跌幅 * 成交量、成交额 * 换手率 ... 更多扩展字段 ### 标的池 (Universe) 预定义的标的集合,方便批量获取数据: * `CN_Equity_A` - 沪深京 A 股 * `CN_ETF` - 沪深 ETF * `CN_Bond` - 沪深转债 * `CN_Index` - 沪深指数 * `US_Equity` - 美股 * `HK_Equity` - 港股 # OpenClaw Skill Source: https://docs.tickflow.org/zh-Hans/openclaw 在 OpenClaw 中安装 TickFlow Skill,让 AI 助手帮你查行情、拉 K 线、分析财务数据 ## 什么是 OpenClaw? [OpenClaw](https://openclaw.ai) 是一个 AI 助手,可以在 WhatsApp、Telegram、Discord 等聊天工具中帮你完成各种任务。 安装 TickFlow Skill 后,你可以直接用自然语言让 AI 帮你: * 查询 A 股、港股、美股的实时行情 * 获取历史 K 线数据并分析 * 查看财务报表、筛选优质股票 * 计算技术指标、对比同行业公司 * …… ## 第一步:安装 OpenClaw 如果你还没有安装 OpenClaw,请先安装。 打开终端,运行: ```bash theme={null} curl -fsSL https://openclaw.ai/install.sh | bash ``` 安装完成后,运行引导程序: ```bash theme={null} openclaw onboard ``` 打开 PowerShell,运行: ```powershell theme={null} powershell -ExecutionPolicy ByPass -c "irm https://openclaw.ai/install.ps1 | iex" ``` 安装完成后,运行引导程序: ```powershell theme={null} openclaw onboard ``` 如果你已有 Node.js 环境: ```bash theme={null} npm i -g openclaw ``` 安装完成后,运行引导程序: ```bash theme={null} openclaw onboard ``` 更多安装方式请参考 [OpenClaw 官网](https://openclaw.ai)。 ## 第二步:安装 TickFlow Skill 如果你已有 Node.js 环境,直接运行: ```bash theme={null} npx clawhub install tickflow ``` 完成! 打开终端,复制粘贴以下命令: ```bash theme={null} mkdir -p ~/.openclaw/workspace/skills/tickflow && \ curl -fsSL https://raw.githubusercontent.com/tickflow-org/tickflow-skills/refs/heads/main/tickflow/SKILL.md \ -o ~/.openclaw/workspace/skills/tickflow/SKILL.md && \ echo "✅ 安装成功!" ``` 打开 PowerShell,复制粘贴以下命令: ```powershell theme={null} powershell -Command "New-Item -ItemType Directory -Force -Path $HOME\.openclaw\workspace\skills\tickflow; curl.exe -fsSL https://raw.githubusercontent.com/tickflow-org/tickflow-skills/refs/heads/main/tickflow/SKILL.md -o $HOME\.openclaw\workspace\skills\tickflow\SKILL.md; Write-Host '✅ 安装完成'" ``` 安装完成后,在聊天中直接对 OpenClaw 说: > "帮我配置一下 TickFlow Skill,我的 API Key 是 tk\_xxx" ## 第三步:开始使用 配置完成后,在聊天中直接对 OpenClaw 说: > "帮我查一下茅台(600519.SH)和腾讯控股(00700.HK)的股价" > "获取上证指数(000001.SH)最近 60 天的日 K 线,计算 MACD" > "对比贵州茅台、五粮液、山西汾酒的 ROE 和净利率" OpenClaw 会自动调用 TickFlow Skill,帮你完成数据获取和分析。 首次使用时,OpenClaw 会自动安装 Python 依赖(通过 `uv`),可能需要等待几秒钟。 ## 相关链接 GitHub 上的 Skill 源码 在 ClawHub 上查看 TickFlow Skill 直接使用 Python SDK 接入 直接调用 HTTP API # 开始之前 Source: https://docs.tickflow.org/zh-Hans/quickstart 获取 API Key 和配置服务器地址,选择 SDK 或 API接入 ## 选择服务模式 ### 免费服务(研究学习) 如果你只需要日K线数据和标的信息(不需要实时行情),可以直接使用**免费服务**,无需注册: **免费服务特点:** * ✅ 无需注册,直接使用 * ✅ 提供历史日K线数据(1d、1w、1M、1Q、1Y) * ✅ 提供标的信息、交易所、标的池查询 * ❌ 不提供实时行情 * ❌ 不提供分钟级K线(1m、5m、15m、30m、60m) * ⚠️ 日K数据为历史数据,盘中不会实时更新 **免费服务地址:** ``` https://free-api.tickflow.org ``` 免费服务适合: * 历史数据回测 * 研究学习 * 日级别策略开发(收盘后) ### 完整服务(需注册) 如需实时行情、分钟K线或更高频率访问,请使用完整服务: ## 步骤一:获取 API Key 访问 [tickflow.org](https://tickflow.org) 登录后,在控制台一键生成你的 API Key。 ## 步骤 2:选择服务器地址 根据你选择的服务模式,使用对应的服务器地址: **完整服务(需要 API Key):** ``` https://api.tickflow.org ``` **免费服务(无需 API Key):** ``` https://free-api.tickflow.org ``` 免费服务仅提供历史日K数据,无需注册。详见上方"免费服务(研究学习)"部分。 ## 快速开始 5 分钟上手 TickFlow Python SDK 3 分钟上手 TickFlow API # 最佳实践 Source: https://docs.tickflow.org/zh-Hans/sdk/python-best-practices 生产环境使用的最佳实践和注意事项 ## 客户端管理 ### 使用上下文管理器 推荐使用 `with` 语句管理客户端生命周期,确保资源正确释放: ```python 同步 theme={null} from tickflow import TickFlow with TickFlow(api_key="your-api-key") as tf: df = tf.klines.get("600000.SH", as_dataframe=True) # 使用完毕后自动关闭连接 ``` ```python 异步 theme={null} from tickflow import AsyncTickFlow async with AsyncTickFlow(api_key="your-api-key") as tf: df = await tf.klines.get("600000.SH", as_dataframe=True) # 使用完毕后自动关闭连接 ``` ### 复用客户端实例 在应用程序中应复用客户端实例,避免频繁创建销毁: ```python theme={null} # ❌ 不推荐:每次请求创建新客户端 def get_stock_price(symbol): tf = TickFlow(api_key="your-api-key") quotes = tf.quotes.get(symbols=[symbol]) return quotes[0]["last_price"] # ✅ 推荐:复用客户端 class StockService: def __init__(self, api_key): self.tf = TickFlow(api_key=api_key) def get_price(self, symbol): quotes = self.tf.quotes.get(symbols=[symbol]) return quotes[0]["last_price"] def close(self): self.tf.close() ``` ## 错误处理 ### 捕获特定异常 SDK 提供了细粒度的异常类型,便于针对性处理: ```python theme={null} from tickflow import ( TickFlow, AuthenticationError, NotFoundError, RateLimitError, ConnectionError, TimeoutError, ) tf = TickFlow(api_key="your-api-key") try: quotes = tf.quotes.get(symbols=["INVALID.XX"]) except AuthenticationError: print("API Key 无效或已过期") except NotFoundError as e: print(f"标的不存在: {e.message}") except RateLimitError: print("请求过于频繁,请稍后重试") except (ConnectionError, TimeoutError): print("网络异常,请检查网络连接") except Exception as e: print(f"未知错误: {e}") ``` ### 异常层级 ``` TickFlowError ├── APIError │ ├── AuthenticationError (401) │ ├── PermissionError (403) │ ├── NotFoundError (404) │ ├── BadRequestError (400) │ ├── RateLimitError (429) │ └── InternalServerError (5xx) ├── ConnectionError └── TimeoutError ``` ## 重试机制 ### 自动重试 SDK 内置了智能重试机制,以下情况会自动重试: * 网络连接失败 * 请求超时 * 服务器错误 (5xx) * 频率限制 (429) ```python theme={null} # 默认重试 3 次,可自定义 tf = TickFlow( api_key="your-api-key", max_retries=5, # 最大重试次数 timeout=60.0 # 超时时间(秒) ) ``` 重试使用指数退避策略(1s, 2s, 4s...),并添加随机抖动,避免雪崩效应。 ## 批量请求优化 ### 使用批量接口 当需要获取多只股票数据时,使用批量接口而非循环单独请求: ```python theme={null} # ❌ 不推荐:循环单独请求 symbols = ["600000.SH", "000001.SZ", "600519.SH"] data = {} for s in symbols: data[s] = tf.klines.get(s) # 3 次网络请求 # ✅ 推荐:使用批量接口 data = tf.klines.batch(symbols) # 1 次网络请求 # 日内数据同理 data = tf.klines.intraday_batch(symbols) # 1 次网络请求 ``` ### 处理大量标的 批量接口自动分批并发请求,默认每批 100 个标的: ```python theme={null} # 获取 2000 只股票的数据 instruments = tf.exchanges.get_instruments("SH", instrument_type="stock")[:2000] symbols = [inst["symbol"] for inst in instruments] # SDK 自动分成 20 批并发请求 df = tf.klines.batch( symbols, as_dataframe=True, show_progress=True, # 显示进度条 max_workers=5 # 控制并发数,避免过载 ) ``` ### 调整每批标的数量 如果服务端对每次请求的标的数量有限制(例如套餐限制每次只能查询 50 个标的),可通过 `batch_size` 参数调整: ```python theme={null} # 历史 K 线批量 dfs = tf.klines.batch( symbols, as_dataframe=True, batch_size=50, # 每批 50 个标的 show_progress=True, ) # 日内 K 线批量(用法一致) dfs = tf.klines.intraday_batch( symbols, as_dataframe=True, batch_size=50, show_progress=True, ) ``` 过高的并发数可能触发频率限制,建议 `max_workers` 设置为 3-10。 ## DataFrame 最佳实践 ### 按需使用 DataFrame DataFrame 转换有一定开销,只在需要时启用: ```python theme={null} # 简单查询:使用原始数据 data = tf.klines.get("600000.SH") latest_price = data["close"][-1] # 复杂分析:使用 DataFrame df = tf.klines.get("600000.SH", as_dataframe=True) df["ma20"] = df["close"].rolling(20).mean() ``` ### 批量数据的使用 批量接口返回 `Dict[str, pd.DataFrame]`,按标的代码索引: ```python theme={null} dfs = tf.klines.batch(["600000.SH", "000001.SZ"], as_dataframe=True) # 获取单只股票的 DataFrame df_600000 = dfs["600000.SH"] print(df_600000.tail()) # 遍历所有股票 for symbol, df in dfs.items(): latest_close = df["close"].iloc[-1] print(f"{symbol}: {latest_close}") # 合并为一个大 DataFrame 进行横截面分析 import pandas as pd all_df = pd.concat(dfs.values()) ``` ## 异步最佳实践 ### 控制并发 使用信号量控制并发数量: ```python theme={null} import asyncio from tickflow import AsyncTickFlow async def main(): semaphore = asyncio.Semaphore(10) # 最大 10 个并发 async def fetch_with_limit(tf, symbol): async with semaphore: return await tf.klines.get(symbol, as_dataframe=True) async with AsyncTickFlow(api_key="your-api-key") as tf: symbols = ["600000.SH", "000001.SZ", ...] # 大量股票 tasks = [fetch_with_limit(tf, s) for s in symbols] results = await asyncio.gather(*tasks) asyncio.run(main()) ``` ### 处理部分失败 使用 `return_exceptions=True` 允许部分任务失败: ```python theme={null} async def main(): async with AsyncTickFlow(api_key="your-api-key") as tf: symbols = ["600000.SH", "INVALID.XX", "000001.SZ"] tasks = [tf.klines.get(s, as_dataframe=True) for s in symbols] results = await asyncio.gather(*tasks, return_exceptions=True) for symbol, result in zip(symbols, results): if isinstance(result, Exception): print(f"{symbol}: 获取失败 - {result}") else: print(f"{symbol}: 成功获取 {len(result)} 条数据") asyncio.run(main()) ``` ## 生产环境配置 ### 环境变量配置 ```bash theme={null} # .env 文件 TICKFLOW_API_KEY=your-production-api-key TICKFLOW_BASE_URL=https://api.tickflow.org ``` ```python theme={null} import os from dotenv import load_dotenv from tickflow import TickFlow load_dotenv() tf = TickFlow() # 自动读取环境变量 ``` ### 日志配置 ```python theme={null} import logging # 配置 httpx 日志查看请求详情 logging.basicConfig(level=logging.INFO) logging.getLogger("httpx").setLevel(logging.DEBUG) ``` ## 常见问题 SDK 会自动重试被限流的请求。如果频繁触发限流,建议: 1. 减少 `max_workers` 或 `max_concurrency` 并发数 2. 使用批量接口减少请求次数 3. 在请求间添加适当延迟 4. 升级套餐 ```python theme={null} import time for symbol in symbols: data = tf.klines.get(symbol) time.sleep(0.1) # 添加 100ms 延迟 ``` 检查以下几点: 1. 确认已安装 pandas:`pip install pandas` 2. 确认标的代码正确(如 `600000.SH` 而非 `600000`) 3. 确认时间范围内有数据 4. 检查是否有异常抛出 ```python theme={null} try: df = tf.klines.get("600000.SH", as_dataframe=True) if df.empty: print("数据为空,请检查参数") except Exception as e: print(f"请求失败: {e}") ``` 1. 使用异步客户端 `AsyncTickFlow` 2. 适当提高 `max_workers`(同步客户端)、`max_concurrency`(异步客户端) 3. 减少单次请求的数据量(如减少 `count`) 4. 使用 `show_progress=True` 监控进度 ```python theme={null} # 异步批量获取,性能最佳 async with AsyncTickFlow() as tf: df = await tf.klines.batch( symbols, count=30, # 只取最近 30 根 max_concurrency=10, show_progress=True ) ``` # 进阶示例 Source: https://docs.tickflow.org/zh-Hans/sdk/python-examples 进阶场景的代码示例,基础用法请参阅快速开始 本页仅收录[快速开始](/zh-Hans/sdk/python-quickstart)未涉及的进阶用法。基础用法(K 线获取、实时行情、标的信息、标的池、财务数据等)请先参阅快速开始。 ## K 线进阶 ### 按时间范围查询 ```python theme={null} import datetime from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") start = int(datetime.datetime(2024, 1, 1).timestamp() * 1000) end = int(datetime.datetime(2024, 12, 31).timestamp() * 1000) df = tf.klines.get( "600000.SH", period="1d", start_time=start, end_time=end, count=10000, as_dataframe=True ) print(f"获取到 {len(df)} 根 K 线") print(df.tail()) ``` ### 批量获取大量股票 批量接口自动将标的列表分批并发请求。默认每批 100 个标的,可通过 `batch_size` 参数调整。 ```python theme={null} instruments = tf.exchanges.get_instruments("SH") symbols = [inst["symbol"] for inst in instruments] print(f"共 {len(symbols)} 只股票") dfs = tf.klines.batch( symbols, period="1d", count=20, as_dataframe=True, show_progress=True, max_workers=5 ) print(f"成功获取 {len(dfs)} 只股票的数据") ``` ### 计算技术指标 ```python theme={null} import pandas as pd df = tf.klines.get("600000.SH", period="1d", count=100, as_dataframe=True) # 均线 df["ma5"] = df["close"].rolling(5).mean() df["ma20"] = df["close"].rolling(20).mean() # MACD exp1 = df["close"].ewm(span=12, adjust=False).mean() exp2 = df["close"].ewm(span=26, adjust=False).mean() df["macd"] = exp1 - exp2 df["signal"] = df["macd"].ewm(span=9, adjust=False).mean() print(df[["close", "ma5", "ma20", "macd", "signal"]].tail()) ``` ### 日内 VWAP 计算 ```python theme={null} df_5m = tf.klines.intraday("600000.SH", period="5m", as_dataframe=True) df_5m["vwap"] = (df_5m["amount"] / df_5m["volume"]).round(2) print(df_5m[["trade_time", "close", "vwap"]].tail()) ``` ### 计算日 K 换手率 结合日 K 线的成交量和股本表的流通股本,计算每日换手率。由于流通股本会随时间变动(增发、回购等),使用 `merge_asof` 为每根 K 线匹配当时有效的流通股本。 ```python theme={null} import pandas as pd from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") symbol = "600000.SH" kdf = tf.klines.get(symbol, period="1d", count=2000, as_dataframe=True) sdf = tf.financials.shares([symbol], as_dataframe=True) # 转为日期类型用于 merge_asof kdf["date"] = pd.to_datetime(kdf["trade_date"]) sdf["date"] = pd.to_datetime(sdf["period_end"]) merged = pd.merge_asof( kdf.sort_values("date"), sdf[["date", "float_shares"]].sort_values("date"), on="date", direction="backward", ) # A股 volume 单位为手(1 手 = 100 股),换手率 = volume * 100 / float_shares merged["turnover_rate"] = (merged["volume"] * 100 / merged["float_shares"]).round(4) merged["turnover_rate%"] = merged["turnover_rate"] * 100 print(merged[["trade_date", "close", "volume", "float_shares", "turnover_rate", "turnover_rate%"]].head(10)) print(merged[["trade_date", "close", "volume", "float_shares", "turnover_rate", "turnover_rate%"]].tail(10)) ``` **输出示例** ```text theme={null} trade_date close volume float_shares turnover_rate turnover_rate% 0 2018-01-26 9.864605 2184196 2.810376e+10 0.0078 0.78 1 2018-01-29 9.901386 1537831 2.810376e+10 0.0055 0.55 2 2018-01-30 9.643920 1078040 2.810376e+10 0.0038 0.38 3 2018-01-31 9.688057 1177032 2.810376e+10 0.0042 0.42 4 2018-02-01 9.783687 1735733 2.810376e+10 0.0062 0.62 5 2018-02-02 9.665989 717967 2.810376e+10 0.0026 0.26 6 2018-02-05 9.923454 1501496 2.810376e+10 0.0053 0.53 7 2018-02-06 9.916098 2443589 2.810376e+10 0.0087 0.87 8 2018-02-07 9.894030 2007701 2.810376e+10 0.0071 0.71 9 2018-02-08 9.636564 1094268 2.810376e+10 0.0039 0.39 trade_date close volume float_shares turnover_rate turnover_rate% 1990 2026-04-16 10.00 437023 3.330584e+10 0.0013 0.13 1991 2026-04-17 9.86 579330 3.330584e+10 0.0017 0.17 1992 2026-04-20 9.78 681169 3.330584e+10 0.0020 0.20 1993 2026-04-21 9.72 728490 3.330584e+10 0.0022 0.22 1994 2026-04-22 9.61 685905 3.330584e+10 0.0021 0.21 1995 2026-04-23 9.54 806247 3.330584e+10 0.0024 0.24 1996 2026-04-24 9.45 848590 3.330584e+10 0.0025 0.25 1997 2026-04-27 9.36 872815 3.330584e+10 0.0026 0.26 1998 2026-04-28 9.37 594550 3.330584e+10 0.0018 0.18 1999 2026-04-29 9.38 614950 3.330584e+10 0.0018 0.18 ``` ## 行情筛选 ### 涨跌幅排行 ```python theme={null} df = tf.quotes.get(universes=["CN_Equity_A"], as_dataframe=True) df["change_pct"] = (df["last_price"] - df["prev_close"]) / df["prev_close"] * 100 print("涨幅榜 Top 10:") print(df.nlargest(10, "change_pct")[["symbol", "last_price", "change_pct"]]) print("\n跌幅榜 Top 10:") print(df.nsmallest(10, "change_pct")[["symbol", "last_price", "change_pct"]]) ``` ### 多条件筛选 ```python theme={null} df = tf.quotes.get(universes=["CN_Equity_A"], as_dataframe=True) df["change_pct"] = (df["last_price"] - df["prev_close"]) / df["prev_close"] * 100 # 涨停股(涨幅 >= 9.9%) limit_up = df[df["change_pct"] >= 9.9] print(f"涨停股数量: {len(limit_up)}") # 放量上涨:成交额 > 10 亿且涨幅 > 3% strong = df[(df["amount"] > 1e9) & (df["change_pct"] > 3)] print(f"放量上涨股票: {len(strong)}") ``` ### 涨停 / 跌停筛选 上面的多条件筛选用涨跌幅百分比粗略估算涨停,但 A 股存在 10%、20%(创业板/科创板)、30%(北交所)等多种涨跌幅限制,按固定百分比无法覆盖所有情况。更精确的做法是用 `instruments` 接口返回的 `ext.limit_up` / `ext.limit_down`(当日涨停价 / 跌停价)与 `last_price` 直接比较。 下面的示例内置了 instruments 自动缓存:首次调用时加载,之后每天 09:10 自动刷新一次(A 股盘前涨跌停价会更新),无需手动管理。 ```python theme={null} from datetime import datetime from zoneinfo import ZoneInfo from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") _TZ = ZoneInfo("Asia/Shanghai") _inst_cache: dict[str, dict] = {} _refreshed_date = None def _ensure_instruments(): """启动时加载,之后每天 09:10 后自动刷新一次。""" global _inst_cache, _refreshed_date now = datetime.now(_TZ) today = now.date() after_0910 = now.hour > 9 or (now.hour == 9 and now.minute >= 10) if _inst_cache and not (after_0910 and _refreshed_date != today): return symbols = (tf.universes.get("CN_Equity_A") or {}).get("symbols", []) instruments = tf.instruments.batch(symbols=symbols) or [] _inst_cache = {i["symbol"]: i for i in instruments if i and i.get("symbol")} _refreshed_date = today print(f"instruments 已刷新: {len(_inst_cache)} 只") def get_limit_stocks(): """返回 (涨停 DataFrame, 跌停 DataFrame)。""" _ensure_instruments() df = tf.quotes.get(universes=["CN_Equity_A"], as_dataframe=True) def _match(row, key): inst = _inst_cache.get(row["symbol"]) if not inst: return False price = (inst.get("ext") or {}).get(key) return price is not None and abs(row.get("last_price", 1e-3) - price) < 1e-3 df["is_limit_up"] = df.apply(lambda r: _match(r, "limit_up"), axis=1) df["is_limit_down"] = df.apply(lambda r: _match(r, "limit_down"), axis=1) return df[df["is_limit_up"]], df[df["is_limit_down"]] up, down = get_limit_stocks() print(f"涨停: {len(up)} 只") print(up[["symbol", "ext.name", "last_price"]].to_string(index=False)) print(f"\n跌停: {len(down)} 只") print(down[["symbol", "ext.name", "last_price"]].to_string(index=False)) ``` 如需持续监控,只需在循环中反复调用 `get_limit_stocks()`,缓存会自动管理: ```python theme={null} import time while True: up, down = get_limit_stocks() now = datetime.now(_TZ).strftime("%H:%M:%S") print(f"[{now}] 涨停 {len(up)} 只, 跌停 {len(down)} 只") time.sleep(3) ``` ## 除权因子分析 ### 对比除权前后价格 ```python theme={null} import datetime symbol = "600519.SH" factors_df = tf.klines.ex_factors([symbol], as_dataframe=True) latest_factor = factors_df.iloc[-1] print(f"最近除权日: {latest_factor['trade_date']}, 因子: {latest_factor['ex_factor']:.6f}") ex_date = int(datetime.datetime.strptime(latest_factor["trade_date"], "%Y-%m-%d").timestamp() * 1000) start = ex_date - 10 * 86400_000 end = ex_date + 10 * 86400_000 df_raw = tf.klines.get(symbol, start_time=start, end_time=end, adjust="none", as_dataframe=True) df_qfq = tf.klines.get(symbol, start_time=start, end_time=end, adjust="forward", as_dataframe=True) print(f"\n不复权价格:") print(df_raw[["trade_date", "close"]].to_string(index=False)) print(f"\n前复权价格:") print(df_qfq[["trade_date", "close"]].to_string(index=False)) ``` ## 美股 & 港股 ### 行情与 K 线 ```python theme={null} # 美股行情 us_quotes = tf.quotes.get(symbols=["AAPL.US", "MSFT.US", "TSLA.US"], as_dataframe=True) print(us_quotes) # 港股行情 hk_quotes = tf.quotes.get(symbols=["00700.HK", "09988.HK"], as_dataframe=True) print(hk_quotes) # 美股日 K 线(支持前复权/后复权) df_us = tf.klines.get("AAPL.US", period="1d", count=100, as_dataframe=True) print(df_us.tail()) # 批量获取 us_symbols = ["AAPL.US", "MSFT.US", "GOOGL.US", "AMZN.US", "TSLA.US"] dfs = tf.klines.batch(us_symbols, period="1d", count=100, as_dataframe=True, show_progress=True) for symbol, df in dfs.items(): print(f"{symbol}: 最新收盘 {df['close'].iloc[-1]}") ``` 美股和港股目前仅支持日线级别(1d、1w、1M、1Q、1Y),暂不支持分钟 K 线和日内分时。 ## 异步高并发 ### 并发获取与分析 ```python theme={null} import asyncio from tickflow import AsyncTickFlow async def fetch_stock_data(tf: AsyncTickFlow, symbol: str) -> dict: df = await tf.klines.get(symbol, period="1d", count=60, as_dataframe=True) df["ma20"] = df["close"].rolling(20).mean() latest = df.iloc[-1] return { "symbol": symbol, "price": latest["close"], "ma20": latest["ma20"], "above_ma20": latest["close"] > latest["ma20"], } async def main(): async with AsyncTickFlow(api_key="your-api-key") as tf: symbols = ["600000.SH", "600519.SH", "000001.SZ", "000858.SZ", "601318.SH"] results = await asyncio.gather(*[fetch_stock_data(tf, s) for s in symbols]) for r in results: status = "站上" if r["above_ma20"] else "跌破" print(f"{r['symbol']}: {r['price']:.2f} ({status} MA20: {r['ma20']:.2f})") asyncio.run(main()) ``` ### 定时监控行情 ```python theme={null} import asyncio import datetime from tickflow import AsyncTickFlow async def monitor_quotes(symbols, interval=5): async with AsyncTickFlow(api_key="your-api-key") as tf: while True: quotes = await tf.quotes.get(symbols=symbols) print(f"\n--- {datetime.datetime.now().strftime('%H:%M:%S')} ---") for q in quotes: change = (q["last_price"] - q["prev_close"]) / q["prev_close"] * 100 print(f"{q['symbol']}: {q['last_price']:.2f} ({change:+.2f}%)") await asyncio.sleep(interval) asyncio.run(monitor_quotes(["600000.SH", "000001.SZ"])) ``` # 快速开始 Source: https://docs.tickflow.org/zh-Hans/sdk/python-quickstart 5 分钟上手 TickFlow Python SDK ## 安装 使用 pip 安装 TickFlow Python SDK: ```bash theme={null} pip install "tickflow[all]" --upgrade ``` SDK 支持 Python 3.9+,推荐使用 Python 3.10 或更高版本。 ## 免费服务(快速体验) 如果你只需要日K线数据和标的信息(不需要实时行情),可以直接使用**免费服务**,无需注册: ```python theme={null} from tickflow import TickFlow # 使用免费服务(无需 API key) tf = TickFlow.free() # 查询日K线数据 df = tf.klines.get("600000.SH", period="1d", count=100, as_dataframe=True) print(df.tail()) # 查询标的信息 instruments = tf.instruments.batch(symbols=["600000.SH", "000001.SZ"]) for inst in instruments: print(f"{inst['symbol']}: {inst['name']}") ``` **免费服务特点:** * ✅ 无需注册,直接使用 * ✅ 提供历史日K线数据(1d、1w、1M、1Q、1Y) * ✅ 提供标的信息、交易所、标的池查询 * ❌ 不提供实时行情 * ❌ 不提供分钟级K线(1m、5m、15m、30m、60m) * ⚠️ 日K数据为历史数据,盘中不会实时更新 免费服务适合: * 历史数据回测 * 研究学习 * 日级别策略开发(收盘后) 如需实时行情、分钟K线或更高频率访问,请继续阅读下方的完整服务配置。 *** ## 完整服务(需注册) 访问 [tickflow.org](https://tickflow.org) 登录后,在控制台一键生成你的 API Key。 有两种方式配置 API Key: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") ``` ```powershell powershell theme={null} $env:TICKFLOW_API_KEY="your-api-key" ``` ```cmd cmd theme={null} set TICKFLOW_API_KEY=your-api-key ``` ```bash theme={null} export TICKFLOW_API_KEY="your-api-key" ``` ```python theme={null} from tickflow import TickFlow # 自动读取 TICKFLOW_API_KEY 环境变量 tf = TickFlow() ``` ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 获取沪深京 A 股实时行情 quotes = tf.quotes.get(symbols=["600000.SH", "000001.SZ"]) for q in quotes: print(f"{q['symbol']}: {q['last_price']}") ``` 如果看到股票价格输出,说明 SDK 已配置成功! ## 标的代码格式与支持市场 所有按标的查询的接口(行情、K 线等)均使用**统一标的代码**,格式为:**`代码.市场后缀`**(中间为英文点号)。 ### 标的代码格式 * 格式:`代码.市场后缀` * 示例: * 股票:`600000.SH`(浦发银行)、`000001.SZ`(平安银行)、`920662.BJ`(方盛股份) * ETF:`510300.SH`(沪深 300 ETF)、`159915.SZ`(创业板 ETF) * 指数:`000001.SH`(上证指数)、`399006.SZ`(创业板指数) 代码部分使用交易所官方代码(如 6 位 A 股代码、合约代码等),**市场后缀**见下表。 ### 支持的市场(后缀) | 后缀 | 市场 | 说明 | | ------ | ------- | ---------------- | | **SH** | 上海证券交易所 | 沪市 A 股、ETF、债券等 | | **SZ** | 深圳证券交易所 | 深市 A 股、创业板、ETF 等 | | **BJ** | 北京证券交易所 | 北交所股票 | | **US** | 美股 | 美国证券市场 | | **HK** | 港股 | 香港联交所 | ### 目前支持状态 * **A 股(SH / SZ / BJ)**:已支持。可查实时行情、日 K、分钟 K、日内分时、财务数据、标的池(如 `CN_Equity_A`)等。 * **美股(US)**:已支持。实时行情、全量历史日 K 线(支持前复权/后复权)、除权因子、标的池(`US_Equity`)。 * **港股(HK)**:已支持。实时行情、全量历史日 K 线(支持前复权/后复权)、除权因子、标的池(`HK_Equity`)。 按标的查询时传入上述格式的字符串或列表即可,例如: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 多市场示例 symbols = [ "600000.SH", # 沪市 "000001.SZ", # 深市 "AAPL.US", # 美股 "00700.HK", # 港股 ] quotes = tf.quotes.get(symbols=symbols, as_dataframe=True) print(quotes) ``` **输出示例** ```text theme={null} symbol region last_price prev_close open ... ext.name ext.change_pct ext.change_amount ext.amplitude ext.turnover_rate 0 00700.HK HK 518.00 522.50 523.00 ... 腾讯控股 -0.008612 -4.50 0.016268 0.000578 1 000001.SZ CN 11.12 11.06 11.04 ... 平安银行 0.005425 0.06 0.011754 0.002192 2 AAPL.US US 273.05 270.23 270.39 ... 苹果 0.010436 2.82 0.014747 0.002238 3 600000.SH CN 9.77 9.78 9.78 ... 浦发银行 -0.001022 -0.01 0.012270 0.000951 [4 rows x 18 columns] ``` ## 基础用法 ### 标的信息 ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 查询单只标的 inst = tf.instruments.get("600000.SH") print(f"{inst['symbol']}: {inst['name']} ({inst['exchange']})") print(f"类型: {inst.get('type')}, 上市日期: {inst.get('ext', {}).get('listing_date')}") print(f"原始数据: {inst}") print("-" * 50) # 批量查询(跨市场) insts = tf.instruments.batch(["600000.SH", "000001.SZ", "AAPL.US", "00700.HK"]) for i in insts: print(f"{i['symbol']}: {i['name']}") print(f"原始数据: {i}") print("-" * 50) ``` **输出示例** ```text theme={null} 600000.SH: 浦发银行 (SH) 类型: stock, 上市日期: 1999-11-10 原始数据: {'symbol': '600000.SH', 'exchange': 'SH', 'code': '600000', 'name': '浦发银行', 'region': 'CN', 'type': 'stock', 'ext': {'type': 'cn_equity', 'listing_date': '1999-11-10', 'total_shares': 33305838300.0, 'float_shares': 33305838300.0, 'tick_size': 0.01, 'limit_up': 9.85, 'limit_down': 8.06}} -------------------------------------------------- 600000.SH: 浦发银行 原始数据: {'symbol': '600000.SH', 'exchange': 'SH', 'code': '600000', 'name': '浦发银行', 'region': 'CN', 'type': 'stock', 'ext': {'type': 'cn_equity', 'listing_date': '1999-11-10', 'total_shares': 33305838300.0, 'float_shares': 33305838300.0, 'tick_size': 0.01, 'limit_up': 9.85, 'limit_down': 8.06}} -------------------------------------------------- 000001.SZ: 平安银行 原始数据: {'symbol': '000001.SZ', 'exchange': 'SZ', 'code': '000001', 'name': '平安银行', 'region': 'CN', 'type': 'stock', 'ext': {'type': 'cn_equity', 'listing_date': '1991-04-03', 'total_shares': 19405918198.0, 'float_shares': 19405600653.0, 'tick_size': 0.01, 'limit_up': 11.95, 'limit_down': 9.77}} -------------------------------------------------- AAPL.US: 苹果 原始数据: {'symbol': 'AAPL.US', 'exchange': 'US', 'code': 'AAPL', 'name': '苹果', 'region': 'US', 'type': 'stock', 'ext': {'type': 'us_equity', 'total_shares': 14687356000.0, 'float_shares': 14662412877.0}} -------------------------------------------------- 00700.HK: 腾讯控股 原始数据: {'symbol': '00700.HK', 'exchange': 'HK', 'code': '00700', 'name': '腾讯控股', 'region': 'HK', 'type': 'stock', 'ext': {'type': 'hk_equity', 'total_shares': 9118000574.0, 'float_shares': 9118000574.0}} -------------------------------------------------- ``` ### 标的池 ```python theme={null} # 列出所有标的池 universes = tf.universes.list() top10_universes = universes[:10] for u in top10_universes: print(f"{u['id']}: {u['name']} ({u['symbol_count']} 只)") # 获取标的池详情(含全部标的代码) universe = tf.universes.get("CN_Equity_A") print(f"A 股共 {len(universe['symbols'])} 只") etf_universe = tf.universes.get("CN_ETF") print(f"ETF 共 {len(etf_universe['symbols'])} 只") ``` **输出示例** ```text theme={null} CN_Equity_SW1_490306: SW1非银金融 (3 只) CN_Equity_SW2_370604: SW2医疗服务 (12 只) CN_Equity_SW2_220803: SW2农化制品 (27 只) CN_Equity_SW2_220202: SW2化学原料 (17 只) CN_Equity_SW1_450603: SW1商贸零售 (5 只) CN_Equity_SW2_640704: SW2自动化设备 (15 只) CN_Equity_SW1_630705: SW1电力设备 (8 只) CN_Equity_SW3_110404: SW3宠物食品 (2 只) CN_Equity_SW3_110704: SW3其他养殖 (4 只) CN_Equity_SW3_450601: SW3综合电商 (2 只) A 股共 5502 只 ETF 共 1443 只 ``` ### K 线获取 单次单标的最多获取 10000 根 K 线 #### 非批量 单只标的日 K、周 K 等,使用 `tf.klines.get(symbol, ...)`: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 获取日 K 线,返回原始数据 klines = tf.klines.get("600000.SH", period="1d", count=10000) print(f"最新收盘价: {klines['close'][-1]}") # 获取日 K 线,返回 DataFrame(需安装 pandas) df = tf.klines.get("600000.SH", period="1d", count=10000, as_dataframe=True) print(df.tail(5)) # 获取分钟 K 线(1m/5m/15m/30m/60m) df = tf.klines.get("600000.SH", period="1m", count=100, as_dataframe=True) print(df.tail(5)) ``` **输出示例** ``` 最新收盘价: 9.89 symbol name timestamp trade_date trade_time open high low close volume amount 6395 600000.SH 浦发银行 1775145600000 2026-04-03 2026-04-03 00:00:00 10.25 10.25 10.08 10.12 411518 417211984.0 6396 600000.SH 浦发银行 1775491200000 2026-04-07 2026-04-07 00:00:00 10.12 10.17 9.95 9.98 378826 380103392.0 6397 600000.SH 浦发银行 1775577600000 2026-04-08 2026-04-08 00:00:00 10.00 10.11 9.95 10.09 482724 484910420.0 6398 600000.SH 浦发银行 1775664000000 2026-04-09 2026-04-09 00:00:00 10.07 10.12 9.93 9.93 460942 460220739.0 6399 600000.SH 浦发银行 1775750400000 2026-04-10 2026-04-10 00:00:00 9.93 9.95 9.86 9.89 426585 422430500.0 symbol name timestamp trade_date trade_time open high low close volume amount 95 600000.SH 浦发银行 1775804160000 2026-04-10 2026-04-10 14:56:00 9.89 9.90 9.89 9.90 2880 2849894.0 96 600000.SH 浦发银行 1775804220000 2026-04-10 2026-04-10 14:57:00 9.90 9.90 9.88 9.89 14223 14065504.0 97 600000.SH 浦发银行 1775804280000 2026-04-10 2026-04-10 14:58:00 9.90 9.90 9.90 9.90 29 28710.0 98 600000.SH 浦发银行 1775804340000 2026-04-10 2026-04-10 14:59:00 9.90 9.90 9.90 9.90 0 0.0 99 600000.SH 浦发银行 1775804400000 2026-04-10 2026-04-10 15:00:00 9.89 9.89 9.89 9.89 8404 8311556.0 ``` #### 批量(推荐) 多只标的一次性拉取,使用 `tf.klines.batch(symbols, ...)`,适合大量标的: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 批量获取多只股票的 K 线 symbols = ["600000.SH", "000001.SZ", "600519.SH"] dfs = tf.klines.batch(symbols, period="1d", count=10000, as_dataframe=True, show_progress=True) print(list(dfs.keys())) print(dfs["600000.SH"].tail()) ``` **输出示例** ```text theme={null} ['000001.SZ', '600519.SH', '600000.SH'] symbol name timestamp trade_date trade_time open high low close volume amount 6373 600000.SH 浦发银行 1772553600000 2026-03-04 2026-03-04 00:00:00 9.69 9.70 9.43 9.60 1617556 1.544304e+09 6374 600000.SH 浦发银行 1772640000000 2026-03-05 2026-03-05 00:00:00 9.56 9.81 9.56 9.78 1197453 1.163685e+09 6375 600000.SH 浦发银行 1772726400000 2026-03-06 2026-03-06 00:00:00 9.74 9.90 9.71 9.89 727260 7.147781e+08 6376 600000.SH 浦发银行 1772985600000 2026-03-09 2026-03-09 00:00:00 9.83 10.02 9.77 9.85 1168405 1.156617e+09 6377 600000.SH 浦发银行 1773072000000 2026-03-10 2026-03-10 00:00:00 9.83 9.99 9.80 9.97 528753 5.234518e+08 ``` #### 复权方式 通过 `adjust` 参数指定复权类型: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 比例前复权(默认) df = tf.klines.get("600000.SH", period="1d", count=1000, adjust="forward", as_dataframe=True) # 差值前复权(与东方财富、同花顺等软件一致) df = tf.klines.get("600000.SH", period="1d", count=1000, adjust="forward_additive", as_dataframe=True) # 不复权 df = tf.klines.get("600000.SH", period="1d", count=1000, adjust="none", as_dataframe=True) # 比例后复权 df = tf.klines.get("600000.SH", period="1d", count=1000, adjust="backward", as_dataframe=True) # 差值后复权 df = tf.klines.get("600000.SH", period="1d", count=1000, adjust="backward_additive", as_dataframe=True) ``` | `adjust` | 说明 | 适用场景 | | --------------------- | --------- | ------------- | | `"forward"` | 比例前复权(默认) | 收益率计算、量化回测 | | `"forward_additive"` | 差值前复权 | 与东方财富/同花顺价格对齐 | | `"backward"` | 比例后复权 | 长期收益对比 | | `"backward_additive"` | 差值后复权 | 与行情软件后复权价格对齐 | | `"none"` | 不复权 | 原始价格 | 东方财富、同花顺等软件默认使用**差值前复权**。如需价格一致,请使用 `adjust="forward_additive"`。 #### 时间区间 通过 `start_time` 和 `end_time` 指定时间范围(毫秒时间戳),返回数据条数受到 `count` 的限制: ```python theme={null} import datetime from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 用毫秒时间戳指定范围 start = int(datetime.datetime(2025, 1, 1).timestamp() * 1000) end = int(datetime.datetime(2025, 12, 31).timestamp() * 1000) df = tf.klines.get("600000.SH", period="1d", start_time=start, end_time=end, count=5000, as_dataframe=True) print(f"2025 年共 {len(df)} 个交易日") print(df.tail()) ``` 也可以同时使用 `count` 和 `end_time`,获取某个时间点之前的 N 根 K 线: ```python theme={null} import datetime from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 获取 2025-06-30 之前的最近 60 根日 K end = int(datetime.datetime(2025, 6, 30).timestamp() * 1000) df = tf.klines.get("600000.SH", period="1d", count=60, end_time=end, as_dataframe=True) print(df.tail()) ``` #### 除权因子 查看标的的历史除权因子: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") factors = tf.klines.ex_factors(["600000.SH", "000001.SZ"], as_dataframe=True) print(factors) ``` ### 日内分时 最新交易日的分钟 K 线(1 分钟、5 分钟等),按单只、批量或标的池方式调用。 #### 非批量 单只标的当日分钟线,使用 `tf.klines.intraday(symbol, ...)`: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 获取当日 1 分钟 K 线 df = tf.klines.intraday("600000.SH", as_dataframe=True) print(f"今日已有 {len(df)} 根分钟 K 线") print(df.tail()) print("-" * 50) # 指定 count 参数,获取当日最新5根分钟K线 df_last_1 = tf.klines.intraday("600000.SH", as_dataframe=True, count=1) print("获取当日最新 1 根分钟K线") print(df_last_1.tail()) print("-" * 50) # 获取当日 5 分钟 K 线 df_5m = tf.klines.intraday("600000.SH", period="5m", as_dataframe=True) print(f"今日已有 {len(df_5m)} 根 5 分钟 K 线") print(df_5m.tail()) ``` **输出示例** ``` 今日已有 202 根分钟 K 线 symbol name timestamp trade_date trade_time open high low close volume amount 197 600000.SH 浦发银行 1773123420000 2026-03-10 2026-03-10 14:17:00 9.97 9.97 9.96 9.96 1878 1871400.0 198 600000.SH 浦发银行 1773123480000 2026-03-10 2026-03-10 14:18:00 9.97 9.97 9.96 9.97 2090 2083325.0 199 600000.SH 浦发银行 1773123540000 2026-03-10 2026-03-10 14:19:00 9.97 9.97 9.96 9.97 1311 1306814.0 200 600000.SH 浦发银行 1773123600000 2026-03-10 2026-03-10 14:20:00 9.97 9.97 9.96 9.97 1819 1813426.0 201 600000.SH 浦发银行 1773123660000 2026-03-10 2026-03-10 14:21:00 9.97 9.97 9.96 9.97 496 494470.0 -------------------------------------------------- 获取当日最新 1 根分钟K线 symbol name timestamp trade_date trade_time open high low close volume amount 0 600000.SH 浦发银行 1773123660000 2026-03-10 2026-03-10 14:21:00 9.97 9.97 9.96 9.97 496 494470.0 -------------------------------------------------- 今日已有 41 根 5 分钟 K 线 symbol name timestamp trade_date trade_time open high low close volume amount 36 600000.SH 浦发银行 1773122700000 2026-03-10 2026-03-10 14:05:00 9.95 9.97 9.95 9.97 11766 11722589.0 37 600000.SH 浦发银行 1773123000000 2026-03-10 2026-03-10 14:10:00 9.96 9.97 9.96 9.97 5950 5930976.0 38 600000.SH 浦发银行 1773123300000 2026-03-10 2026-03-10 14:15:00 9.96 9.97 9.96 9.96 13054 13012628.0 39 600000.SH 浦发银行 1773123600000 2026-03-10 2026-03-10 14:20:00 9.96 9.97 9.96 9.97 10810 10773740.0 40 600000.SH 浦发银行 1773123900000 2026-03-10 2026-03-10 14:25:00 9.97 9.97 9.96 9.97 496 494470.0 ``` #### 批量 多只标的当日分钟线,使用 `tf.klines.intraday_batch(symbols, ...)`: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 批量获取多只股票的当日分钟 K 线 symbols = ["600000.SH", "000001.SZ", "600519.SH"] dfs = tf.klines.intraday_batch(symbols, as_dataframe=True, show_progress=True) print(f"成功获取 {len(dfs)} 只股票的日内数据") # 展示浦发银行当日最新5根分钟K线 print(dfs["600000.SH"].tail()) ``` **输出示例** ```text theme={null} 成功获取 3 只股票的日内数据 symbol name timestamp trade_date trade_time open high low close volume amount 200 600000.SH 浦发银行 1773123600000 2026-03-10 2026-03-10 14:20:00 9.97 9.97 9.96 9.97 1819 1813426.0 201 600000.SH 浦发银行 1773123660000 2026-03-10 2026-03-10 14:21:00 9.97 9.97 9.96 9.96 881 878056.0 202 600000.SH 浦发银行 1773123720000 2026-03-10 2026-03-10 14:22:00 9.96 9.97 9.96 9.96 618 615792.0 203 600000.SH 浦发银行 1773123780000 2026-03-10 2026-03-10 14:23:00 9.97 9.97 9.96 9.97 649 646777.0 204 600000.SH 浦发银行 1773123840000 2026-03-10 2026-03-10 14:24:00 9.96 9.97 9.96 9.97 1328 1323983.0 ``` #### 按标的池查询(全市场扫描) 通过标的池 ID 一次性获取整个市场的日内分时数据,适合全市场轮询和量化扫描场景: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") # 一次性获取全部 A 股最新 3 根分钟 K 线 data = tf.klines.intraday_universe("CN_Equity_A", count=3) print(f"获取到 {len(data)} 只标的的日内数据") # 展示浦发银行 kline = data["600000.SH"] print(f"600000.SH: {len(kline['timestamp'])} 根K线, 最新收盘={kline['close'][-1]}") # 也支持 as_dataframe dfs = tf.klines.intraday_universe("CN_Equity_A", count=1, as_dataframe=True) print(f"DataFrame 模式: {len(dfs)} 只标的") print(dfs["600000.SH"]) ``` **输出示例** ```text theme={null} 获取到 5540 只标的的日内数据 600000.SH: 3 根K线, 最新收盘=9.0 DataFrame 模式: 5540 只标的 symbol name timestamp trade_date trade_time open high low close volume amount 0 600000.SH 浦发银行 1787900400000 2026-08-28 2026-08-28 15:00:00 9.0 9.0 9.0 9.0 4372 3934800.0 ``` `intraday_universe` 是全市场扫描分钟K线数据的最高效方式 ### 获取实时行情 #### 按标的代码查询 ```python theme={null} quotes = tf.quotes.get(symbols=["600000.SH", "000001.SZ"], as_dataframe=True) print(quotes) ``` **输出示例** ```text theme={null} symbol region last_price prev_close open ... ext.name ext.change_pct ext.change_amount ext.amplitude ext.turnover_rate 0 600000.SH CN 9.89 9.98 9.98 ... 浦发银行 -0.009018 -0.09 0.015030 0.002103 1 000001.SZ CN 10.91 10.96 10.96 ... 平安银行 -0.004562 -0.05 0.008212 0.002860 [2 rows x 18 columns] ``` #### 按标的池查询 ```python theme={null} # 获取全部 A 股行情 quotes_df_a = tf.quotes.get(universes=["CN_Equity_A"], as_dataframe=True) print(quotes_df_a) # 获取全部沪深 ETF 行情 quotes_df_etf = tf.quotes.get(universes=["CN_ETF"], as_dataframe=True) print(quotes_df_etf) ``` **输出示例** ```text theme={null} symbol region last_price prev_close open ... ext.name ext.change_pct ext.change_amount ext.amplitude ext.turnover_rate 0 600916.SH CN 10.50 10.66 10.69 ... 中国黄金 -0.015009 -0.16 0.026266 0.025402 1 301363.SZ CN 29.16 29.14 29.37 ... 美好医疗 0.000686 0.02 0.024708 0.011435 2 600649.SH CN 4.79 4.84 4.86 ... 城投控股 -0.010331 -0.05 0.022727 0.013862 3 603681.SH CN 21.73 21.88 21.88 ... 永冠新材 -0.006856 -0.15 0.027422 0.025814 4 301137.SZ CN 61.56 59.15 58.56 ... 哈焊华通 0.040744 2.41 0.071851 0.072857 ... ... ... ... ... ... ... ... ... ... ... ... 5479 300127.SZ CN 35.83 35.19 35.51 ... 银河磁体 0.018187 0.64 0.020176 0.014084 5480 600249.SH CN 5.84 5.80 5.84 ... 两面针 0.006897 0.04 0.013793 0.008029 5481 600456.SH CN 39.64 39.17 39.50 ... 宝钛股份 0.011999 0.47 0.023487 0.017193 5482 603095.SH CN 20.30 20.41 20.60 ... 越剑智能 -0.005390 -0.11 0.030867 0.016026 5483 002181.SZ CN 10.72 10.46 10.57 ... 粤 传 媒 0.024857 0.26 0.032505 0.034027 [5484 rows x 18 columns] symbol region last_price prev_close open ... ext.name ext.change_pct ext.change_amount ext.amplitude ext.turnover_rate 0 159974.SZ CN 1.980 1.978 1.960 ... 央企创新ETF富国 0.001011 0.002 0.014156 0.014264 1 159637.SZ CN 0.924 0.910 0.914 ... 新能源车ETF东财 0.015385 0.014 0.019780 0.011927 2 159258.SZ CN 1.159 1.137 1.144 ... 机器人ETF南方 0.019349 0.022 0.014072 0.013587 3 159351.SZ CN 1.252 1.232 1.237 ... A500ETF嘉实 0.016234 0.020 0.012175 0.097820 4 159692.SZ CN 1.229 1.221 1.226 ... 证券ETF东财 0.006552 0.008 0.008190 0.025241 ... ... ... ... ... ... ... ... ... ... ... ... 1393 159775.SZ CN 0.910 0.892 0.900 ... 电池ETF建信 0.020179 0.018 0.017937 0.150701 1394 512750.SH CN 1.452 1.452 1.443 ... 基本面50ETF嘉实 0.000000 0.000 0.008264 0.005310 1395 563000.SH CN 1.051 1.036 1.040 ... 中国A50ETF易方达 0.014479 0.015 0.010618 0.012222 1396 512050.SH CN 1.239 1.220 1.225 ... A500ETF基金 0.015574 0.019 0.013115 0.224107 1397 516390.SH CN 1.007 0.992 0.998 ... 新能源车ETF汇添富 0.015121 0.015 0.017137 0.037805 [1398 rows x 18 columns] ``` ### 市场深度(五档行情) 市场深度为 Pro / Expert 套餐功能,也可单独订阅。 #### 单只标的 查询单只标的的五档买卖盘口: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") depth = tf.depth.get("600000.SH") print(depth) ``` **输出示例** ```text theme={null} {'symbol': '600000.SH', 'region': 'CN', 'timestamp': 1776754802000, 'bid_prices': [9.72, 9.71, 9.7, 9.69, 9.68], 'bid_volumes': [3192, 3870, 26168, 5849, 5480], 'ask_prices': [9.73, 9.74, 9.75, 9.76, 9.77], 'ask_volumes': [74, 1602, 1148, 1209, 1109]} ``` | 字段 | 说明 | | ------------- | ------------- | | `bid_prices` | 买入价(买1-买5,降序) | | `bid_volumes` | 买入量 | | `ask_prices` | 卖出价(卖1-卖5,升序) | | `ask_volumes` | 卖出量 | #### 批量 多只标的的五档行情,使用 `tf.depth.batch(symbols)`: ```python theme={null} from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") symbols = ["600000.SH", "000001.SZ", "600519.SH"] depths = tf.depth.batch(symbols) for sym, d in depths.items(): print(f"{sym}: 买1={d['bid_prices'][0]}×{d['bid_volumes'][0]}, 卖1={d['ask_prices'][0]}×{d['ask_volumes'][0]}") ``` **输出示例** ```text theme={null} 000001.SZ: 买1=11.23×6023, 卖1=11.24×8208 600519.SH: 买1=1291.91×87, 卖1=1292.0×11 600000.SH: 买1=9.67×1324, 卖1=9.68×118 ``` 批量查询需要 Pro(最多 100 个标的)或 Expert(最多 200 个标的)套餐。超过单次上限时,SDK 会自动分批并发请求并合并结果。 ### 财务数据 财务数据为 Expert 套餐功能,也可单独订阅。 #### 利润表 ```python theme={null} income_df = tf.financials.income(["000001.SZ"], as_dataframe=True) print(income_df.tail(3)) ``` **输出示例** ```text theme={null} symbol period_end announce_date total_assets ... accounts_payable inventory minority_interest goodwill 127 000001.SZ 2025-09-30 2025-10-25 5.766764e+12 ... NaN NaN NaN 7.568000e+09 128 000001.SZ 2025-12-31 2026-03-21 5.925777e+12 ... NaN NaN NaN 7.568000e+09 129 000001.SZ 2026-03-31 2026-04-25 6.033962e+12 ... NaN NaN NaN 7.568000e+09 [3 rows x 20 columns] ``` #### 资产负债表 ```python theme={null} balance_df = tf.financials.balance_sheet(["000001.SZ"], as_dataframe=True) print(balance_df.tail(3)) ``` **输出示例** ```text theme={null} symbol period_end announce_date total_assets ... accounts_payable inventory minority_interest goodwill 127 000001.SZ 2025-09-30 2025-10-25 5.766764e+12 ... NaN NaN NaN 7.568000e+09 128 000001.SZ 2025-12-31 2026-03-21 5.925777e+12 ... NaN NaN NaN 7.568000e+09 129 000001.SZ 2026-03-31 2026-04-25 6.033962e+12 ... NaN NaN NaN 7.568000e+09 [3 rows x 20 columns] ``` #### 现金流量表 ```python theme={null} cashflow_df = tf.financials.cash_flow(["000001.SZ"], as_dataframe=True) print(cashflow_df.tail(3)) ``` **输出示例** ```text theme={null} symbol period_end announce_date ... net_financing_cash_flow capex net_cash_change 130 000001.SZ 2025-09-30 2025-10-25 ... -8.058100e+10 1.288000e+09 -2.210800e+10 131 000001.SZ 2025-12-31 2026-03-21 ... -1.492360e+11 2.893000e+09 8.568900e+10 132 000001.SZ 2026-03-31 2026-04-25 ... -3.563400e+10 1.720000e+08 -5.219500e+10 [3 rows x 8 columns] ``` #### 核心财务指标 ```python theme={null} metrics_df = tf.financials.metrics(["000001.SZ"], as_dataframe=True) print(metrics_df.tail(3)) ``` **输出示例** ```text theme={null} symbol period_end announce_date eps_basic ... revenue_yoy net_income_yoy debt_to_asset_ratio roe_diluted 83 000001.SZ 2025-09-30 2025-10-25 1.87 ... -9.7811 -3.4987 91.0187 8.28 84 000001.SZ 2025-12-31 2026-03-21 2.07 ... -10.3978 -4.2127 90.6985 9.15 85 000001.SZ 2026-03-31 2026-04-25 0.67 ... 4.6516 3.0292 90.9830 2.83 [3 rows x 13 columns] ``` #### 股本表 ```python theme={null} shares_df = tf.financials.shares(["600000.SH", "000001.SZ"], as_dataframe=True) print(shares_df.tail(3)) ``` **输出示例** ```text theme={null} symbol period_end announce_date total_shares float_shares 327 000001.SZ 2024-12-31 2025-03-15 1.940592e+10 1.940557e+10 328 000001.SZ 2025-03-31 2025-03-31 1.940592e+10 1.940557e+10 329 000001.SZ 2025-06-30 2025-08-23 1.940592e+10 1.940560e+10 ``` #### 更多过滤条件 * 仅获取最新一期数据 ```python theme={null} latest = tf.financials.income(["600519.SH", "000001.SZ"], latest=True) for symbol, records in latest.items(): if records: print(f"{symbol} 最新营收: {records[0].get('revenue')}") ``` **输出示例** ```text theme={null} 600519.SH 最新营收: 130903889634.88 000001.SZ 最新营收: 131442000000.0 ``` * 按时间范围过滤 ```python theme={null} income_df = tf.financials.income( ["000001.SZ"], start_date="2024-01-01", end_date="2025-12-31", as_dataframe=True, ) print(income_df) ``` **输出示例** ```text theme={null} symbol period_end announce_date revenue ... net_income net_income_attributable basic_eps diluted_eps 0 000001.SZ 2024-03-31 2024-04-20 3.877000e+10 ... 1.493200e+10 1.493200e+10 0.66 0.66 1 000001.SZ 2024-06-30 2024-08-16 7.713200e+10 ... 2.587900e+10 2.587900e+10 1.23 1.23 2 000001.SZ 2024-09-30 2024-10-19 1.115820e+11 ... 3.972900e+10 3.972900e+10 1.94 1.94 3 000001.SZ 2024-12-31 2025-03-15 1.466950e+11 ... 4.450800e+10 4.450800e+10 2.15 2.15 4 000001.SZ 2025-03-31 2025-04-19 3.370900e+10 ... 1.409600e+10 1.409600e+10 0.62 0.62 5 000001.SZ 2025-06-30 2025-08-23 6.938500e+10 ... 2.487000e+10 2.487000e+10 1.18 1.18 6 000001.SZ 2025-09-30 2025-10-25 1.006680e+11 ... 3.833900e+10 3.833900e+10 1.87 1.87 7 000001.SZ 2025-12-31 2026-03-21 1.314420e+11 ... 4.263300e+10 4.263300e+10 2.07 2.07 [8 rows x 14 columns] ``` ## WebSocket 实时推送 WebSocket 为付费功能,需要订阅包含 WebSocket 实时行情的套餐(如 **Expert**)或单独开启。市场深度频道额外需要「市场深度」权限。 通过 WebSocket 订阅标的后,服务端会持续推送行情变动,适合低延迟、持续接收行情更新的场景。 SDK 提供 `tf.stream`(统一推送),按频道订阅行情和盘口: ### 基本用法 ```python theme={null} import datetime from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") stream = tf.stream @stream.on_quotes def on_quotes(quotes): for q in quotes: ts = datetime.datetime.fromtimestamp(q["timestamp"] / 1000) ext = q.get("ext", {}) name = ext.get("name", "") change_pct = ext.get("change_pct") change_str = f"{change_pct:+.2%}" if change_pct is not None else "N/A" print( f"[{ts:%H:%M:%S}] {q['symbol']} {name} " f"最新:{q['last_price']} 涨跌:{change_str} " f"开:{q['open']} 高:{q['high']} 低:{q['low']} 昨收:{q['prev_close']} " f"量:{q['volume']} 额:{q['amount']:.0f}" ) @stream.on_depth def on_depth(depths): for d in depths: print( f"[盘口] {d['symbol']} " f"买1:{d['bid_prices'][0]}×{d['bid_volumes'][0]} " f"卖1:{d['ask_prices'][0]}×{d['ask_volumes'][0]}" ) @stream.on_error def on_error(msg): print(f"错误: {msg}") # 按频道订阅 stream.subscribe("quotes", ["600000.SH", "000001.SZ"]) stream.subscribe("depth", ["600000.SH", "000001.SZ"]) stream.connect() # 阻塞直到 close() 或 Ctrl+C ``` **输出示例** ```text theme={null} [11:30:00] 600000.SH 浦发银行 最新:9.62 涨跌:-1.03% 开:9.71 高:9.73 低:9.61 昨收:9.72 量:366689 额:353371300 [11:30:00] 000001.SZ 平安银行 最新:11.04 涨跌:-0.36% 开:11.08 高:11.09 低:11.02 昨收:11.08 量:275295 额:304075500 [盘口] 600000.SH 买1:9.62×1287 卖1:9.63×3667 [盘口] 000001.SZ 买1:11.04×265 卖1:11.05×536 ``` `depth` 频道需要「市场深度」权限(Pro / Expert 或单独订阅)。无权限时订阅会收到错误提示,不影响其他频道。 ### 非阻塞模式 在后台线程运行 WebSocket,主线程继续执行其他逻辑: ```python theme={null} import time from tickflow import TickFlow tf = TickFlow(api_key="your-api-key") stream = tf.stream @stream.on_quotes def on_quotes(quotes): for q in quotes: print(f"{q['symbol']}: {q['last_price']}") stream.subscribe("quotes", ["600000.SH"]) stream.connect(block=False) # 后台线程运行 time.sleep(10) stream.subscribe("quotes", ["000001.SZ"]) # 动态追加订阅 time.sleep(30) stream.close() ``` ### 异步用法 ```python theme={null} import asyncio import datetime from tickflow import AsyncTickFlow async def main(): async with AsyncTickFlow(api_key="your-api-key") as tf: stream = tf.stream @stream.on_quotes def on_quotes(quotes): for q in quotes: ts = datetime.datetime.fromtimestamp(q["timestamp"] / 1000) ext = q.get("ext", {}) name = ext.get("name", "") print(f"[{ts:%H:%M:%S}] {q['symbol']} {name}: {q['last_price']}") await stream.subscribe("quotes", ["600000.SH", "000001.SZ"]) await stream.connect() asyncio.run(main()) ``` 如果只需获取某一时刻的行情快照,使用 REST 接口 `tf.quotes.get()` 更为简单。 完整的 WebSocket 协议说明和多语言示例请参考 [WebSocket 文档](/zh-Hans/api-reference/websocket)。 ## 异步使用 对于高并发场景,使用异步客户端: ```python theme={null} import asyncio from tickflow import AsyncTickFlow async def main(): async with AsyncTickFlow(api_key="your-api-key") as tf: # 异步获取数据 df = await tf.klines.get("600000.SH", as_dataframe=True) print(df.tail()) # 并发获取多只股票,仅演示,如需大量获取K线数据,请使用批量接口,tf.klines.batch tasks = [ tf.klines.get(s, as_dataframe=True) for s in ["600000.SH", "000001.SZ"] ] results = await asyncio.gather(*tasks) asyncio.run(main()) ``` ## 下一步 查看更多使用场景和代码示例 了解生产环境的最佳实践 # 批量查询 K线数据 Source: https://docs.tickflow.org/zh-hans/api-reference/k线数据/批量查询-k线数据 /zh-Hans/api-reference/openapi.json get /v1/klines/batch # 批量查询最新交易日的分钟K线(批量日内分时) Source: https://docs.tickflow.org/zh-hans/api-reference/k线数据/批量查询最新交易日的分钟k线(批量日内分时) /zh-Hans/api-reference/openapi.json get /v1/klines/intraday/batch # 按标的池查询最新交易日的分钟K线(标的池日内分时) Source: https://docs.tickflow.org/zh-hans/api-reference/k线数据/按标的池查询最新交易日的分钟k线(标的池日内分时) /zh-Hans/api-reference/openapi.json get /v1/klines/intraday/universe # 查询 K线数据 Source: https://docs.tickflow.org/zh-hans/api-reference/k线数据/查询-k线数据 /zh-Hans/api-reference/openapi.json get /v1/klines # 查询最新交易日的分钟K线(日内分时) Source: https://docs.tickflow.org/zh-hans/api-reference/k线数据/查询最新交易日的分钟k线(日内分时) /zh-Hans/api-reference/openapi.json get /v1/klines/intraday # 查询除权因子 Source: https://docs.tickflow.org/zh-hans/api-reference/k线数据/查询除权因子 /zh-Hans/api-reference/openapi.json get /v1/klines/ex-factors # 获取交易所列表 Source: https://docs.tickflow.org/zh-hans/api-reference/交易所/获取交易所列表 /zh-Hans/api-reference/openapi.json get /v1/exchanges 返回所有已配置元数据的交易所及其标的数量。 # 获取交易所的标的列表 Source: https://docs.tickflow.org/zh-hans/api-reference/交易所/获取交易所的标的列表 /zh-Hans/api-reference/openapi.json get /v1/exchanges/{exchange}/instruments 返回指定交易所的所有标的,可选按类型过滤。 # 批量查询实时行情 Source: https://docs.tickflow.org/zh-hans/api-reference/实时行情/批量查询实时行情 /zh-Hans/api-reference/openapi.json post /v1/quotes # 批量查询市场深度(五档行情) Source: https://docs.tickflow.org/zh-hans/api-reference/实时行情/批量查询市场深度(五档行情) /zh-Hans/api-reference/openapi.json get /v1/depth/batch # 查询实时行情 Source: https://docs.tickflow.org/zh-hans/api-reference/实时行情/查询实时行情 /zh-Hans/api-reference/openapi.json get /v1/quotes # 查询市场深度(五档行情) Source: https://docs.tickflow.org/zh-hans/api-reference/实时行情/查询市场深度(五档行情) /zh-Hans/api-reference/openapi.json get /v1/depth # 批量查询标的元数据 Source: https://docs.tickflow.org/zh-hans/api-reference/标的/批量查询标的元数据 /zh-Hans/api-reference/openapi.json post /v1/instruments 使用 POST 方法批量查询,支持更多标的(最多 1000 个)。 # 查询标的元数据 Source: https://docs.tickflow.org/zh-hans/api-reference/标的/查询标的元数据 /zh-Hans/api-reference/openapi.json get /v1/instruments 根据标的代码获取元数据,包括名称、交易所、类型等信息。 使用 GET 方法时通过 URL 参数传递标的代码。 # 批量获取标的池详情 Source: https://docs.tickflow.org/zh-hans/api-reference/标的池/批量获取标的池详情 /zh-Hans/api-reference/openapi.json post /v1/universes/batch # 获取标的池列表 Source: https://docs.tickflow.org/zh-hans/api-reference/标的池/获取标的池列表 /zh-Hans/api-reference/openapi.json get /v1/universes # 获取标的池详情 Source: https://docs.tickflow.org/zh-hans/api-reference/标的池/获取标的池详情 /zh-Hans/api-reference/openapi.json get /v1/universes/{id} # 查询利润表 Source: https://docs.tickflow.org/zh-hans/api-reference/财务数据/查询利润表 /zh-Hans/api-reference/openapi.json get /v1/financials/income 获取指定标的的利润表数据,包含营收、利润、费用、EPS 等核心字段。 # 查询核心财务指标 Source: https://docs.tickflow.org/zh-hans/api-reference/财务数据/查询核心财务指标 /zh-Hans/api-reference/openapi.json get /v1/financials/metrics 获取指定标的的核心财务指标,包含每股指标、盈利能力、成长性和偿债能力。 # 查询现金流量表 Source: https://docs.tickflow.org/zh-hans/api-reference/财务数据/查询现金流量表 /zh-Hans/api-reference/openapi.json get /v1/financials/cash-flow 获取指定标的的现金流量表数据,包含经营/投资/筹资三类净现金流。 # 查询股本表 Source: https://docs.tickflow.org/zh-hans/api-reference/财务数据/查询股本表 /zh-Hans/api-reference/openapi.json get /v1/financials/shares 获取指定标的的股本数据,包含总股本和流通股本。 # 查询资产负债表 Source: https://docs.tickflow.org/zh-hans/api-reference/财务数据/查询资产负债表 /zh-Hans/api-reference/openapi.json get /v1/financials/balance-sheet 获取指定标的的资产负债表数据,包含资产、负债、权益核心科目。