mirror of
https://github.com/shy3130/tick-stock-panel.git
synced 2026-11-02 10:26:13 +00:00
release: v0.3.6 — 核心+扩展架构完善版
合并 0.3.6 分支全部内容 (36 提交, 详细历史见 0.3.6 分支): ■ 数据与插件 - TdxQuant 数据源: 通达信量化接入 (实时/五档/日K/复权/分钟), tdxaidata 收进默认依赖 - 扩展表两级拉取配方: 概念/行业出厂即带完整可拉配置, 可作自定义接入参考示例 - 能力门禁日志带生效源; 标的池解析只走 instruments 维表 ■ 页面扩展化 - 11 个官方页面全量迁移为单文件扩展 (custom/*/extension.tsx), 删目录即卸载 - 运行时页面包系统: 打包产物上传即挂载, 免重建宿主 - 新装用户扩展页默认隐藏, 老用户升级菜单无感 ■ AI - Responses 协议接入; 会话历史与长任务跨设备同步 (服务端注册表) - 助手头部快捷入口 + 悬浮球拖拽 zoom 坐标系修复 + 系统设置开关 ■ 界面 - 设置「关于」子菜单: 版权/更新/打赏 + 开源许可弹窗与合规声明双保险 - 侧栏两态收起、数据/AI 助手快捷行 (同步呼吸光晕)、核心/扩展 ext 标记 - 界面缩放默认 90%; 菜单设置徽标 Swiss 化; 策略池「叠加」分组 - 情绪评分口径可配置; 财务画像 5 张子表手动拉取 ■ 文档与其他 - README 重构「核心+扩展」主线 + 架构图重画; 开放端点数核实为 65 - 版本号 bump 0.3.6; tdx 物化库测试夹具补 macOS dylib
This commit is contained in:
@@ -64,6 +64,7 @@ AI_DAILY_TOKEN_BUDGET=500000 # 每日 token 预算上限
|
||||
| 配置项 | 说明 |
|
||||
| :--- | :--- |
|
||||
| `AI_PROVIDER` | `openai_compat`(OpenAI 兼容,支持 DeepSeek / 通义 / OpenAI 等)或 `ollama`(本地模型) |
|
||||
| `AI_PROTOCOL` | 请求协议: `chat_completions`(默认, 兼容面最广)或 `responses`(OpenAI 官方新协议, DeepSeek 官方亦已支持); 仅 openai 系 provider 生效, 也可在设置页切换 |
|
||||
| `AI_BASE_URL` | 接口地址,如 DeepSeek `https://api.deepseek.com/v1` |
|
||||
| `AI_API_KEY` | 留空则关闭 AI 功能 |
|
||||
| `AI_MODEL` | 模型名,如 `deepseek-chat` |
|
||||
|
||||
@@ -804,7 +804,7 @@ researchUniverses()
|
||||
| price_limits.py:87-101 | numpy_limit_pct_vectors(当前名推断) | ✓ |
|
||||
| capabilities.py:44-45 | 复权口径一致性"不做路由耦合"注释 | ✓ |
|
||||
| index_const.py:12-15 | 核心四只代码(000001.SH/399001.SZ/399006.SZ/000680.SH) | ✓ |
|
||||
| daily_pipeline.py:92-125 | _resolve_universe(CN_Equity_A 当前池) | ✓ |
|
||||
| daily_pipeline.py | _resolve_universe(instruments 维表 + 自选,无池兜底) | ✓ |
|
||||
| kline_sync.py:358-367 | (symbol, trade_date) 去重 keep=last 原子合并 | ✓ |
|
||||
| scoring.py:13-51 / 53-66 / 91-104 / 108+ | VIRTUAL 依赖 35 项 / 预热表 / 依赖展开与预热推导 / scoring_value_expr | ✓(全文读取,附录A 由其逐字推导) |
|
||||
| monitor.py:1314-1322 | score_min/max 消费 result.scores | ✓ |
|
||||
|
||||
+13
-1
@@ -161,6 +161,10 @@
|
||||
|
||||
## 🧰 数据与扩展
|
||||
|
||||
### 页面包(运行时扩展页面)
|
||||
|
||||
页面可以打包成**单文件 ES 模块产物**(`frontend/page-pack-template` 一键构建),在「设置 → 页面包」上传即挂载为完整页面 — 路由、侧栏入口、菜单管理自动注册,**宿主无需重新构建**;本地 dev / 生产 / 桌面端一致生效。上传时即时试载校验契约(清单格式、路由冲突),坏包停用并显示原因;启停删除随时管理,刷新后生效。源码级扩展(`frontend/src/custom/`)与声明式分析页面仍是随构建的另外两条扩展路径。契约与安全边界见 [page-sdk.md](./page-sdk.md)。
|
||||
|
||||
### 数据源插件化
|
||||
|
||||
内置 [TickFlow](https://tickflow.org) 官方 SDK(日 K / 分钟 K / 指数 / 财务 / 实时行情),同时支持接入第三方数据源:YAML 声明自有 HTTP 接口,或开发插件源。多个数据集(日K / 除权因子 / 实时行情 / 分钟K / 五档盘口 / 财务,注册表持续扩展)按源声明自由组合,在「设置 → 数据源」切换。
|
||||
@@ -195,6 +199,14 @@ timeseries 模式的表 (如人气排行) 默认只能从开启拉取之日起
|
||||
|
||||
数据量大的接口 (全市场排行、批量快照) 单次响应装不下时, 拉取配置可声明分页 (仅 GET): **页码参数名**(`page_param`, 如 `page`)、**每页条数参数名**(`page_size_param`, 如 `pageSize`)与**每页条数**(`page_size`)。配置后单次拉取按页循环请求并合并结果, 空页/不足一页自动判停; **最多页数**(`max_pages`, 默认 20, 上限 200)防止接口永远返回数据拖死循环。POST body 分页不支持 (请求体是固定模板)。
|
||||
|
||||
##### 两级拉取协议 (目录 → 逐条目)
|
||||
|
||||
有些数据源只提供「类别清单」+「单类别成员」两个端点 (同花顺概念/行业、多数板块类 API), 没有一次返回「标的 → 所属类别」全量映射的接口。这类源在拉取配置里声明 `fanout` 配方即可, 无需任何按表硬编码: 先请求 `pull.url` 拿第一级目录, 再按 `fanout.param` 并发拉每个条目的成员, 最后**反转为「标的 → 类别清单」**并与普通单请求路径产出同构的行。
|
||||
|
||||
配方字段 (除注明外均为字符串): `url` 第二级地址、`param` 第二级查询参数名、`id_field` 第一级条目中作为该参数值的字段、`label_field` 展示名字段 (可选, 仅用于告警)、`items_path` 第二级响应的成员数组 dot-path、`member_id_field` / `member_label_field` 成员里的代码与名称字段、`symbol_col` / `name_col` / `value_col` 输出列名、`separator` 多类别拼接符 (概念用 `;`, 行业层级用 `-`)、`concurrency` 并发上限 (默认 8)、`retries` 单条目失败重试次数 (默认 1, 用尽则跳过该条目并记 warning; 全部条目失败才报错)。鉴权与标识头沿用 `pull.auth` / 通用出站口径。
|
||||
|
||||
概念/行业两张内置表出厂即带完整配方, 在「数据」页展开本表 → **拉取** 可查看全部字段, 接入自有板块类源时照抄即可。
|
||||
|
||||
##### `/rows` 查询接口 (面向二次开发)
|
||||
|
||||
每张扩展表天然是标准 HTTP 接口 `GET /api/ext-data/{id}/rows`, 供页面之外的任意消费方调用:
|
||||
@@ -303,4 +315,4 @@ AI 客户端 ⇄ MCP stdio (薄桥) ⇄ HTTP + Bearer Token ⇄ 开放网关
|
||||
|
||||
### 桌面客户端版本清单
|
||||
|
||||
发布流水线会在每个 Release 附带 `latest.json`(版本号、三平台下载地址、sha256),设置 → 系统设置 → 检查更新即基于它(优先 GitHub API)提示新版本。
|
||||
发布流水线会在每个 Release 附带 `latest.json`(版本号、三平台下载地址、sha256),设置 → 关于 → 检查更新即基于它(优先 GitHub API)提示新版本。
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# 页面包开发指南 (Page Pack SDK v1)
|
||||
|
||||
页面包是**运行时可挂载的页面产物**:把页面打包成单文件 ES 模块(`extension.js`),在「设置 → 页面包」上传,刷新后即成为完整页面——自动注册路由、侧栏入口,可在菜单设置里排序/隐藏。本地 dev、生产构建、桌面端三种运行形态一致生效,宿主无需重新构建。
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
cp -r frontend/page-pack-template my-pack && cd my-pack
|
||||
pnpm install && pnpm build # → dist/extension.js
|
||||
```
|
||||
|
||||
打开宿主「设置 → 页面包」→ 填 ID(字母/数字/下划线)→ 选择 `dist/extension.js` → 上传并校验 → 刷新页面。
|
||||
|
||||
## 产物契约 (apiVersion 1)
|
||||
|
||||
产物必须 `export default` 一个清单对象:
|
||||
|
||||
```tsx
|
||||
const extension = {
|
||||
id: 'demo.hello', // 带命名空间且全局唯一; 冲突时整个包被拒
|
||||
apiVersion: 1 as const,
|
||||
routes: [{
|
||||
id: 'hello',
|
||||
path: '/demo-hello', // 非根绝对路径、静态(不支持 :param/通配), 不得覆盖核心或已有页面
|
||||
mount: (el, ctx) => { // 渲染进容器; 返回清理函数(可选)
|
||||
const root = createRoot(el)
|
||||
root.render(<HelloPage />)
|
||||
return () => root.unmount()
|
||||
},
|
||||
}],
|
||||
navigation: [{
|
||||
id: 'hello', routeId: 'hello', label: '页面包演示', icon: 'Sparkles',
|
||||
}],
|
||||
}
|
||||
export default extension
|
||||
```
|
||||
|
||||
校验与冲突规则由宿主注册表统一执行(与源码级扩展 `frontend/src/custom/` 同一机制);上传时即时试载校验,启动时再次校验,失败会停用该包并在面板显示原因。
|
||||
|
||||
## 能力桥 ctx
|
||||
|
||||
页面包**自包含**(React 等依赖由模板打进产物,与宿主不共享模块实例),宿主能力经 `ctx` 暴露:
|
||||
|
||||
| 能力 | 说明 |
|
||||
| --- | --- |
|
||||
| `ctx.api` | 宿主完整 API 封装(同源 fetch、自动携带登录态、统一错误处理) |
|
||||
| `ctx.QK` | 集中查询键(若你自行使用 TanStack Query 可作 key 规范) |
|
||||
| `ctx.cn` | 样式类合并工具(clsx + tailwind-merge) |
|
||||
| `ctx.format` | 数值/日期格式化工具集 |
|
||||
|
||||
**禁止** import 宿主内部模块(`@/lib/...` 等别名在产物构建中不可解析);数据请求一律经 `ctx.api`,不得自行拼后端 URL 绕过封装。
|
||||
|
||||
## 图标白名单
|
||||
|
||||
`navigation[].icon` 按名称解析,白名单:`Activity BarChart3 Bell BookOpen Brain Calendar Database Globe LineChart PieChart Shield Sparkles Star Table TrendingUp Zap`(缺省 `Sparkles`)。需要扩充时在 `frontend/src/extensions/runtime.tsx` 的 `ICON_ALLOWLIST` 增补。
|
||||
|
||||
## 约束与边界
|
||||
|
||||
- **样式**:宿主 Tailwind 按需编译,任意类名不保证存在——布局关键样式用内联样式;主题色用宿主 CSS 变量(如 `var(--accent)`)。
|
||||
- **路由集成**:页面挂在宿主路由容器内(`/你的路径` 可直达、可刷新),但包内不共享宿主 Router 上下文——需要跳转宿主页面时用 `window.location` 或自行包 `MemoryRouter`。
|
||||
- **生效方式**:上传/启停后**刷新页面生效**(挂载发生在启动引导窗口),不做热插拔。
|
||||
- **大小**:上限 5MB/包;自包含 React 后典型产物 60–150KB(minify + 可自行加 brotli/gzip 由后端协商)。
|
||||
- **安全**:页面包是任意代码,与登录会话同权运行——只上传自己或可信来源的产物;这是单用户产品的既定边界,第三方插件沙箱不在 v1 范围。
|
||||
- **版本**:宿主升级破坏契约时提升 `apiVersion` 并保留旧版兼容期;产物内 `apiVersion` 不匹配会被明确拒绝。
|
||||
|
||||
## 与其他扩展方式的取舍
|
||||
|
||||
| 方式 | 适用 | 见 |
|
||||
| --- | --- | --- |
|
||||
| 页面包(运行时产物) | 免重建挂载、独立分发 | 本文档 |
|
||||
| 源码级扩展 `frontend/src/custom/<ns>/extension.tsx` | 随宿主一起构建维护、可用全部核心模块 | `docs/secondary-development.md` §3 |
|
||||
| 声明式分析页面(零代码) | 扩展数据 + 模板化列表/分组页 | 设置 → 扩展页面 |
|
||||
@@ -34,6 +34,11 @@ hidden: false # (可选)true = 已加载但对设置
|
||||
description: "数据源描述"
|
||||
install_hint: "pip install xxx" # 未装依赖时显示的安装提示
|
||||
homepage: "https://example.com" # (可选)官网/申请地址, 显示在设置页 Key 配置说明中
|
||||
billing: points # (可选)计费标识: "points" → 设置页能力芯片/适配行标注「积分」
|
||||
billing_note: "消耗与频率/范围相关,间隔越短越高" # (可选)计费提示: 设置页按警示框展示
|
||||
usage_notes: # (可选)使用要点: 各能力规模/节奏, 详情卡以列表展示
|
||||
- "实时快照: 600 只/批, 全市场一轮约 10 批"
|
||||
key_manage_url: "https://example.com/me" # (可选)Key/账务管理页, 显示在设置页 Key 配置区(如积分明细入口)
|
||||
```
|
||||
|
||||
只声明真实提供的数据集;未声明的数据集 `provider_has_dataset` 返回 False,自动回退
|
||||
@@ -313,6 +318,11 @@ uv run --extra dev python -m ruff check app/plugins/<your_plugin>/ tests/test_<y
|
||||
- `client.py` — httpx 客户端(X-api-key 认证 + 统一信封解包 + 分页 + 页间隔限频 + 单标的日K + dump 预签名下载, S3 下载不带 Key 头)
|
||||
- `provider.py` — Provider 实现(实测/文档双字段名映射、百分数→小数制、volume 股→手、上海零点戳 +8h 时区、dump 按 release 版本缓存、软失败、Key 探测)
|
||||
- `tests/test_fuyao_provider.py` — 73 个契约测试, 是新插件的测试范本
|
||||
- **`backend/app/plugins/tdxquant/`** — 通达信量化数据服务(runtime: python; `tdxaidata` 已是后端默认依赖, ctypes 包装的私有 TCP 协议, wheel 自带跨平台原生库)
|
||||
- 提供 `realtime`(五市场全 A 股票池枚举 + 600 只/批快照, 批间失败隔离)、`depth5`(快照自带买卖五档数组, 手口径透传)、`daily`(count 模式单标的拉取, 原始价, volume 股→手, amount 万元→元, `iter_daily` 逐标的流式)、`adj_factor`(事件接口每10股口径 ÷10 转每股 + 本地K线一次配价, 交易所公式推导单事件比值, 涨跌停自检)、`minute`(1m count 模式单标的, 240 根/日, 深度约 40 交易日, datetime=Date+Time 拼北京墙钟 naive, 与日K同口径 股→手/万元→元)、`full_minute`(修复轮 `get_intraday_batch` 当日窗口 + 稳态增量 `get_intraday_latest` 每股最新 N 根; 无批量端点, 全市场一轮 10 分钟量级); 指数快照直接支持(上证指数走 TDX 999999.SH 别名, `get_realtime_indices` 映射); 快照无名称列由维表关联; 未声明 financial → 回退 TickFlow; 清单声明 `billing: points` + `key_manage_url`(商城积分明细入口)
|
||||
- `client.py` — 原生层封装(lib 私有物化 + token 注入双 ini + `TDX_AI_DATA_LIB` 指向、空闲首连 "Invalid server response" 重试包装、股票池 12h 缓存)
|
||||
- `provider.py` — Provider 实现(快照昨收=LastClose/高低=Max/Min 字段映射、涨跌幅 (Now-LastClose)/LastClose 小数制、RefreshTime 北京墙钟→epoch ms、软失败)
|
||||
- `probe.py` — 候选 Key 探测的独立子进程(原生 DLL 每进程单 Key): 分阶段进度留痕定位原生层死点; 因 TDX 会话按 IP 复用(错误 Key 在活跃会话下也能拉数), 探测语义为格式+连通性而非 Key 真伪, 真伪由首次实拉暴露
|
||||
|
||||
## 路由机制(无需关心, 仅参考)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user