mirror of
https://ghfast.top/https://github.com/aeroxw/easy_tdx_max.git
synced 2026-09-12 22:44:22 +08:00
- web-api.md:REST/WebSocket/SSE 端点与示例;吸收 api_reference.md 的 WebSocket 帧表/控制消息/行为约定/前端接入,消除两处互补重复 - web-ui.md:行情终端与回测工作台零代码操作手册(原错位嵌套在 「本地 K 线仓库」章节下的 Web UI 块,补全章节结构) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
11 KiB
Web API(REST + WebSocket)
概述
将 easy-tdx 暴露为 REST + WebSocket 服务,供前端、其他语言或远程调用。无需额外注册,零配置启动。
安装
# 标准安装
pip install easy-tdx[web]
# 开发模式(从源码安装,支持热重载)
pip install -e ".[web]"
快速启动
# 启动 Web API 服务器(自动连接最优 TDX 服务器)
easy-tdx serve
# 启动后浏览器打开 http://127.0.0.1:8000/docs 查看完整 API 文档(Swagger UI)
# 也可以访问 http://127.0.0.1:8000/redoc 查看 ReDoc 格式文档
# 指定端口和 TDX 服务器
easy-tdx serve --port 8080 --tdx-host 119.147.212.81
# 开发模式(代码修改后自动重载)
easy-tdx serve --reload
💡 启动后访问 http://127.0.0.1:8000/docs 可以看到完整的交互式 API 文档,支持在线调试每个接口。
REST API 示例
# ── 基础行情 ──
# 获取深圳市场证券数量
curl "http://localhost:8000/api/v1/security/count?market=SZ"
# 获取股票K线
curl "http://localhost:8000/api/v1/bars?market=SZ&code=000001&category=DAY&count=100"
# 批量获取实时行情
curl -X POST "http://localhost:8000/api/v1/quotes" \
-H "Content-Type: application/json" \
-d '{"stocks": [{"market": "SZ", "code": "000001"}, {"market": "SH", "code": "600000"}]}'
# 市场统计
curl "http://localhost:8000/api/v1/market/stat"
# 全市场强势股排名(基于本地 vipdoc 数据,扫描约 30-60 秒)
# steady = 中长期稳健 / breakout = 近期妖股 / balanced = 均衡
curl "http://localhost:8000/api/v1/market/strength?preset=breakout&top_n=20"
# 自定义权重 + 过滤低流动性(日均成交额 ≥ 5000 万)
curl "http://localhost:8000/api/v1/market/strength?w5=0.5&w20=0.3&w60=0.2&min_amount=50000000&top_n=30"
# 板块信息(标准协议)
curl "http://localhost:8000/api/v1/block?filename=block_gn.dat"
# ── 板块分析(MAC 协议)──
# 行业板块列表
curl "http://localhost:8000/api/v1/board-mac/list?board_type=HY&count=50"
# 板块成分股(按涨幅排序)
curl "http://localhost:8000/api/v1/board-mac/members?board_symbol=881001&count=20"
# 个股所属板块
curl "http://localhost:8000/api/v1/board-mac/belong?market=SZ&code=000001"
# 板块摘要(含主力净流入、涨跌家数)
curl "http://localhost:8000/api/v1/board-mac/summary?board_symbol=881001"
# 行业板块涨幅排名 Top 10
curl "http://localhost:8000/api/v1/board-mac/ranking?board_type=HY&top_n=10"
# 板块 20 日涨幅排行
curl "http://localhost:8000/api/v1/board-mac/change-ranking?board_type=HY&days=20&top_n=10"
# ── 资金 / 信息 ──
# 个股资金流向(主力/散户净流入)
curl "http://localhost:8000/api/v1/mac/capital-flow?market=SH&code=600519"
# 个股基本信息快照
curl "http://localhost:8000/api/v1/mac/symbol-info?market=SZ&code=000001"
# 服务器交易时段信息
curl "http://localhost:8000/api/v1/mac/server-info"
# ── 公告检索(巨潮资讯网,独立数据源)──
# 检索公司公告(无需 TDX 行情服务器)
curl "http://localhost:8000/api/v1/announcements?code=688017&count=30&page=1"
# 返回每条含 url(4 参数可直点打开)和 pdf_url(PDF 直链):
# {"data": [{"title":"...","type":"...","date":"...","url":".../detail?stockCode=...","pdf_url":"http://static.cninfo.com.cn/.../xxx.PDF",...}], "count": 30}
# ── 财报三表(新浪财经,独立数据源)──
# 利润表(type: lrb/fzb/llb)
curl "http://localhost:8000/api/v1/sina/financial-report?code=600519&type=lrb&num=8"
# 返回每行一期(最新在前),列为科目名(float)+ {科目}_同比(如有):
# ── 排行 / 竞价 / 异动 ──
# 全 A 涨幅排行前 20
curl "http://localhost:8000/api/v1/mac/quote-list?category=A&count=20&sort_type=CHANGE_PCT"
# 集合竞价数据
curl "http://localhost:8000/api/v1/mac/auction?market=SZ&code=000001"
# 市场异动行情
curl "http://localhost:8000/api/v1/mac/unusual?market=SH&count=50"
# ── 扩展市场(期货/港股/美股)──
# 港股 K 线
curl "http://localhost:8000/api/v1/ex/bars?market=HK_MAIN_BOARD&code=00700&category=DAY&count=30"
# 美股实时报价
curl "http://localhost:8000/api/v1/ex/quote?market=US_STOCK&code=AAPL"
# ── 技术指标 ──
# 列出所有可用指标
curl "http://localhost:8000/api/v1/indicator/list"
# 计算 MACD + KDJ 指标
curl -X POST "http://localhost:8000/api/v1/indicator/compute" \
-H "Content-Type: application/json" \
-d '{"data": [{"open":10,"close":10.5,"high":11,"low":9.5,"vol":1000}], "indicators": ["MACD", "KDJ"]}'
# ── 缠论分析 ──
curl -X POST "http://localhost:8000/api/v1/chanlun/analyze" \
-H "Content-Type: application/json" \
-d '{"market": "SZ", "code": "000001", "category": "DAY", "count": 200}'
# ── 板块总览(一次取全部板块:当日涨跌幅 + 涨速 + 3/5/20日/YTD 涨幅 + 领涨股,服务端 15s 缓存)──
# board_type: HY 行业一级 / HY2 行业二级 / GN 概念 / FG 风格 / DQ 地区
curl "http://localhost:8000/api/v1/board-mac/overview?board_type=HY"
curl "http://localhost:8000/api/v1/board-mac/overview?board_type=GN"
# ── 回测任务(WebUI 回测工作台同款后端)──
# 列出内置策略及参数 schema
curl "http://localhost:8000/api/v1/backtest/strategies"
# 提交异步回测(strategy 见 /backtest/strategies;完整字段与 portfolio/multi/optimize/wf/evaluate
# 各端点的请求体以 /docs 的 Swagger 为准),返回 task_id
curl -X POST "http://localhost:8000/api/v1/backtest/run/async" \
-H "Content-Type: application/json" \
-d '{"strategy": "ma_cross", "symbol": "SZ:000001", "category": "DAY", "count": 2000}'
# 轮询任务结果(对比页/导出亦走 /backtest/tasks)
curl "http://localhost:8000/api/v1/backtest/tasks/<task_id>"
# ── 策略库(保存的策略持久化 SQLite)──
curl "http://localhost:8000/api/v1/strategies"
# ── 自选股 ──
curl "http://localhost:8000/api/v1/watchlist"
curl -X POST "http://localhost:8000/api/v1/watchlist" \
-H "Content-Type: application/json" -d '{"market": "SH", "code": "600519", "name": "贵州茅台"}'
# ── AI 解读(模型 Key 只存本地 ~/.easy_tdx/llm.json)──
curl "http://localhost:8000/api/v1/llm/config" # 当前配置 + Provider 预设
curl -X POST "http://localhost:8000/api/v1/llm/chat/async" \
-H "Content-Type: application/json" \
-d '{"prompt": "解读这份回测报告:..."}' # 后台任务,GET /llm/chat/tasks/{id} 轮询
# ── 交易时段(自动刷新门控用)──
curl "http://localhost:8000/api/v1/market/session"
WebSocket 实时行情
/api/v1/ws/realtime/{symbol}(v1.28 起接通数据源):连接即订阅指定标的,服务端
经 RealtimeDataFeed(按 interval 秒轮询五档快照 → EventBus)推送 tick 帧;
连接断开自动退订,无人订阅时完全停止轮询。盘外时段默认只睡不拉(交易时段过滤),
本地冒烟/演示可配合 EASY_TDX_E2E_MOCK=1 的合成行情随时验证(见
scripts/ws_smoke.py)。
const ws = new WebSocket("ws://localhost:8000/api/v1/ws/realtime/SZ000001");
ws.onmessage = (event) => {
const frame = JSON.parse(event.data);
if (frame.type === "tick") {
// {type:"tick", symbol:"SZ000001", market:"SZ", code:"000001",
// price:10.5, volume:12345, ts:1760000000.0,
// open, high, low, pre_close, amount, name}
console.log(frame.symbol, frame.price, frame.ts);
} else if (frame.type === "ping") {
// 服务端 30s 空闲心跳,忽略即可(客户端无须回包)
}
};
// 动态订阅更多标的(服务端回 {"type":"status","msg":"subscribed SH600000"})
ws.send(JSON.stringify({action: "subscribe", symbol: "SH600000"}));
// 退订
ws.send(JSON.stringify({action: "unsubscribe", symbol: "SH600000"}));
服务端推送帧(JSON)
| type | 触发 | 字段 |
|---|---|---|
tick |
轮询到标的的最新快照(价格/量变化才推,约 interval 秒一拍) |
symbol、market、code、price、volume、ts(epoch 秒)、open、high、low、pre_close、amount、name |
ping |
连续 30s 未收到客户端消息的心跳 | —(客户端忽略即可,无须回包) |
status |
客户端 subscribe/unsubscribe 的确认 | msg(如 subscribed SH600000) |
error |
非法 JSON / 未知 action / 超出订阅上限 | msg |
客户端控制消息(JSON 文本帧)
{"action": "subscribe", "symbol": "SH600000"}
{"action": "unsubscribe", "symbol": "SH600000"}
行为约定
- 连接即订阅 path 上的 symbol;断开自动退订全部标的。
- 按需轮询:订阅集合为空时服务端不产生任何行情请求;去重后标的总数上限
80(
get_stock_quotes协议约束)。 - 交易时段:默认 A 股时段外只睡不拉(无 tick 帧,心跳照发);mock 模式
(
EASY_TDX_E2E_MOCK=1)不受限制。 - 背压:消费过慢时丢最旧快照保最新,不积压。
- 环境变量:
EASY_TDX_WS_INTERVAL(轮询间隔秒数,默认 3.0)。
浏览器接入建议(自动重连 + 心跳容忍):onclose 后指数退避重连(参考
web-ui/src/stores/quotes.ts 对 SSE 的同类处理);{"type":"ping"} 心跳帧直接
忽略、不回包;连续 N 秒无任何帧(含 ping)再视为僵死连接主动重连。
前端接入方式(自动重连 + 心跳容忍)
function connectRealtime(symbol: string, onTick: (f: TickFrame) => void) {
let retry = 0
let ws: WebSocket | null = null
const open = () => {
ws = new WebSocket(`ws://${location.host}/api/v1/ws/realtime/${symbol}`)
ws.onmessage = (e) => {
const frame = JSON.parse(e.data)
if (frame.type === 'tick') { retry = 0; onTick(frame) } // ping/status 忽略
}
ws.onclose = () => {
retry += 1
setTimeout(open, Math.min(1000 * 2 ** (retry - 1), 30_000)) // 指数退避
}
}
open()
return () => ws?.close()
}
说明:看板/自选页的实时刷新已由 SSE
/stream/quotes(全量快照、单连接共享) 承担;WS 通道定位是按需订阅单标的 tick 事件(后续实时策略信号的接入点), 两条链路按场景选用,不要求同时连接。手动冒烟见scripts/ws_smoke.py。
API 文档
启动服务后访问:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
编程 API
from easy_tdx.web import create_app
import uvicorn
app = create_app(host="119.147.212.81", port=7709)
uvicorn.run(app, host="0.0.0.0", port=8000)