mirror of
https://github.com/shy3130/tick-stock-panel.git
synced 2026-11-02 02:16:13 +00:00
- 策略: 引擎只加载 data/strategies/{custom,ai,composite} 与研究模板目录,
原 25 个内置策略一次性迁移为用户自定义文件(ID 不变, 引用零迁移);
研究模板移至 app/strategy/research, 打包 spec 同步; 新装环境策略库为空
- 信号: 管线不再硬编码任何信号表达式; 涨跌停判定价成为运行时列
limit_up_price/limit_down_price(生效价∓0.005 容差), 20 个信号转为
data/user_data/custom_signals 定义(显式 column 沿用 signal_* 原列名);
依赖解析/注入顺序/当日路径 prev-join 全部定义驱动; 语义统一为历史路径
口径(顺带修正当日路径 BOLL 比较符与翘板/炸板空值两处既有偏差)
- 前端: 信号库单列表(全部可编辑), SignalPicker/监控选项/信号标签全走
定义接口; 回测页新增免责声明(模拟性质/数据源准确性不作保证/不构成
投资建议)
- 测试: 25 个策略夹具与 20 个信号种子入库 tests/fixtures, 受影响测试
全部自包含化(不依赖运行目录用户数据); 77 万行 MA 死叉新旧表达式对拍
逐行一致; 回测实跑 45 笔卖点信号出场验证矩阵链路
- 同批包含工作区既有进度: 策略结果 ext 列同日投影修复(含测试)、数据源插件、fuyao/auth/api_gateway/data_integrity 调整、README 信号库
描述与 strategy.md 导入路径补充
验证: 后端 2592 passed(空数据目录 CI 模拟 2588 passed, 4 例为模拟环境
伪影复验排除); 前端 vitest 125 passed + tsc 0 错 + vite build 通过
13 KiB
13 KiB
核心能力开放与插件化改造设计方案
状态: V1/V2 已实现(0.3.2)—— Token + scope 网关 + 限流、五个 scope 全量 Tier A、
/api/openapi.json?tier=a契约视图、设置页 Token 管理(「设置 → 开放接口」)。V3+(钩子契约、SSE 票据、模拟盘拆分)仍为设计。使用说明见 features.md → 开放接口。 遵循 CONTRIBUTING.md 的数据口径、插件化与测试矩阵要求; 扩展机制现状见 secondary-development.md。
1. 目标与非目标
目标
- 项目自身保留核心域能力(数据、策略/回测、监控推送、扩展数据存储), 并以稳定 HTTP API 对外开放, 二次开发者不修改本项目源码即可在其上构建应用。
- 外围能力扩展域化: 通过既有插件机制(数据源 plugin.yaml / 前端插槽 / 后端 custom / 扩展数据表)接入, 而不是长在核心里。
- 开放有护栏: Token + scope 授权、按 Token 限流、CORS 白名单; 读开放、写受控。
非目标
- 不做多用户/多租户(数据层全局单用户是既定取舍; 以「单用户 + 多 Token + scope」满足外部调用方隔离需求)。
- 不做前端运行时插件(remote module/微前端)与第三方代码沙箱——等真实第三方插件作者出现再立项。
- 不做热更新; 桌面版更新走「下载安装包 + 静默覆盖安装 + 重启」路径。
2. 核心域 / 扩展域边界
划线原则: 按「数据与语义的归属 + 依赖箭头方向」划分, 不按页面外观划分。核心域 = 被多个模块消费其数据/语义、且自身不依赖外围的; 扩展域 = 只消费核心接口、可整体替换或移除而不伤核心的。
2.1 核心域(保留在主程序, 代码不拆出)
| 域 | 内容 | 现有承载 |
|---|---|---|
| 数据底座 | 日K/除权/分钟/实时/财务的同步管道、TickFlow 与数据源插件路由、enriched 存储、复权与单位口径 | services/kline_sync services/financial_sync、plugins/*、DuckDB/parquet |
| 订阅锚点 | 自选与分组(监控范围、持仓提醒、看板的数据订阅范围锚点) | api/watchlist、data/watchlist |
| 策略与回测引擎 | 策略注册/运行、回测矩阵引擎、优化器、挖掘运行时、环境过滤语义(regime_filter 的 T-1 掩码)、回测候选缓存 | strategy/、backtest/*、api/strategies api/screener api/backtest |
| 环境数据生产 | regime_builder 的市场状态计算与盘后增量(回测/挖掘/因子归因/AI 四处消费同一口径) | services/regime_builder、盘后管道 |
| 监控与推送管道 | 规则引擎、SSE/语音/系统通知/Webhook/留痕五通道 | services/quote_service、api/monitor-rules api/alerts |
| 扩展数据存储 | 扩展表 CRUD、时序分区/快照、市场级表(market_level)、rows/values 查询出口 | services/ext_data ext_pull、api/ext-data |
| 认证与配置 | 访问密码(本机/内网 UI)、API Token 与 scope(本方案新增)、secrets | services/auth、api/settings |
2.2 扩展域(通过既有机制接入, 核心只暴露契约)
| 能力 | 接入机制 | 状态 |
|---|---|---|
| 第三方行情数据源 | backend/app/plugins/<name>/plugin.yaml + Provider |
✅ 已有 |
| 无代码 HTTP 数据源 | data/data_sources/*.yaml |
✅ 已有 |
| 用户自注册数据表(含市场级时序) | 扩展数据配置 + 上传/拉取/回补 | ✅ 已有(本方案补齐市场级与查询出口) |
| 自定义声明式页面 | analysis_menus 配置 + 三模板 |
✅ 已有 |
| 前端页面/导航/插槽 | frontend/src/custom/<ns>/extension.tsx |
✅ 已有(AI 助手即范例) |
| 后端路由/启动钩子/通知格式化 | backend/app/custom/<module>.py |
✅ 已有 |
| 自定义/AI/叠加策略 | data/strategies/ 目录 |
✅ 已有 |
| AI 分析、大盘复盘、概念/行业/个股/财务分析、监控中心/异动/连板/持仓提醒、模拟盘、品牌页等展示与外围业务页 | 核心数据的消费端; 二开可用扩展页面平行实现替代 UI | 页面可替换; 模拟盘拆分为官方插件的候选(见 §6 V3) |
3. 对外开放形态总览
┌─ 二次开发者的应用 ────────────────────────────────┐
│ 浏览器 SPA / 脚本 / 自建服务 │
└──────────────┬────────────────────────────────────┘
│ HTTPS + Bearer Token (scope 授权)
▼
┌─ 开放网关层(新增, 薄) ────────────────────────────┐
│ Token 认证 → scope 校验 → 限流(按 Token) → CORS │
├─ 核心 API(Tier A 稳定契约, 见 §5) ────────────────┤
│ 行情数据 / 扩展数据 / 策略与回测 / 监控事件 / 模拟盘 │
├─ 管理接口(Tier B, 永不开放给 Token 的写 scope) ────┤
│ 数据同步、扩展表 CRUD、配置、密码 │
└────────────────────────────────────────────────────┘
4. 认证、授权与护栏
4.1 Token 体系
- 存储沿用 secrets 模式:
data/user_data/tokens.json(chmod 0600):{id, name, token_hash, scopes, created_at, last_used_at, revoked}; 明文 Token 只在创建响应中出现一次(前缀tsp_+ 32 字节随机 hex)。 - 认证通道与现有单密码并行不替代: 本机/内网 UI 登录照旧;
Authorization: Bearer tsp_...是外部调用方专用第二通道。 - 中间件顺序: 访问密码门 → Token 识别(有 Bearer 头则走 Token 路径, 免密码会话)→ scope 校验 → 限流。
4.2 Scope 矩阵(最小够用, 宁少勿滥)
| Scope | 允许 | 默认签发 |
|---|---|---|
read:market |
行情/指数/标的搜索/分时/日K 读取 | ✅ 新 Token 默认 |
read:analysis |
策略列表与运行结果、回测报告与候选、市场环境、监控事件读取 | ❌ 显式勾选 |
read:ext |
扩展数据 rows/values/schema 读取 | ❌ 显式勾选 |
write:ext |
扩展表行数据程序化写入(POST /api/ext-data/{id}/ingest, 0.3.2 增) |
❌ 显式勾选 |
run:backtest |
触发回测/挖掘任务(受重活并发器约束) | ❌ 显式勾选 |
paper:trade |
模拟盘下单/撤单/建户(写操作, 最高敏感级) | ❌ 显式勾选 |
admin |
管理接口 | ❌ 永不签发给 Token, 仅 UI 会话可用 |
结构管理端点(扩展表建表/字段/上传/拉取/回补/删除、数据同步、设置)一律不进 Token scope —— 外部可读 + 三类受控写(扩展表行数据、回测任务、模拟盘); 行数据写入复用管理端同一校验与落盘路径, 表结构不可被外部改写。
4.3 限流与 CORS
- 按 Token 滑动窗口: 默认 120 req/min; 触发 429 +
Retry-After。重活端点(回测/挖掘提交)另受既有heavy_job_limiter并发约束。 - CORS:
OPEN_API_CORS_ORIGINS配置(逗号分隔白名单), 默认空 = 不放行跨域; 放行后浏览器端二开可直接调用。 - 响应头:
X-RateLimit-Remaining/X-RateLimit-Limit。
5. 核心 API 清单(Tier A 契约)
稳定性分层: Tier A = 对外承诺稳定(字段只增不改, 破坏性变更需 v2 前缀 + 一个大版本过渡期); Tier B = 内部实现细节, 随时变化, 不出现在开放文档。以 OpenAPI x-stability: stable 标注 + /openapi.json 过滤视图 ?tier=a 实现, 不搬迁路由前缀。
5.1 行情数据(read:market)
| 端点 | 说明 |
|---|---|
GET /api/kline/instruments/search |
标的搜索(代码/名称/拼音首字母, 含 ETF/指数) |
GET /api/kline/daily?symbol=&start=&end= |
日K(前复权/不复权口径参数) |
GET /api/intraday/... |
分时/多日分时 |
GET /api/index/... |
指数行情与估值截面 |
GET /api/overview/market-snapshot |
全市场当日快照(一次拉取, 二开图表直供) |
5.2 扩展数据(read:ext)
| 端点 | 说明 |
|---|---|
GET /api/ext-data/{id}/rows |
明细查询五件套: date 单日 / start_date+end_date 范围(自动行级 date 列)/ filter 等值 / sort / offset+limit; columns 裁剪 |
GET /api/ext-data/{id}/values?field= |
字段取值枚举(filter 下拉配套) |
GET /api/ext-data/schema/{id} |
表结构 |
GET /api/ext-data(列表) |
只返回 id/label/mode/market_level/字段名, 不含拉取配置等管理细节 |
市场级表(market_level)通过同一组端点消费 —— 这是「市场环境类数据发布为扩展数据」的出口。
5.3 策略与回测(read:analysis / run:backtest)
| 端点 | 说明 |
|---|---|
GET /api/strategies / GET /api/strategies/{id} |
策略清单与详情(参数定义、数据依赖) |
POST /api/screener/run |
运行策略(异步任务) |
GET /api/screener/result... |
运行结果(含扩展列) |
POST /api/backtest |
提交回测(含 regime_filter) → 任务 id |
GET /api/backtest/{job}/status / GET .../report |
任务状态 / 回测报告(指标、回合、净值序列) |
GET /api/backtest/candidates |
持久化回测候选摘要 |
GET /api/regime/states 等 |
市场环境状态序列(内置 regime 的读取出口) |
5.4 监控与事件(read:analysis)
| 端点 | 说明 |
|---|---|
GET /api/alerts |
告警/事件留痕查询 |
GET /api/events/stream(SSE) |
实时事件流(告警/成交/系统事件); Token 以 query 参数短期票据接入(SSE 无法带 header) |
| Webhook 订阅注册 | V2 再做: 按 Token 注册回调 URL + 事件类型 + 签名密钥(复用现有 custom webhook 通道能力) |
5.5 模拟盘(paper:trade)
| 端点 | 说明 |
|---|---|
GET /api/paper/accounts /overview /positions /nav /stats /compare |
账户与账务读取 |
POST /api/paper/orders DELETE /api/paper/orders/{id} |
下单/撤单(写) |
GET /api/paper/trades |
成交台账(append-only 事实源) |
5.6 系统
| 端点 | 说明 |
|---|---|
GET /api/health |
探活(无鉴权, 白名单已有) |
GET /api/auth/api-tokens(UI 会话) |
Token 管理: 列表/创建/吊销(管理页, 不属于开放面) |
GET /api/openapi.json?tier=a |
Tier A 契约视图(机器可读) |
5.7 通用约定
- 分页:
offset+limit, 响应含total; 列表端点统一items/rows字段名在契约化时逐一固定。 - 错误: FastAPI 默认
{detail}; 契约化后统一补code字段(Tier A 端点)。 - 日期: 全部
YYYY-MM-DD/ ISO 时间戳, 北京时间口径(与内部一致, 不做时区换算)。 - 金额单位: 元; 比例: 百分数数值(与各域现状一致, 契约文档逐一标注, 不强行统一)。
6. 分期路线
V1 开门(Token + 护栏 + 最小契约)— 建议立即
- ✅ Token 存储/创建/吊销 + 设置页管理 UI(「设置 → 开放接口」,
services/api_tokens.py)。 - ✅ 中间件: Bearer 识别 → scope 校验 → 限流(
services/api_gateway.py,CORS 原本已全开)。 - ✅ Tier A: 直接覆盖全部五个 scope(
api_gateway._RULES规则表)。 - ✅ 测试矩阵:
backend/tests/test_api_gateway.py(401/403/429/吊销即拒/前缀混淆防护)。
V2 契约化 + 示例仓库
- ✅ Tier A 已含策略/回测/监控事件/模拟盘;
GET /api/openapi.json?tier=a契约视图(规则表单源)。 - ✅ 示例脚本(0.3.2):
examples/open-api/四个零依赖可运行示例(行情 / 写入扩展数据 / 回测 / 事件流)+ README; 独立示例仓库待有真实用户再拆。 - ✅ SSE 短期票据落地(0.3.2):
POST /api/events/ticket换 60s 一次性票据 →GET /api/events?ticket=…(services/event_tickets.py+api/events.py, 事件源已接告警触发)。
V3 钩子契约 + 模拟盘拆分试点
- 核心提供
盘中快照钩子盘后结算钩子事件契约, 模拟盘改为通过钩子接入 → 验证「核心 + 官方插件」拆分工程可行性(当前反向 import 30 处, 先立契约再搬)。
V4 市场级过滤契约(按需)
- 引擎把 regime_filter 泛化为「date 对齐的市场级扩展表过滤」: 官方 regime 表迁移为第一个实现, 第三方择时数据集(市场级扩展表)可直接选入回测过滤。触发条件: 第一个真实的第三方择时数据集出现。
7. 风险与守住的边界
- Token 泄漏 = 面板数据泄漏: 默认只读 scope、可随时吊销、创建时明文只显一次; paper:trade 永不默认。
- 契约冻结过早: Tier A 从最小两组起步, 按二开反馈逐域升级, 未验证的端点留在 Tier B。
- 限流误伤本机 UI: Token 限流只作用于 Bearer 路径; UI 会话不受 Token 桶约束。
- 不因开放破坏内部演进: 开放面是「视图 + 网关」, 不重写内部路由; 内部 API 与开放 API 解耦, 由标注层衔接。