97 KiB
见势 · Veyra AI 量化分析产品:前后端完整设计报告
版本:V1.1 · 编写/更新日期:2026-10-04
设计基线:hengce_app_admin_prototype.html双端交互原型;App V2 采用白底、石墨黑与少量柔紫。
本次更新:统一品牌为「见势 · Veyra」,同步 App 视觉 Token、页面层级与组件规范。
面向:产品、设计、App、Web、Go 后端、量化研究、测试与运维团队。
本文是实施设计,尚未连接真实行情、模型或券商。文中容量、时延、参数与排期是规划假设,需通过实际测试确认。
目录
- 产品目标与范围
- 原型到正式产品的映射
- 技术栈与选型
- 总体架构与职责边界
- 核心业务流程与状态机
- App 前端设计
- 管理端前端设计
- Go 后端设计
- 量化策略与风险引擎
- AI 分析与模型接入
- 行情、公告与实时分析链路
- 数据库与存储设计
- API 与实时事件协议
- 异步任务、推送与一致性
- 权限、安全与商业上线边界
- 回测、模拟交易与复盘
- 部署、可观测性与容灾
- 测试与验收标准
- 开发目录与团队协作
- 分阶段实施计划
- 容量、成本与扩展路径
- 关键决策、待定项与开发起点
- 官方参考资料
1. 产品目标与范围
1.1 产品定位
见势 · Veyra 面向从空仓开始的个人投资者,以 App 为主,通过授权行情、确定性策略、AI 证据解释和持仓风险监控,帮助用户形成可执行、可追踪、可复盘的交易决策。中文名为「见势」,英文名为「Veyra」,完整品牌名统一写作「见势 · Veyra」。
产品的完整闭环为:设置偏好 → 全市场筛选 → 发现候选 → 理解证据 → 生成买入计划 → 条件触发提醒 → 用户确认实际成交 → 持仓监控 → 卖出/减仓/加仓建议 → 成交记录 → 复盘。
“收益最大化”转为工程上可验证的目标:在资金、风险、流动性和交易制度约束下,比较成本后的策略表现与风险调整后收益。产品不承诺盈利,也不能把模型表达的确定性当成真实胜率。
1.2 本报告采用的实施假设
| 项目 | 本版决定 |
|---|---|
| 首期市场 | 沪深 A 股普通股票;板块支持采用白名单,主板先上线,创业板、科创板逐步通过规则验收 |
| 用户初始状态 | 无持仓;不会强迫用户先导入股票才提供候选 |
| 投资周期 | 数天至数周为主,后续支持数周至数月 |
| 实时口径 | 盘中基于授权行情更新,分钟级策略评估;前台事件更新,后台系统推送 |
| 初期执行方式 | 用户在券商自行交易,App 记录成交;不自动下单 |
| 首期账户 | 独立模拟账户与手工真实记录账户;真实记录不代表券商核验结果 |
| 推荐发布 | 候选经策略、质量与风险检查,再进入人工审核;个性化计划另受用户适配和服务权限约束 |
| 管理端 | 独立 Web 控制台,覆盖原型的 10 个工作区 |
| 技术偏好 | Go 后端;React Native + Expo App |
| App 配色 | 白底、石墨黑、少量柔紫;不使用绿色,不采用蓝色作为品牌主色 |
| 管理端配色 | 保留暖白、炭黑与焦糖橙的现有后台主题;品牌名同步为见势 · Veyra |
实际证券交易规则按交易所、证券类别、板块和生效日期配置。原型中的“100 股整数倍”只适用于部分演示场景,不能直接复制到所有正式交易场景。
1.3 首期范围与后续范围
| 优先级 | 功能 |
|---|---|
| P0:完整闭环 | 登录、偏好、空仓首页、候选列表与证据、买入计划、条件监控、成交录入、持仓、卖出计划、提醒中心、基础复盘 |
| P0:运营支撑 | 候选审核、策略版本、真实回测任务、数据健康、模型配置、推送任务、用户状态、审计、服务开关 |
| P0:可靠性 | 行情时效检查、规则校验、权限、幂等、账本一致性、失败重试、备份恢复 |
| P1:增强体验 | 分批买卖、加仓/减仓细化、组合集中度、事件更新、多策略对照、详细归因、正式适当性流程 |
| P2:扩展 | 经授权的券商成交同步、更多市场与资产、复杂组合优化、更细行情、机构工作流 |
授权与资格具备后才能开放相应真实建议服务。研发阶段仍可完成全部流程的模拟验证。
1.4 首期暂不建设
高频交易、杠杆融资、期权、自动券商下单、用户自定义任意脚本执行、收益保证、由大模型独立决定价格与仓位,均不进入首期。
2. 原型到正式产品的映射
2.1 保留已确认的交互
| 原型页面/交互 | 正式产品实现 | 必须补齐的能力 |
|---|---|---|
| 投资偏好 | 用户偏好、资金参考、关注周期、板块选择 | 与正式风险评估、板块交易权限分开存储 |
| 空仓首页 | 市场摘要、有效候选、等待中的计划 | 无机会、休市、行情过期、服务异常等空状态 |
| 机会与股票详情 | 趋势、回撤、事件候选;逻辑/计划/资料 | 数据来源、证据定位、反证、发布时间、版本、失效时间 |
| 买入计划 | 入场区间、条件、数量上限、止损、目标、期限 | 风险与资金校验、执行可行性、计划预览与确认 |
| 成交录入 | 用户录入买卖价格、数量、成交时间、费用 | 幂等、可卖数量、分批成交、补录、纠错与审计 |
| 持仓监控 | 成本、浮盈亏、可卖数量、风险变化 | 批次账本、真实/模拟隔离、停牌与 T+1 提示 |
| 卖出建议 | 风险止损、目标分批止盈、逻辑失效、时间退出 | 建议数量与可执行数量分离,用户实际成交另记 |
| 提醒中心 | 持久化站内通知与深链 | 推送渠道状态、未读、过期、去重、补拉 |
| 管理端发布/撤回 | 服务端审核流程 | 发布事务、撤回事件、历史版本不可改写 |
| 策略编辑 | 创建新版本并激活 | 参数校验、回测证明、灰度、回滚 |
| 回测演示 | Python 执行真实任务,保存报告 | 时点数据、成本、不可成交情形、样本外验证 |
| 数据故障模拟 | 自动采集健康、故障告警与降级 | 阻断新建议,同时保留历史成交记录能力 |
| 模型连接测试 | 后端受控调用与 Schema 验证 | 密钥管理、费用、版本、超时、权限 |
| 角色切换 | 真实后台身份与权限 | MFA、服务端 RBAC、对象权限、双人复核 |
2.2 原型限制的替换原则
原型是单文件、本地共享状态的交互演示。正式产品中,App 与管理端各自独立发布,统一连接 Go API;PostgreSQL 是业务事实来源,Redis 与客户端缓存只负责加速。
原型固定资金、日期、用户、股票与预设回测结果全部替换为真实账户配置和授权数据。模拟数据必须有独立环境与标签,不能混入正式候选、报告或运营指标。原型里的“推送成功”拆成网关受理、通道交接、设备观察和用户已读,不能只用一个成功字段表示全部阶段。
3. 技术栈与选型
3.1 推荐技术栈
以下是针对本项目的工程选型,不是供应商性能排名。
| 层级 | 推荐技术 | 选型理由/边界 |
|---|---|---|
| App | React Native + Expo + TypeScript | 符合你的开发习惯,覆盖 iOS 与 Android |
| App 路由 | Expo Router | 用页面路由组织流程和推送深链 [R1] |
| 服务端状态 | TanStack Query | 查询缓存、失效更新、加载与错误状态;不代替账本事实 [R2] |
| 本地交互状态 | Zustand | 筛选、草稿、主题、当前账户;正式写操作必须等待服务端确认 |
| App 表单 | React Hook Form + Zod | 表单反馈与契约校验;服务端再次验证 |
| App UI | 自建主题组件 + react-native-svg | 延续已确认视觉,首期折线/简单 K 线使用 SVG |
| 长列表 | FlashList,性能验证后采用 | 提醒、候选和成交列表;不先引入复杂图形引擎 |
| App 凭据 | expo-secure-store | 存放刷新凭据等敏感小数据,不保存完整持仓数据库 [R3] |
| App 推送 | expo-notifications + 推送适配层 | 使用开发构建测试;国内 Android 另适配厂商/聚合推送 [R4] |
| App 构建 | Expo Development Build;EAS 或受控本地构建 | 原生推送 SDK 通过 config plugin 集成;商店包与测试包隔离 |
| 管理端 | React + TypeScript + Vite | 独立 SPA,后台不需要首期 SSR |
| 管理端 UI | Ant Design,统一覆盖主题 Token | 表格、表单、弹窗;默认蓝色和绿色状态都替换 [R5] |
| 管理端图表 | Apache ECharts | 回测净值、回撤、数据延迟;图表数值来自服务端 |
| Go HTTP | Gin + 标准库 | 清晰路由与中间件,业务不依赖 Gin Context [R6] |
| Go 数据访问 | pgx + sqlc | 显式 SQL、强类型生成、事务边界可审查 [R7] |
| Go 迁移 | goose | 版本化迁移;生产迁移独立任务执行 |
| Go 资金计算 | 定点整数/经审核的 Decimal 库 | 禁止 float64 用于账本金额、价格与费用比较 |
| 量化计算 | Python + NumPy + pandas + PyArrow | 因子、回测与批量研究;算法和数据版本化 |
| Python 内部 API | FastAPI + Pydantic | 接收受控计算任务和返回结构化结果,不直接写用户账本 |
| 业务数据库 | PostgreSQL | 账户、计划、账本、版本、审核、任务;利用行锁保证并发约束 [R8] |
| 缓存 | Redis | 快照、订阅索引、限流、短期事件提示;可重建 |
| 首期异步队列 | PostgreSQL Job 表 + Outbox | 任务状态和业务事务一起持久化;减少组件数量 |
| 文件与研究数据 | S3 兼容对象存储 + Parquet | 原始数据、时点快照、回测报告、证据文件 |
| 模型主路由 | 阿里云百炼 Qwen 固定快照 | 初始 qwen3.7-plus-2026-05-26,结构化分析与工具使用 [R9] |
| 模型备用路由 | DeepSeek API | 初始 deepseek-flash;别名对应版本可能变化,保存供应商版本信息 [R10] |
| 协议 | REST + OpenAPI;前台 WebSocket | 首期内部 HTTP JSON;高吞吐时再引入 gRPC |
| 可观测性 | OpenTelemetry + Prometheus + Grafana + 日志平台 | 统一事件、任务、模型与 API 链路 |
| 交付 | Docker + CI;本地 Compose | 首期受控容器部署,不先要求 Kubernetes |
3.2 版本与依赖策略
采用启动项目时验证过的稳定版本,而不是在文档里组合未经测试的“最新版本”。Go 选择仍获维护的稳定分支并固定补丁版本;Expo SDK、React Native、React 必须使用 Expo 官方支持的配套组合,通过 expo install 安装原生依赖。数据库选择云厂商支持的稳定大版本。[R4][R11]
交付时必须提交 go.mod/go.sum、前端锁文件、Python 锁文件、容器镜像摘要、OpenAPI 版本和模型配置版本。升级先跑契约、账本、真机推送和回测再现验证,再灰度发布。生产模型不得使用未记录变更的自动更新配置。
3.3 为什么保留 Python
Go 负责用户请求、状态机、账本、风险门禁和任务调度;Python 负责历史因子、策略研究与回测。成熟量化数值生态更适合 Python,而高并发业务与一致性更适合放在 Go。首期不要把同一条仓位规则分别写在两个语言里:共享版本化规则规格和黄金测试样本,Go 风险引擎为在线最终裁决者,Python 回测必须通过相同规则样本。
4. 总体架构与职责边界
4.1 总体拓扑
flowchart TD
App["React Native / Expo App"] --> Edge["HTTPS 入口与访问控制"]
Admin["React 管理端"] --> Edge
Edge --> API["Go API:模块化单体"]
API --> DB["PostgreSQL:业务事实与 Outbox"]
API --> Cache["Redis:缓存与订阅索引"]
API --> Storage["对象存储:证据与报告"]
DB --> Worker["Go Worker:任务、监控、推送"]
Worker --> Quant["Python:因子与回测"]
Worker --> AI["模型适配层:主模型与备用模型"]
Feed["授权行情、公告、交易日历"] --> Worker
Worker --> Push["推送网关:APNs、Expo、Android 通道"]
Worker --> DB
Worker --> Cache
API 和 Worker 可以由同一个 Go 仓库、同一个镜像构建,用不同启动命令运行。模块化单体是代码组织方式,不意味着只有一个进程。Python 独立部署以隔离 CPU/内存密集计算。图中的箭头表示依赖与主要数据流,不表示浏览器能直接访问数据库或供应商密钥。
4.2 Go 模块边界
| 模块 | 职责 | 禁止跨越的边界 |
|---|---|---|
| identity | 登录、设备、会话、管理员身份 | 不暴露其他用户账户 |
| profile | 偏好、板块声明、适当性与授权状态 | 个人偏好不冒充正式评估 |
| market | 证券主数据、行情查询、交易日历、健康 | 不将缓存时间当行情产生时间 |
| strategy | 策略版本、因子规格、运行配置 | 已发布版本不原地修改 |
| research | AI 分析、证据、候选、审核 | 模型不能直接发布建议 |
| planning | 买卖计划、条件、修订与生命周期 | 提醒不能变成实际成交 |
| risk | 数量、资金、权限、时效、可执行性 | 不允许客户端参数绕过规则 |
| portfolio | 账户、成交、持仓批次、现金流水、复盘 | 不依赖推送是否送达修改资产 |
| notification | 站内通知、推送、重试与偏好 | 不把网关受理当用户已读 |
| operations | 数据源、服务开关、模型路由、任务 | 配置变更必须授权和审计 |
| audit | 操作记录、证据快照、敏感导出 | 不允许管理员直接删改历史 |
模块通过 Application Service 调用,不在 Handler 里跨多个表拼接业务事务。统一 Unit of Work;涉及计划、账本、Outbox 的事务由调用方服务明确管理。
4.3 初期与扩展架构
首期:Go API、Go Worker、Python Quant、托管 PostgreSQL、Redis、对象存储和 Web 静态资源即可。队列放 PostgreSQL,查询缓存放 Redis。
增长后:仅按实测瓶颈拆出行情接入、实时订阅网关或通知服务。需要大规模事件回放和分区消费时引入 Kafka/Redpanda;历史行情查询与研究并发超出 PostgreSQL/Parquet 能力时评估 ClickHouse。没有数据证明之前,不先铺设完整微服务系统。
4.4 环境与数据边界
local / test / staging / production 分离数据库、对象桶、模型密钥、推送项目与包标识。生产内再区分 simulation 和 manual_real 账户。测试任务不能发送到生产设备,模拟净值不能出现在真实账户业绩汇总中。
5. 核心业务流程与状态机
5.1 空仓到持仓的主流程
flowchart TD
Scan["授权数据扫描"] --> Check["策略与风险预检查"]
Check --> Review["证据分析与人工审核"]
Review --> Candidate["已发布观察候选"]
Candidate --> Preview["个性化计划预览"]
Preview --> Plan["用户确认创建计划"]
Plan --> Trigger["条件成立:提醒用户"]
Trigger --> Fill["用户录入实际成交"]
Fill --> Position["账本更新与持仓监控"]
Position --> Exit["退出、减仓或加仓计划"]
Exit --> Fill
Position --> Recap["成本后复盘"]
Check --> NoAction["条件不足:继续观察"]
Plan --> Invalid["过期、撤回或条件失效"]
观察候选回答“值得研究什么”;买入条件回答“何时、以什么上限行动”;成交回答“用户实际做了什么”。三者采用不同对象与 API,避免将一次分析直接解释成买入指令。
5.2 候选状态机
DRAFT → PENDING_REVIEW → PUBLISHED;审核退回进入 RETURNED,重新提交时生成新修订;已发布候选可进入 WITHDRAWN 或 EXPIRED。
发布要求:关联策略允许运行、数据质量合格、分析通过结构化校验、证据可定位、反证明确、期限合法、服务能力允许发布、审核角色有权限。编辑证据或条件后,旧发布内容不再被直接覆盖,而是新建候选修订重新审核。
撤回保留历史版本,关闭新计划创建并冻结未完成买入计划的主动触发;已成交持仓仍继续监控。严重风险撤回可产生高优先级风险通知,不能自动卖掉用户持仓。
5.3 计划使用两组状态
单一“等待/触发/买入”不足以支持部分成交与失效,所以正式数据分离生命周期和触发状态。
| 字段 | 取值 | 含义 |
|---|---|---|
lifecycle |
ACTIVE / COMPLETED / CANCELLED / EXPIRED / INVALIDATED |
计划能否继续使用 |
trigger_state |
WAITING / SATISFIED / NO_LONGER_SATISFIED |
最新条件是否成立;仅 ACTIVE 时持续评估 |
filled_qty |
非负数量 | 用户记录并关联该计划的已成交数量 |
eligibility |
ELIGIBLE / BLOCKED / UNKNOWN |
当前是否具备建议所需权限与数据条件 |
execution_status |
EXECUTABLE / WAIT_T1 / SUSPENDED / NO_LIQUIDITY / UNKNOWN |
建议当前是否有可执行基础,不表示保证成交 |
页面把 ACTIVE + WAITING 显示为“等待条件”,ACTIVE + SATISFIED 显示为“条件已满足”,有部分成交时叠加“已成交 X 股”,累计达到目标后 COMPLETED。过期、撤回、暂停不会撤销历史成交。
条件曾满足后回落,改为 NO_LONGER_SATISFIED;下一次满足必须符合重新触发冷却与事件去重规则。即使历史条件成立,用户打开推送时也要重新读取当前计划,不能展示为永久有效。
5.4 手工成交、纠错与资金
模拟账户采用严格余额、数量、时间和交易规则校验;手工真实记录账户允许用户补录真实发生的历史成交,并显示“用户记录、未经券商核验”。历史成交可能偏离计划,因此超计划预算应提示偏离并保留记录,而不是把历史事实强改成建议。
模拟账户现金由初始资金和资金流水生成;真实记录账户的“资金参考”仅用于计划风险预算,不自动生成现金余额。只有用户确认完整初始现金与出入金后才展示“账本估算可用现金”;信息不完整时显示未知,阻止依赖现金余量的精确仓位建议。
补录历史交易需按时间重放受影响证券账本,检查历史余额与可卖批次。存在缺失时进入待核对状态,不静默制造负持仓。错误成交通过冲正/替代记录纠正,保留原始记录、原因与引用;不得直接修改已入账事实。
5.5 持仓监控与退出逻辑
监控范围包含价格、入场逻辑、公告变化、持仓集中度、资金风险和时间。输出 HOLD / REDUCE / EXIT / ADD / OBSERVE / NO_ACTION,同时附条件、证据和失效期限。
风险规则触发不依赖大模型完成。当天不可卖批次、停牌、跌停或流动性不足时,可给出风险告知和待执行计划,但建议数量与即时可执行数量必须分开。止损价是风险阈值,跳空、涨跌停、T+1 等情况下实际损失可能超过预算。
加仓必须建立新计划并占用风险预算,不能因股价下跌自动补仓。加仓后的整体风险、成本和集中度重新计算;减仓和分批止盈按当前可卖数量核验。
6. App 前端设计
6.1 信息架构与路由
底部主导航保留原型的:首页、机会、计划、持仓、我的。提醒中心从首页与我的进入;股票详情、计划详情、成交表单、复盘为二级页面。
apps/mobile/app/
(auth)/login.tsx
onboarding/preferences.tsx
(tabs)/index.tsx # 首页
(tabs)/opportunities.tsx
(tabs)/plans.tsx
(tabs)/portfolio.tsx
(tabs)/profile.tsx
stocks/[instrumentId].tsx
plans/[planId].tsx
fills/new.tsx
positions/[positionId].tsx
notifications/index.tsx
recap/index.tsx
settings/notifications.tsx
settings/accounts.tsx
_layout.tsx
路由参数只携带对象 ID,不携带可被伪造的价格、持仓或权限结论。对象详情从服务端加载;无权限、已撤回、已过期分别有专门状态。推送深链只能映射到白名单业务路由。
6.2 页面设计与接口依赖
| 页面 | 主要模块 | 主要操作 | 数据接口 |
|---|---|---|---|
| 偏好 | 资金参考、周期、风险偏好、板块 | 保存、跳过可选项 | GET/PATCH /me/preferences |
| 空仓首页 | 市场摘要、机会摘要、等待计划、服务提示 | 发现机会、查看计划、提醒 | GET /home |
| 有仓首页 | 账户摘要、风险提醒、当日计划 | 进入持仓、查看建议 | GET /home |
| 机会 | 关键词、策略分类、有效期 | 筛选、收藏、查看逻辑 | GET /candidates |
| 股票详情 | 行情、逻辑/计划/资料、证据、反证 | 查看证据、预览计划 | GET /instruments/{id}、GET /candidates/{id} |
| 买入预览 | 触发条件、资金上限、数量、止损、目标 | 调整目标金额、确认计划 | POST /plan-previews、POST /plans |
| 计划列表/详情 | 状态、版本、触发时间、期限 | 取消、查看变化、录入成交 | GET /plans、GET /plans/{id} |
| 成交录入 | 账户、方向、价格、数量、时间、费用 | 预检查、确认、偏离提示 | POST /fills/preview、POST /fills |
| 持仓/详情 | 总量、可卖量、成本、盈亏、风险、计划 | 预览退出、加仓、记录卖出 | GET /positions、GET /positions/{id} |
| 提醒 | 优先级、原因、状态、未读 | 已读、打开最新对象 | GET /notifications、POST /notifications/{id}/read |
| 我的/复盘 | 账户模式、偏好、通知、统计、隐私 | 切换账户、查看归因 | GET /accounts、GET /recaps |
完整 API 前缀为 /api/v1,表中省略前缀。
6.3 状态管理
TanStack Query 管服务端状态,查询 Key 必须包含 account_id 和影响结果的筛选参数。Zustand 只保存当前账户、主题、筛选与非敏感表单草稿。切换账户时中断旧请求、清空敏感缓存、重新订阅事件。
成交、发布、撤回等操作不做“资产已更新”的乐观展示。用户提交后显示处理中,收到服务端确认再失效刷新账户、持仓、计划和复盘查询。通知标为已读可乐观更新,但失败必须回滚。
前台 WebSocket 只发对象变更提示和有限快照;客户端按版本处理,再向 REST 获取完整事实。应用恢复前台后重新拉取服务状态、通知游标与当前账户快照,不能只依赖先前连接。
6.4 视觉与组件体系
App 采用清爽、简洁的视觉方向:白色页面、石墨黑文字与主按钮,柔紫只用于 AI 研究、观察状态和少量强调。减少外框和重复卡片,以字号、留白和轻分隔建立层级。
| Token | 浅色值 | 深色值 | 用途 |
|---|---|---|---|
background |
#FFFFFF |
#111114 |
页面背景 |
surface |
#FFFFFF |
#111114 |
表单、弹层与主表面 |
layer |
#F5F5F7 |
#1D1D23 |
浅灰模块与选中导航背景 |
textPrimary |
#1B1B20 |
#F5F5F7 |
主文字与行情图线 |
textSecondary |
#74747F |
#A6A6B3 |
辅助文字,独立验证对比度 |
action |
#202025 |
#EDEDF2 |
主要按钮 |
onAction |
#FFFFFF |
#19191E |
主要按钮文字 |
accent |
#6554A5 |
#BCB0F6 |
AI 标签与强调文字 |
accentSoft |
#F1EDF9 |
#2B2442 |
AI 观察模块与标签浅底 |
border |
#EAEAF0 |
#2C2C35 |
列表与模块分隔 |
priceUp / danger |
#C54655 |
#F7919D |
上涨、风险;用图标与标签区分语义 |
priceDown |
#71717C |
#BABAC5 |
下跌,同时显示负号与向下箭头 |
observe / waiting |
#6554A5 |
#BCB0F6 |
观察/等待标签;风险警告另用明确图标与文案 |
成功状态使用中性或柔紫文字配勾选图标,不引入默认绿色。禁用、上涨、下跌、已成交均不能只靠颜色识别。App 与管理端保留各自视觉 Token,避免后台焦糖橙自动影响 App。
品牌规范:页面标题与首次品牌展示使用「见势 · Veyra」;首页采用「见势」主字标加较小的「· Veyra」,原型主字标约 29px、英文约 18px;图标和头像使用 V 标识。深浅主题共享相同品牌写法,原型顶部和管理端品牌入口也同步更新。
页面层级:空仓首页先展示 AI 观察和“发现今日机会”入口,再展示市场快照、观察名单或已有计划;候选采用清晰的列表行与轻分隔。持仓页突出总资产、资金与浮盈亏数字,再展示单股风险与退出入口。详情页保持逻辑/计划/资料三个标签,表单与弹层沿用同一主题。
基础组件:Screen / AppHeader / Card / Button / StatusBadge / MoneyText / QuoteStamp / EvidenceList / RiskNotice / PlanCard / PositionCard / EmptyState / ErrorState / BottomSheet / ConfirmDialog。交互热区至少 44×44,支持系统字体放大、读屏标签、键盘避让与安全区。
6.5 图表与性能
首期使用服务端聚合好的有限时间窗口,默认不一次加载多年分钟线。分时与净值用 SVG 折线,简单 K 线分批加载;大数据量场景再基于真实设备评测升级渲染方案。图表显示数据时间、复权口径和单位。
行情展示按屏幕可见证券订阅,变更合并刷新,避免每条行情导致全屏渲染。退出页面取消无用订阅。模拟与真实账户使用明显文字标签,盈亏注明费用与现金完整性口径。
6.6 通知、离线与发布
离线可以查看带时间戳的历史快照和保存表单草稿;不得离线提交成交并伪装为入账成功,不得使用旧行情生成新买卖建议。重新联网后先同步,再确认提交。
远程推送采用 Development Build 和正式包验证,不依赖 Expo Go 完成推送验收。[R4] 海外/具备相应网络通道的设备可采用 Expo Push Service;中国大陆 Android 上线前必须评估无 Google 服务的设备,接入受控厂商/聚合推送 SDK,并测试 token 注册、冷启动、深链和隐私告知。
EAS Update 只在匹配 runtime 的范围内发布 JS/资源,原生 SDK 和权限变化需要重新出包;每次应用更新支持灰度与回滚。金融内容、隐私、模型供应商与数据服务变化还需同步更新对应政策与用户告知。
7. 管理端前端设计
7.1 管理端布局
保留原型的左侧导航、顶部环境提示、主工作区、详情抽屉/确认弹窗。常用表格支持服务端分页、条件筛选、排序和状态回显。桌面优先,移动宽度可查看和处理简单任务;复杂回测配置以桌面为主。
7.2 十个工作区
| 工作区 | 核心功能 | 重要约束 |
|---|---|---|
| 运营总览 | 待审候选、有效发布数、数据质量、任务积压、推送失败 | 明确统计时间、范围和模拟/正式环境 |
| 候选审核 | 证据、反证、策略版本、有效期、发布、退回、撤回 | 有审核意见;版本冲突拒绝;必要时双人复核 |
| 策略管理 | 策略定义、参数版本、灰度激活、暂停、回滚 | 新版不覆盖旧候选;暂停后的计划策略明确 |
| 回测研究 | 创建异步任务、取消、进度、报告与对比 | 不展示预设绩效;数据与成本可复现 |
| 数据状态 | 源延迟、缺口、证券覆盖、校验失败、切源、重算 | 切源后先核验,禁止手动“一键健康”伪造指标 |
| AI 配置 | 模型路由、Prompt 版本、超时、预算、评估、测试 | 密钥只显示引用/掩码;测试执行在后端 |
| 提醒推送 | 站内记录、通道尝试、回执、失败分类、重试 | 过期计划不得重推;全局暂停和个人偏好生效 |
| 用户管理 | 账户状态、权限、用户声明、服务授权、受控查询 | 客服最小访问,不随意查看全部持仓 |
| 审计记录 | 主体、对象、原因、前后版本、请求链路、导出 | 只读;导出审批和可追溯 |
| 系统设置 | 服务开关、限流、通知策略、角色权限 | 高影响配置双人审批与生效版本 |
7.3 交互和错误处理
发布、撤回、策略激活、全局服务暂停采用具体对象确认,显示影响数量与策略。审核者提交时携带 expected_version,其他人先修改时返回冲突,重新加载后再确认。保存草稿和发布是两个动作。
批量操作先预览影响、逐项校验,再返回每项结果;部分失败不能显示整批成功。长任务返回任务 ID,页面轮询或订阅进度,离开页面不取消服务端工作。被撤销权限后立即失效会话,不仅隐藏按钮。
7.4 Web 状态与安全
React Router 管理路由,TanStack Query 管理数据。使用 HttpOnly、Secure、SameSite Cookie 承载管理端会话,写请求增加 CSRF 防护。模型密钥不进入 JS、HTML、浏览器存储和构建环境变量。
Ant Design 的 colorPrimary / colorSuccess / colorInfo / colorError / colorWarning 统一定制,保证无绿色、无默认蓝色主题;图表也使用同一组业务颜色。[R5] 证据摘要与用户备注按文本渲染;需要富文本时通过安全白名单净化,禁止直接注入供应商 HTML。
8. Go 后端设计
8.1 分层与依赖
采用 Transport → Application → Domain → Repository/Adapter。Transport 负责解析、身份和响应;Application 组织事务;Domain 负责状态、规则与计算;Adapter 对接数据库、行情、模型和推送。
Domain 不依赖 HTTP、Gin、模型 SDK 或数据库驱动。业务错误使用稳定代码,HTTP 状态在外层映射。时间、ID 生成与规则读取通过接口注入,保证历史日期与休市测试可重复。
8.2 关键服务
| 服务 | 输入与输出 | 事务/一致性 |
|---|---|---|
| CandidateService | 分析结果、审核意见 → 候选修订与发布 | 状态变更、审计、Outbox 同事务 |
| PlanService | 候选/持仓、账户、用户参数 → 预览和正式计划 | 确认时重检版本、时效、预算并建立保留额度 |
| RiskEngine | 行情、规则、账户、计划 → 阻断项与数量 | 确定性计算,不能被模型覆盖 |
| FillService | 成交事实 → 成交、批次、现金、计划进度 | 账户行锁,完整账本事务,幂等结果 |
| MonitoringService | 行情/公告变化 → 条件变化与风险事件 | 序号检查、条件重验、去重事件 |
| AnalysisService | 证据快照 → 结构化分析 | 异步完成,版本校验后入库 |
| NotificationService | 业务事件 → 站内通知和通道任务 | 先持久化,后发送;回执独立记录 |
| RecapService | 成交、费用、估值 → 可追溯统计 | 快照可重算,明确账本完整性 |
8.3 预览与确认
买入预览生成短期 preview_id,保存规则版本、证据版本、行情时间、账户版本与计算结果。用户确认创建时,服务端再次读取最新状态;预览过期或风险改变时返回 PREVIEW_STALE,要求重新预览。不能接受客户端回传的“已通过风险”字段。
在模拟账户或已完整维护资金的记录账户中,正式计划建立预算保留;多个计划共享资金时不能各自假定拥有全部现金。预算保留只是本产品的额度管理,不表示真实券商冻结资金。未知现金账户以用户设定的总计划额度控制,并明确提示非券商余额。
8.4 幂等与并发
所有资金与状态写操作支持 Idempotency-Key。作用域为用户/账户+路由,保存请求体哈希与完整结果;相同 Key 不同请求体返回冲突。Key 是随机 ID,不包含个人信息。
账本写入时锁账户,按固定顺序锁受影响持仓批次;采用数据库约束和事务防止超卖、重复冲正、重复事件。[R8] 对前端表单编辑使用对象 version 乐观锁。服务端不能仅靠 Redis 分布式锁维护资金正确性。
8.5 开关的精确语义
| 开关/事件 | 新建议与计划 | 存量监控 | 成交记录与历史查询 |
|---|---|---|---|
| 分析服务暂停 | 阻止新分析与新建议生成 | 确定性风险监控继续,标记解释降级 | 继续 |
| 某策略暂停 | 不生成新候选、不触发该策略待买计划 | 已持仓的基础风险规则继续 | 继续 |
| 行情失效 | 阻止依赖该行情的新计划和新触发 | 显示数据未知,不生成新的价格结论 | 继续,记录事实与来源 |
| 候选撤回 | 阻止新计划,相关待买计划失效 | 继续并显示撤回原因 | 继续 |
| 通知暂停 | 站内事件仍保存,远程推送停止 | 分析与监控继续 | 继续 |
| 用户停用 | 按服务政策拒绝主动使用和推送 | 后台维护与依法留存仍执行 | 导出/更正通过受控渠道处理 |
紧急全局停止建议开关可同时阻断发布、新计划与触发,但必须与“暂停模型调用”“暂停通知”分开,避免误停账本与历史记录。
9. 量化策略与风险引擎
9.1 首期三类策略
| 策略 | 候选条件示例 | 触发条件示例 | 失效条件示例 |
|---|---|---|---|
| 趋势与突破 | 趋势、行业相对强度、流动性满足 | 收盘确认或指定分钟线确认突破并满足量能 | 跌破结构、超期、波动/风险超限 |
| 趋势回撤 | 中期趋势仍有效,回撤在预定范围 | 止跌确认、风险收益与成交条件合格 | 趋势破坏、反证出现、回撤超限 |
| 公告事件观察 | 授权公告与可验证事实支持研究 | 事件确认加量价条件;证据不足只观察 | 澄清、更正、事件落空、利好已兑现 |
这些是研究方向,不代表已验证盈利策略。每个策略必须有版本化公式、参数、数据依赖、适用市场、评估频率、时点规则与退出逻辑。首期优先日线筛选+分钟监控,控制研究与运营复杂度。
9.2 候选筛选顺序
证券白名单 → 交易与风险状态过滤 → 流动性过滤 → 策略因子计算 → 市场/行业状态 → 确定性排序 → AI 证据与反证分析 → 质量检查 → 人工审核 → 发布。
暂不采用每天必须推荐若干只的指标。数量不足时展示“当前没有符合条件的候选”。AI 不能把不合格候选通过改写措辞变成合格建议。
9.3 风险校验顺序
校验账户与服务权限、证券交易权限、交易日与证券状态、数据时效、证据与候选有效性、策略版本、价格范围、现金/计划额度、单笔风险、组合集中度、最小数量/递增单位、流动性与可卖数量。每个阻断项输出稳定代码和用户可理解的解释。
9.4 仓位计算规格
令账户风险基数为 E,单笔风险率为 r,保守入场价格为 Pe,止损阈值为 Ps,每股预估成本与滑点缓冲为 c:
单笔风险金额 R = E × r
单位计划损失 L = Pe - Ps + c
风险数量上限 Qrisk = floor(R / L),仅当 Pe > Ps 且 L > 0
资金数量上限 Qcash = floor((可分配资金 - 费用缓冲) / Pe)
最终上限 Q = 按证券规则向下取整(min(Qrisk, Qcash, Qposition, Qliquidity))
Pe 优先使用入场区间上沿计算,避免低估风险。风险基数、比例和缓冲来自确定性配置;已有活动计划的风险保留要纳入总风险。最终数量小于最低合法数量则不生成可执行买入计划。
纯示例:E=100000、r=0.005、Pe=25、Ps=24、c=0.10,风险数量上限为 454 股;若该证券买入单位为 100 股,则可降为 400 股,再与资金和流动性上限取最小值。该例只说明计算,不是交易建议,也不能保证损失限制在 500 元。
9.5 风险配置与交易规则
风险配置包含单笔风险、总开放风险、单证券/行业集中度、单日提醒频率、最大并行计划、回撤后的建议降级策略。阈值需经研究和产品审批,不把原型的演示数值当上线默认值。
交易规则包含最小买入数量、数量递增、零股卖出、价格最小变动单位、T+1/结算属性、涨跌幅与特殊期间、申报范围、交易时段、费用版本。规则按生效时间选择,并加入交易所通知、证券状态和企业行为;不依赖手机日期推断交易日。交易规则更新需要黄金样本测试与人工审核。[R12]
9.6 组合层约束
组合风险与单票风险一起检查。无法获知用户在其他券商的持仓时,明确组合统计只覆盖已录入账户;不将局部账本称为全部资产。个股建议需要提示行业重复暴露和计划之间的资金竞争。用户新增外部持仓后重新评估未完成计划。
10. AI 分析与模型接入
10.1 模型角色与路由
主模型采用已讨论的 Qwen Plus 固定快照,负责中文公告理解、证据归纳、反证查找和结构化说明。备用模型初始采用 DeepSeek Flash,负责主通道故障后的合格分析请求。官方文档确认上述接口具有结构化输出/JSON 与工具调用能力,但这不证明其具有投资预测优势,需自行评估。[R9][R10]
| 任务 | 执行者 | 调用频率 |
|---|---|---|
| 价格、收益、数量、费用、T+1 | Go 风险/账本与 Python 数值程序 | 按业务与行情频率 |
| 全市场因子扫描 | Python/Go 批量计算 | 日线收盘、盘中规定窗口 |
| 公告事实提取 | AI + 来源校验 | 新文档事件触发 |
| 候选逻辑与反证 | 主模型 | 新候选或证据实质变化 |
| 持仓变化说明 | 主模型/备用模型 | 风险事件、公告或显著变化 |
| 普通价格提醒 | 规则模板 | 条件触发,无需等待 LLM |
| 复盘总结 | 程序统计 + AI 文字说明 | 收盘后/用户请求,缓存 |
生产初始路由配置写为 provider + model_id + configuration_version。Qwen 用固定快照 ID;DeepSeek 别名可能更新,保存请求时模型名与响应可用的版本元数据,发现别名漂移必须重跑回归评估。不能声称别名永远固定在某个模型版本。
10.2 分析链路
- Worker 收到候选或文档变化事件,按证券+证据版本去重。
- 根据分析时点构造数据快照,提供行情摘要、确定性因子、公告证据、策略条件和已知反证。
- 执行受控检索;只检索发布/获取时间不晚于分析时点的授权证据。
- 模型按版本化 Prompt 与 JSON Schema 返回结构化结论。
- 服务端校验 Schema、证据 ID、引用定位、时效、数值引用与建议类别。
- 风险与质量检查再次执行,分析入库并保留输入快照引用。
- 候选进入人工审核;持仓风险说明按服务能力与审核政策分流。
AI 只读工具示例:get_quote_snapshot、get_factors、search_evidence、get_position_snapshot、get_rule_summary。工具请求必须继承用户与账户权限;不提供成交写入、发布、密钥读取或券商交易工具。
10.3 输出契约
{
"schema_version": "analysis.v1",
"instrument_id": "inst_demo_001",
"as_of": "2026-09-30T01:41:00Z",
"decision": "OBSERVE",
"summary": "策略条件尚未全部确认,继续观察。",
"evidence_refs": [
{"evidence_id": "ev_001", "locator": "page:3", "claim": "可核验的事实摘要"}
],
"counter_evidence_refs": ["ev_002"],
"missing_information": ["下一次规定周期的量价确认"],
"rule_result_refs": ["risk_eval_001"],
"valid_until": "2026-09-30T02:00:00Z"
}
模型不返回可直接落账的金额、仓位和成交概率。需要展示价格与数量时,API 把程序算出的 plan_preview 与 AI 文字组合;引用数值必须精确匹配快照。valid_until 的模型提议也受服务端上限和证据期限限制。
不展示模型自报“90% 胜率”。如未来需要概率,只能使用明确时间目标、经过样本外检验与校准的量化模型,显示样本数、区间、定义与失效条件。LLM 的“信息完整度”可做质量维度,但不能称为盈利概率。
10.4 检索与证据
首期采用 PostgreSQL 结构化筛选与全文检索,证据以证券、事件类型、发布时间、可用时间和内容哈希建立索引。先限定证券与时点,再检索相关段落;必要时后续引入 pgvector 混合检索,不先建设独立向量数据库。
每段证据保存原始来源、文档版本、页码/段落、发布时点、系统首次可用时点、内容哈希与授权状态。公告更正建立新版本并关联旧版本;反证被删除或更正时触发重新分析。历史回测必须使用当时实际可得版本。
10.5 超时、降级与费用
初始规划:单次供应商请求超时 15 秒,最多一次受控备用调用,分析任务端到端预算 35 秒;这些是项目配置,不是供应商 SLA。后台长文提取可使用独立较长任务队列,不阻塞用户操作。
主模型超时、限流或服务错误时,备用通道必须通过同样 Schema、证据和质量校验。不能用备用结果绕过审核。连续失败后熔断:价格规则提醒继续,AI 解释显示“暂不可用”;新建依赖 AI 的建议暂停,不复用过期解释。
调用预算按任务类型设输入/输出 token 上限、每证券事件频率、每日团队额度与租户额度。相同证据、Prompt、模型和策略版本的公共分析可复用;用户账户个性化结果不能跨用户缓存。价格依赖官方当时计费规则,不在代码中硬编码永久单价。[R9][R10]
10.6 AI 质量与攻击防护
建立至少覆盖公告、更正、停牌、数据缺失、跳空、相反证据与提示注入的评估集。离线评估 Schema 通过率、事实引用准确性、过期证据率、数值一致性、缺失信息识别、拒绝越权能力、时延和成本;上线前针对风险事实错误设阻断门槛。
公告与新闻视为不可信数据,不当成系统指令。禁止读取文档里的外部命令、执行脚本或自动访问任意 URL。模型工具使用固定 allowlist、最小权限和参数校验;模型生成的 Markdown/链接同样需要安全渲染。
11. 行情、公告与实时分析链路
11.1 数据源设计
| 数据类型 | 数据内容 | 首期实现 |
|---|---|---|
| 证券主数据 | 代码、交易所、板块、上市状态、名称历史 | 每日同步,盘中接收状态变化 |
| 行情 | 授权快照、分钟 OHLCV、交易状态、序号 | 接入适配层统一格式;日线归档 |
| 公告与财务 | 原文、发布日期、首次可用时间、更正版本 | 受控采集、解析、去重、证据索引 |
| 交易日历 | 交易日、时段、临时调整 | 版本化同步,休市前核验 |
| 规则与费用 | 板块、证券类型、价格/数量、费用 | 人工批准版本,按时点应用 |
| 企业行为 | 分红、拆并股、配股、退市等 | 持仓与行情口径独立处理 |
行情合作需要明确 App 展示、服务端非展示分析、缓存留存、派生指标与再分发的授权范围。上证信息官方提供行情与相关服务信息,实际可用字段、时延和许可按采购合同核验;本报告不假设购买一种行情即可任意使用全部场景。[R13]
11.2 标准行情契约
统一包含 instrument_id / exchange / vendor / feed_session_id / sequence / event_time / received_at / bid_ask_or_last / volume / trading_status / quality_state / adjustment_mode。
以供应商行情产生时间判断时效,以 received_at - event_time 观察接入延迟。供应商序号只在其 session/分区内比较,不跨源强行排序。全系统时间统一 UTC 存储,业务显示 Asia/Shanghai;交易日另外保存 trade_date。
交易量累计快照差分不能跨 session 或交易日。分钟线区分未完成与完成:使用完整分钟条件的策略必须等 bar close,不能在 bar 中途用最终最高/最低/量造成前视偏差。
11.3 实时监控
flowchart TD
Feed["行情与文档事件"] --> Validate["序号、时效与质量检查"]
Validate --> Store["持久化批次与最新快照"]
Store --> Monitor["证券索引查找活动计划/持仓"]
Monitor --> Rule["条件与风险评估"]
Rule --> Change["事务保存状态与事件"]
Change --> Notice["站内通知与前台更新"]
Change --> AI["必要时异步解释"]
Notice --> Push["检查有效期后发送远程推送"]
Validate --> Bad["异常数据隔离与服务降级"]
维护 instrument_id → 活动计划/持仓订阅 反向索引,只评估受影响对象。公共因子按证券和策略版本计算一次,再应用用户资金与风险约束。全市场扫描可以分批完成,不能对每个用户重新扫全市场。
11.4 时效门槛与故障
按数据源合同和策略周期配置 freshness budget:快照、分钟线、公告、日历各自不同,不设一个统一 5 秒阈值。App 显示行情时间和质量状态,报价异常时禁用依赖该数据的新计划确认。
断流处理:监测心跳与时间;暂停相关价格触发;记录缺口;通知运营;切到有授权且口径兼容的备用源;补齐数据并通过校验后恢复。补齐旧行情只能用于历史重算,不能向用户重新发送“刚触发”的陈旧交易提示。
恢复时重建 Redis 索引与快照,并从持久化高水位读取。系统无法保证观察到断流期间每个瞬时触发点,因此保留监控缺口,复盘中说明数据覆盖;不可通过插值伪造当时提醒。
11.5 时延目标
首期目标以“系统收到合格数据”作为起点:确定性条件评估至站内事件落库 P95 ≤ 3 秒;前台连接正常时事件可见 P95 ≤ 5 秒;普通 API P95 ≤ 300 毫秒;AI 任务按第 10.5 节预算独立统计。分钟策略本身可能在分钟结束后评估,真实端到端时延还包含源数据延迟和移动网络。
系统推送无法承诺秒级必达,后台 App 也不能持续运行实时行情连接。[R14] 此目标只适用于通过容量测试的规定负载,不对所有用户网络和供应商服务做保证。
12. 数据库与存储设计
12.1 数据统一规范
ID 使用 UUID,外部展示可增加人类可读编号。时间使用 timestamptz;交易日使用 date;数量使用 bigint(首期整股),未来非整股资产扩展独立规格;价格 numeric(20,6),金额 numeric(24,6),金额结算按规则舍入。API 所有金额、价格、数量以十进制字符串传输,避免 JS 精度问题。
核心业务字段正规化;策略参数、规则扩展和供应商元数据用 JSONB,但配 Schema 验证与版本。不得把全部业务事实塞到一个无约束 JSON 文档。
12.2 核心实体与关系
erDiagram
USER ||--o{ ACCOUNT : owns
ACCOUNT ||--o{ PLAN : has
CANDIDATE ||--o{ PLAN : informs
STRATEGY_VERSION ||--o{ CANDIDATE : generates
ACCOUNT ||--o{ FILL : records
PLAN o|--o{ FILL : links
FILL ||--o{ POSITION_LOT : creates
POSITION_LOT ||--o{ SELL_ALLOCATION : consumed_by
FILL ||--o{ SELL_ALLOCATION : allocates
ACCOUNT ||--o{ CASH_ENTRY : posts
ANALYSIS ||--o{ CANDIDATE : supports
ANALYSIS ||--o{ ANALYSIS_EVIDENCE : cites
EVIDENCE ||--o{ ANALYSIS_EVIDENCE : referenced_by
卖出成交通过 sell_allocations 分配到买入批次。持仓汇总是可重建投影,不是唯一事实表。历史更正会重建相关投影,不能靠覆盖一个总数量字段解决所有问题。
12.3 用户、账户与权限表
| 表 | 主要字段 | 约束与索引 |
|---|---|---|
users |
id、phone_hash、encrypted_phone、status、created_at | 登录标识唯一;敏感原文加密 |
user_preferences |
user_id、reference_capital、cycle、risk_preference、boards、version | user_id 唯一;只是用户偏好 |
service_entitlements |
user_id、capability、scope、status、valid_from/to、basis_ref | 生效范围与证据;过期自动失效 |
suitability_records |
user_id、assessment_version、result、assessed_at、valid_to、consent_ref | 与简单偏好分离 |
accounts |
id、user_id、mode、currency、ledger_status、version | 索引 user_id;mode 限定账户类别 |
account_settings |
account_id、risk_basis、plan_budget_limit、risk_policy_version | 账户唯一;配置修订可追溯 |
user_consents |
user_id、document_type、document_version、accepted_at、channel、revoked_at | 协议/授权版本可追溯;撤回按政策影响能力 |
sessions |
id、user_id、token_hash、device_id、expires_at、revoked_at | 刷新凭据只存哈希 |
devices |
id、user_id、platform、push_provider、encrypted_token、status | 用户/设备唯一;token 轮换 |
admin_roles / admin_role_bindings |
role、permission、admin_user、scope、valid_to | 权限变更审计与会话失效 |
12.4 证券、研究、候选与规则表
| 表 | 主要字段 | 约束与索引 |
|---|---|---|
instruments |
id、exchange、code、asset_type、board、status | exchange+code+有效期间,处理代码复用 |
instrument_events |
instrument_id、event_type、effective_at、source_ref | 包含停复牌与企业行为 |
trading_calendars |
exchange、trade_date、sessions、calendar_version | exchange+trade_date+版本 |
trading_rule_versions |
id、scope、effective_from/to、schema_version、rules、source | 同范围生效区间不得重叠 |
fee_rule_versions |
id、scope、effective_from/to、rates、rounding、source | 按方向、证券类型与时间应用 |
strategies |
id、code、name、status | code 唯一 |
strategy_versions |
id、strategy_id、version、parameters、code_digest、data_spec、status | strategy_id+version 唯一,不覆盖 |
strategy_deployments |
strategy_id、version_id、cohort、status、effective_at | 激活与灰度可回滚 |
evidence_documents |
id、instrument_id、source、published_at、available_at、content_hash、storage_uri、supersedes_id | 来源+内容哈希去重;时点索引 |
evidence_chunks |
id、document_id、locator、text、search_vector | 文档+定位索引;全文索引 |
analysis_runs |
id、as_of、input_hash、model_config_id、prompt_version、schema_version、status、result、cost | 输入/模型/Prompt 版本去重 |
analysis_evidence_refs |
analysis_id、chunk_id、claim_type、quoted_locator | 联合唯一;反证和正证区分 |
candidate_revisions |
id、candidate_key、revision、instrument_id、strategy_version_id、analysis_id、status、valid_until、version | key+revision 唯一;状态+期限索引 |
candidate_reviews |
revision_id、reviewer_id、decision、reason、reviewed_at、input_version | 一次审核事实不可改写 |
12.5 计划、账本与通知表
| 表 | 主要字段 | 约束与索引 |
|---|---|---|
plan_previews |
id、account_id、candidate_revision_id/position_ref、input_versions、result、expires_at | 短期保留;用户/账户权限 |
plans |
id、account_id、instrument_id、side、intent、source_revision_id、lifecycle、trigger_state、target_qty、filled_qty、valid_until、version | 数量非负;account+状态+期限索引 |
plan_revisions |
plan_id、revision、conditions、entry_range、stop、targets、risk_snapshot、rule_version_id | 修订不可覆盖,保留用户确认版本 |
budget_reservations |
account_id、plan_id、cash_amount、risk_amount、status | 活动计划唯一;成交按量释放保留 |
risk_evaluations |
account_id、plan_id、as_of、rule_version、input_refs、blocks、result | 分析与计划引用同一快照 |
fills |
id、account_id、instrument_id、plan_id 可空、side、price、qty、fees、trade_at、trade_date、source、reversal_of、status | 冲正目标唯一;qty > 0;account+时间索引 |
position_lots |
id、account_id、instrument_id、buy_fill_id、initial_qty、remaining_qty、sellable_from_trade_date、cost_amount | remaining 非负且 ≤ initial;账户/证券索引 |
sell_allocations |
sell_fill_id、lot_id、qty、allocated_cost | 成交+批次唯一;总分配量等于卖出量 |
corporate_actions |
instrument_id、type、announcement_ref、ex_date、record_date、pay_date、version | 来源与生效时间;按账户持仓资格处理 |
lot_adjustments |
lot_id、corporate_action_id/correction_id、qty_delta、cost_delta、effective_at | 企业行为与重放保留调整事实,不改写原始买入成交 |
cash_entries |
id、account_id、fill_id、type、amount、effective_at、reversal_of | 资金流水不可删改;与成交事务一致 |
position_snapshots |
account_id、instrument_id、qty、sellable_qty、cost、as_of、ledger_version | 账户+证券唯一;可从账本重建 |
notifications |
id、user_id、account_id、event_id、kind、priority、object_ref、expires_at、read_at | user+event+kind 去重;用户/时间游标 |
notification_deliveries |
notification_id、device_id、provider、status、attempt、ticket_id、receipt_state、last_error | 每设备每尝试独立保存 |
notification_preferences |
user_id、kind、push_enabled、quiet_hours、quota_policy | 站内与远程通道分开 |
真实记录账户中,现金或历史账本不完整时 ledger_status=INCOMPLETE。不能输出基于完整资金账本的精确可用现金和总收益率;已有股票数量与成本也标明核对状态。
企业行为采用事件入账:现金分红形成资金流水与应收/支付状态,拆并股等形成批次数量和成本调整;复权行情只用于明确口径的研究与图表,不能替代资产调整。系统数据不完整时提示人工核对,保留原始来源和调整版本。
12.6 任务、审计与行情存储
| 表/存储 | 主要字段/内容 | 用途 |
|---|---|---|
jobs |
kind、payload_ref、status、priority、attempt、run_after、lease_until、leased_by、result_ref | 持久化任务与抢占租约 |
outbox_events |
id、event_type、aggregate_id、aggregate_version、payload、created_at、dispatched_at | 与业务事务同写 |
consumer_inbox |
consumer、event_id、processed_at | 消费幂等,联合唯一 |
idempotency_records |
principal、scope、key、request_hash、status、response、expires_at | 写接口重放 |
audit_events |
actor、role、object、action、reason、before/after_ref、trace_id、occurred_at | 后台变更与敏感访问留痕 |
backtest_runs |
strategy_version、dataset_manifest、period、cost_rule、execution_spec、seed、code_digest、status、report_uri | 可再现研究 |
quote_ingest_batches |
feed、session、sequence_range、event_range、manifest_uri、quality | 行情接入和缺口追踪 |
bars_daily / bars_minute |
instrument、interval、bar_start、OHLCV、source、revision、available_at | 按日期分区;完成状态与时点明确 |
| 对象存储 | 原始行情分片、公告原文、Parquet、回测结果、证据快照 | 校验和、访问权限、生命周期策略 |
首期只将需要在线查询的时间窗口保存在 PostgreSQL;长期高频行情放 Parquet 与对象存储,按时间和证券分区。归档/缓存删除不能违反行情合同和记录留存要求。
12.7 账本关键事务示例
BEGIN
校验幂等记录与请求哈希
SELECT account FOR UPDATE
按交易时间、证券规则与账本完整性校验成交
买入:写 fill、position lot、费用与现金流水
卖出:锁可卖 lots,写 fill、sell allocations、现金流水
更新 position 投影与 account.version
关联计划时更新 filled_qty、释放相应保留额度
写 audit、outbox、幂等响应
COMMIT
若只是录入已经发生的实际成交,当前候选撤回、行情断流或分析服务暂停不应阻止记录事实;历史交易规则仍按成交时点核验。计划偏离记录在独立字段中,不擅自改变成交价格、数量或时间。
13. API 与实时事件协议
13.1 通用约定
公网 REST 前缀 /api/v1,管理端 /api/admin/v1,内部量化 /internal/v1。Go 服务维护 OpenAPI 源,自动生成 TypeScript 客户端类型。JSON 使用 snake_case,所有金额/价格/数量为字符串,时间为带时区 ISO 8601。
列表采用 cursor / limit;排序稳定使用时间+ID。需要精确跳页的管理报表可使用受限 offset,行情和提醒不用无限 offset。筛选参数设白名单,默认和最大 limit 明确。
成功响应统一:
{
"data": {"id": "plan_001", "version": 3},
"meta": {
"request_id": "req_001",
"server_time": "2026-09-30T01:41:02Z",
"as_of": "2026-09-30T01:41:00Z"
}
}
错误响应统一:
{
"error": {
"code": "DATA_STALE",
"message": "行情已超过本策略允许的时效,请等待数据恢复。",
"retryable": true,
"details": {"source": "quote_feed", "as_of": "2026-09-30T01:30:00Z"}
},
"meta": {"request_id": "req_002"}
}
401 表示身份失效,403 表示权限不足,404 避免泄露越权对象,409 表示版本/幂等/状态冲突,422 表示业务规则阻断,429 表示限流,503 表示依赖服务暂不可用。前端依据错误代码决定重试或引导,不能解析中文文案判断。
13.2 App API 清单
| 方法与路径 | 用途 | 主要输入/输出 |
|---|---|---|
POST /auth/otp/request |
获取登录验证码 | 限流、防滥用;不暴露账号是否存在 |
POST /auth/otp/verify |
登录 | 会话与短期访问凭据 |
POST /auth/refresh |
轮换刷新凭据 | 旧凭据单次使用、重用检测 |
POST /auth/logout |
撤销会话 | 设备与会话 |
GET /me |
用户与服务权限 | 状态、可用能力,不返回后台权限 |
GET/PATCH /me/preferences |
偏好读写 | expected_version |
GET /service-status |
数据与建议能力 | 降级原因、恢复状态 |
GET/POST /accounts |
账户列表/创建 | simulation/manual_real、资金初始化规则 |
GET /accounts/{id}/summary |
账户汇总 | 现金完整性、净值、风险 |
GET/PATCH /accounts/{id}/settings |
账户风险与计划额度 | 版本、变更影响;收紧额度时重新评估活动计划 |
POST /accounts/{id}/cash-entries |
模拟或手工出入金 | 金额、类型、有效时间;幂等 |
GET /home?account_id= |
首页聚合 | 空仓/有仓摘要、提醒、候选 |
GET /instruments |
搜索证券 | 代码、名称、允许市场 |
GET /instruments/{id} |
证券详情 | 主数据、行情和规则摘要 |
GET /instruments/{id}/bars |
图表 | interval、时间范围、复权口径 |
GET /candidates |
有效候选 | strategy、account_id、游标 |
GET /candidates/{id} |
候选修订详情 | 证据、反证、状态、版本 |
POST/DELETE /watchlist/{instrument_id} |
关注/取消关注 | 关注不等于持仓 |
GET /watchlist |
关注列表 | 游标、行情时间、有效候选摘要 |
POST /plan-previews |
买/卖/加/减仓预览 | account、candidate/position、intent、目标金额 |
POST /plans |
确认计划 | preview_id、expected_versions;幂等 |
GET /plans、GET /plans/{id} |
计划列表/详情 | 生命周期、触发状态、有效期 |
POST /plans/{id}/cancel |
用户取消计划 | 版本、原因;释放保留 |
POST /plans/{id}/revision-previews |
修改计划预览 | 必须重新风控、确认生成新修订 |
POST /plans/{id}/revisions |
确认计划修订 | 旧版本不得覆盖 |
POST /fills/preview |
成交录入预检查 | 账户、价格、数量、时间、费用 |
POST /fills |
确认成交事实 | 幂等;可不关联计划 |
GET /fills |
成交记录 | 账户、日期、证券 |
POST /fills/{id}/corrections |
冲正并提交替代 | 原因、replacement;账本重放任务 |
GET /tasks/{id} |
用户受控异步任务状态 | 仅本人纠错/导出任务,结果不泄露内部 payload |
GET /positions、GET /positions/{id} |
持仓与批次 | 总量/可卖量/成本/核对状态 |
GET /notifications |
提醒补拉 | cursor、未读过滤 |
POST /notifications/{id}/read |
标为已读 | 与通道回执不同 |
GET/PATCH /me/notification-preferences |
通知偏好 | 按类型、时段、通道 |
PUT /devices/{id}/push-token |
注册/轮换设备 token | provider、token、权限状态 |
GET /recaps |
复盘与统计 | 账户、日期范围、口径版本 |
POST /exports、GET /exports/{id} |
用户数据导出 | 受控异步下载,审计 |
POST /me/deletion-requests |
账户注销申请 | 会话撤销与留存政策流程 |
此表路径均位于 /api/v1。纠错接口可返回 202 与重放任务 ID;重放期间对应账户为 RECONCILING,暂停依赖旧账本的新计划和成交提交,避免并行污染。
13.3 管理端 API 清单
| 方法与路径 | 用途 | 权限要点 |
|---|---|---|
GET /overview |
总览 | 只读运营数据 |
GET /candidates、GET /candidates/{id} |
候选队列与详情 | 范围控制 |
POST /candidates/{id}/publish |
审核发布 | reason、expected_version、审核角色 |
POST /candidates/{id}/return |
退回 | 必填原因 |
POST /candidates/{id}/withdraw |
撤回 | 影响预览、版本与原因 |
GET /strategies |
策略列表 | 研究/运营 |
POST /strategies/{id}/versions |
新建参数版本 | Schema、代码摘要与验证 |
POST /strategies/{id}/activate |
激活/灰度 | 回测与审批记录 |
POST /strategies/{id}/pause |
暂停 | 范围、原因、生效事件 |
POST/GET /backtests |
创建/查询研究任务 | 算力配额与数据权限 |
GET /backtests/{id} |
进度/报告 | 清晰标记历史回测 |
POST /backtests/{id}/cancel |
请求取消 | 已完成结果不可改写 |
GET /data-sources |
质量状态 | 实测状态,不允许客户端赋值 |
POST /data-sources/{id}/switch-preview |
切源预览 | 授权、覆盖与口径检查 |
POST /data-sources/{id}/switch |
切源 | 审批、生效配置 |
GET /model-configs |
模型配置与指标 | 不返回密钥原文 |
POST /model-configs |
新建路由版本 | secret_ref、模型与预算 |
POST /model-configs/{id}/test |
后端连通/Schema 测试 | 限额,非前端 API 直连 |
POST /model-configs/{id}/activate |
激活模型配置 | 回归评估与审批 |
GET /notification-tasks |
推送任务与尝试 | 站内/通道状态分开 |
POST /notification-tasks/{id}/retry |
安全重试 | 重检有效期、权限、去重 |
POST /notices |
发布运营通知 | 模板、对象、范围、审核 |
GET /users、GET /users/{id} |
用户管理 | 脱敏、最小字段、访问审计 |
POST /users/{id}/status |
启用/停用 | 原因与权限 |
GET /audit-events |
审计查询 | 只读,受控导出 |
GET /settings |
配置 | 权限范围 |
POST /settings/change-previews |
配置影响预览 | 不直接生效 |
POST /settings/changes |
提交/批准配置变更 | 双人审批、版本与生效时间 |
GET /roles、GET /role-bindings |
权限配置查询 | 专门身份管理权限 |
POST /role-binding-changes |
申请/批准角色变更 | 双人分离、范围、到期时间与会话失效 |
路径均位于 /api/admin/v1。原型的“模拟触发”只能存在于非生产测试工具,生产管理 API 不提供直接篡改真实价格条件的接口。
13.4 计划确认请求示例
POST /api/v1/plans
Authorization: Bearer <short-lived-token>
Idempotency-Key: 28b8d02b-e678-4cba-8500-1e33086f728d
Content-Type: application/json
{
"account_id": "acc_001",
"preview_id": "preview_001",
"expected_account_version": 12,
"expected_candidate_version": 4,
"accepted_plan_revision": 1
}
客户端不传最终风险批准结果。服务端返回正式计划、权威数值、账户新版本和明确状态。
13.5 WebSocket 协议
App 使用短期会话票据完成 WSS 鉴权,票据不放长期可记录的 URL。前端只订阅允许访问的账户和证券;服务端再次检验范围。每连接设置订阅数、速率和缓冲上限,慢客户端允许丢弃行情中间更新,但不能丢失持久化业务事实。
{
"event_id": "evt_001",
"type": "plan.trigger_changed",
"schema_version": 1,
"account_id": "acc_001",
"aggregate_id": "plan_001",
"aggregate_version": 5,
"cursor": "opaque-server-cursor",
"occurred_at": "2026-09-30T01:41:02Z",
"data": {
"lifecycle": "ACTIVE",
"trigger_state": "SATISFIED",
"as_of": "2026-09-30T01:41:00Z"
}
}
事件类型包括 candidate.published / candidate.withdrawn / plan.trigger_changed / plan.invalidated / position.changed / notification.created / service.degraded / service.recovered。模型完成也可发送 analysis.completed,但用户只能读取有权限的结果。
客户端按 event_id 去重、按对象版本忽略旧更新。短期在线事件采用 Redis Stream/同等短期分发机制可重建;持久化通知通过 REST 游标补拉。重连游标过期时返回 RESYNC_REQUIRED,客户端拉最新快照,不能保证无限期回放。
13.6 Python 内部协议
POST /internal/v1/factor-jobs、POST /internal/v1/backtest-jobs 接收 job_id、strategy_version_id、dataset_manifest、as_of/period、execution_spec、code_digest,立即返回受理结果。GET /internal/v1/jobs/{id} 返回进度与结果 URI,POST .../cancel 请求协作取消。
job_id 幂等;任务重复投递不重复运行同一逻辑。Go Worker 通过内部身份和网络策略访问,Python 无公网入口,也不允许客户端传入任意 SQL、Shell、Python 代码或对象存储路径。
14. 异步任务、推送与一致性
14.1 任务与 Outbox
首期队列基于 PostgreSQL:业务事务写入状态、Outbox 与必要任务;Dispatcher 将事件转为消费任务/在线更新,成功后记派发进度。Worker 使用 FOR UPDATE SKIP LOCKED 短事务领取任务并建立租约,不在调用模型或执行回测的几十秒期间持有数据库行锁。[R8]
任务状态为 QUEUED / RUNNING / SUCCEEDED / RETRY_WAIT / FAILED / CANCEL_REQUESTED / CANCELLED。长任务续租;租约过期可被重新领取;消费者使用 consumer + event_id 或业务任务 Key 幂等。目标为至少一次执行与业务效果幂等,不宣传跨数据库、供应商和设备的全局 exactly-once。
失败采用指数退避和抖动;初始建议 3 次自动重试,永久性权限错误、Schema 不合格和过期任务直接终止。超过次数进入失败队列,由运营分类处理。模型自动重试另受第 10.5 节供应商调用预算约束,不能每次 Job 重试都无限消耗 token。
14.2 事件顺序与竞争
发布、撤回、触发和成交都保存对象版本。发送买入提醒前再次检查候选状态、策略部署、计划期限、用户权限、行情时效与通知偏好。
如果候选先撤回、触发任务后到,旧版本任务必须终止;如果提醒已经发出,再撤回时发送最新状态事件,并在用户打开旧提醒时展示“已失效”。系统无法收回所有手机上已显示的通知,所以通知正文附时间并引导查看当前计划。
用户成交与计划到期竞争时,先按成交事实入账,再按关联和时点处理计划进度;计划到期不使历史真实成交无效。两笔并发卖出同一批次时,账户/批次锁和数量约束只允许合法总量入账。
14.3 提醒持久化与通道状态
先保存站内通知,再创建远程推送任务。用户关闭远程通知不会删除站内风险事件。原型里仅成功推送才出现在提醒中心的行为在正式产品中替换为这一规则。
| 状态 | 含义 | 可以展示的文案 |
|---|---|---|
PENDING |
等待发送 | 待发送 |
SUPPRESSED |
偏好、静默、额度、暂停或无可用设备 | 远程推送未发送;展示原因 |
GATEWAY_ACCEPTED |
推送网关接受请求 | 网关已受理 |
PROVIDER_ACCEPTED |
下游系统接受/交接成功 | 通道已接收 |
DEVICE_OBSERVED |
App 主动上报看到了该事件 | 设备已接收;不表示用户阅读 |
READ |
用户在 App 标为已读或打开内容 | 已读 |
FAILED |
已知发送失败 | 失败与原因 |
EXPIRED |
失去提醒价值 | 已过期,不重推 |
不同供应商回执能力不同,缺少设备层证据时保留未知。Expo Receipt 表示与底层推送服务交接情况,不能证明设备收到或用户看到。[R14] 数据库分别记录站内已读和每设备尝试,不用一个 status 强行线性覆盖全部维度。
14.4 去重、频率与优先级
去重 Key 为用户+账户+对象+条件版本+触发周期。价格围绕阈值来回波动时采用冷却、持续确认或迟滞机制,参数由策略定义。
通知分为风险、计划条件、证据变化和运营四类。运营与普通机会采用日额度和静默时段;高优先级风险采用独立策略,但必须尊重用户系统通知权限,不擅自绕过。日额度按交易日与 Asia/Shanghai 时区计算,数据库原子检查,Redis 只做加速。管理端显示被抑制原因而不是伪报失败。
重试时使用剩余有效期设置 TTL,失效后不发送。批量提醒使用摘要与合并规则,避免一次全市场变化产生通知风暴。
15. 权限、安全与商业上线边界
15.1 管理权限矩阵
| 操作 | 超级管理员 | 审核员 | 量化研究员 | 运营/客服 | 只读审计员 |
|---|---|---|---|---|---|
| 总览与服务状态 | ✓ | ✓ | ✓ | ✓ | ✓ |
| 查看研究证据 | ✓ | ✓ | ✓ | 限范围 | ✓ |
| 审核/发布/退回 | 按审核授权 | ✓ | — | — | — |
| 撤回候选 | 按审核授权 | ✓ | 提交申请 | — | — |
| 策略版本/回测 | ✓ | 只读 | ✓ | — | 只读 |
| 策略激活/全局配置 | 发起/批准分离 | — | 发起申请 | — | — |
| 通知任务处理 | ✓ | 只读 | — | 按范围 | 只读 |
| 用户支持查询 | 按范围 | — | — | 脱敏最小范围 | 按审计授权 |
| 审计查询/导出 | 查询;导出受控 | 自己相关 | 自己相关 | 自己相关 | 查询;导出受控 |
| 密钥轮换/角色授权 | 专门安全权限 | — | — | — | — |
超级管理员不是自动拥有投资建议审核资格。后台身份权限和业务执业授权是两层独立条件。高影响配置实行发起人与批准人不同;首期无法配备双人时,只允许非生产完整演示,不应把“管理员自审”当成正式双人流程。
15.2 应用与接口安全
App 使用短期访问凭据和轮换刷新凭据;刷新凭据安全存储,服务端保存哈希、撤销和重用检测。管理端使用 MFA 与会话 Cookie,限制登录来源并审计敏感访问。接口按对象核验 user/account 所有权,测试跨账户 ID 篡改与批量导出越权。
所有外部连接 TLS,内部网络最小开放;数据库、对象桶、缓存与 Python 服务不暴露公网。模型/行情/推送密钥放 Secret Manager,运行时注入,仅受控后端可读。日志不得记录 OTP、访问凭据、密钥、完整手机号、完整供应商输入或用户资产原文。
模型 Base URL、数据回调 URL 和文件下载只允许固定白名单,防止 SSRF。文件解析设大小、格式、页数与执行时长限制;异步容器以低权限运行,禁用任意外部命令和未受控网络访问。
15.3 用户隐私与数据留存
手机号、设备推送 token 和敏感资产信息按需求加密或脱敏;模型公共分析不含用户身份。个性化模型输入原则上只发送必要风险摘要,不能默认把完整交易历史与手机号发给供应商。
数据目录必须标注用途、授权、存放地区、访问角色、保留期限与删除方式。供应商调用区域、数据处理条款和跨境安排需在采购时核验,不因“国内品牌”自动判定所有处理都在境内。
注销撤销登录与设备 token,停止服务;需依法或依合同保留的业务记录转入受限留存范围,其他数据按政策删除。留存年限由适用业务、法律和合同确定,本文不把一个固定期限套到所有表。
15.4 真实建议服务的上线门禁
证监会官方资料将具体证券分析、价格预测、品种选择及买卖时机建议纳入相关“荐股软件”监管说明,商业提供此类能力不能仅靠“AI 生成”“仅供参考”规避相应要求。[R15] 这不是完整法律意见;正式经营模式和当时适用要求须由专业合规团队核验。
工程上实现服务能力门禁:
| 能力 | 研发/模拟阶段 | 真实商业阶段 |
|---|---|---|
| 模拟候选与模拟计划 | 明确标记,可完整验证 | 与真实服务隔离 |
| 真实行情展示/统计 | 按数据授权及功能边界开放 | 授权范围内开放 |
| 具体股票个性化买卖建议 | 不向无授权正式用户开放 | 根据经营资格、合作模式、服务协议、适当性与审核结果开放 |
| 自动下单 | 首期关闭 | 另立项目,核验券商授权与程序化交易等要求 |
后台 service_entitlements 和全局能力配置共同控制,不仅在 App 隐藏按钮。合作方与系统提供方各自职责需明确,不能认为一次审核或一行免责声明就具备全部上线条件。
16. 回测、模拟交易与复盘
16.1 回测任务规范
每次回测固定:策略与参数版本、代码镜像摘要、数据清单与哈希、证券池时点、因子可用时间、交易规则版本、费用、滑点、成交模型、基准、时间范围、随机种子和指标口径。
分钟条件不能用尚未结束的 bar 最终数据执行;收盘才知道的信号通常从下一个可执行时点开始模拟。信号时点、委托时点、成交时点分开,禁止“用当日收盘得出信号又在同一收盘价必然成交”的隐性前视。
16.2 历史数据与成交约束
必须包含退市证券与历史证券池变化,避免幸存者偏差;财务指标按当时披露和更正时点使用,避免未来数据回填。复权用于研究的方式要与真实成交价格、现金分红、配股等分开,不能同时复权和重复入账红利。
成交模型包含 T+1、交易日历、停牌、涨跌停、数量和价格规则、费用、滑点、成交量参与率与部分成交。缺少盘口时采用保守成交假设,显示假设敏感性;不能把触价等同于全部成交。成本参数是版本化输入,不把原型 0.10% 示例当真实统一费率。
16.3 研究分段与指标
训练/参数研究、验证、最终样本外区间按时间切分,进行滚动验证;高度相关样本采用相应隔离方法。记录所有实验,控制反复调参挑最好结果的问题,冻结上线候选后不再用最终测试区间调参。
报告至少包含:成本后累计与年化收益、年化波动、最大回撤与持续时间、基准超额、换手、交易笔数、胜率、盈亏比、平均持有期、敞口、无法成交次数、费用贡献、收益分布和不同市场阶段。Sharpe 等指标注明频率与无风险利率假设;样本不足时不夸大稳定性。
展示“历史回测”,不得混入“真实成交”。策略发布前需要样本外研究、成本敏感性与前向模拟跟踪,不能因一个漂亮净值图直接上线。
16.4 模拟交易与真实记录
模拟成交只能按预定、可追踪的成交模型产生,不能用户点击就总以有利价格成交。手工模拟成交与系统撮合模拟分别标记来源,避免把两类结果混成策略证明。
真实记录展示用户确认的成交、费用和外部出入金;未经券商核验明确标记。没有完整现金流水时只报告股票交易盈亏和持仓估算,不报告完整账户收益率。
16.5 复盘指标与公式
买入批次成本 = 成交价格 × 成交数量 + 按规则归入的买入费用
卖出已实现盈亏 = 卖出收入 - 卖出费用 - 分配到卖出数量的批次成本
未实现盈亏 = 当前估值 - 剩余批次成本(明确未来卖出费用是否已计)
完整账户权益 = 已核对现金 + 持仓估值 + 其他已确认资产/应收项
部分卖出采用明确的批次分配规则(首期 FIFO);成本和可卖数量以批次账本为基础。资金进出时,账户收益计算使用明确的时间加权口径;如展示资金加权收益另说明算法。不能简单用“当前资产减初始资产”忽略追加资金。
AI 复盘解释只能基于程序统计,区分策略行为与用户偏离:未触发买入、超计划仓位、迟延退出、费用影响、信息变化。避免仅凭事后涨跌编造“当时必然应该买卖”的结论。
17. 部署、可观测性与容灾
17.1 首期部署
| 组件 | 开发环境 | 生产初始方案 |
|---|---|---|
| App | Expo Development Build、真机 | iOS/Android 商店或合规分发,独立包标识 |
| 管理 Web | Vite 本地 | 静态资源托管+HTTPS 入口,后台访问限制 |
| Go API | 本地进程/Compose | 至少 2 个实例,健康检查与滚动发布 |
| Go Worker | Compose,按任务类别进程 | 监控/通知与回测调度分队列,独立并发上限 |
| Python | 固定依赖环境 | 计算容器,与 API 隔离 CPU/内存 |
| PostgreSQL | Compose | 托管 HA、备份、PITR,限制公网 |
| Redis | Compose | 托管或受控主从;故障时事实不丢失 |
| 对象存储 | 本地兼容服务 | 私有桶、加密、版本与生命周期 |
| 密钥 | 本地受控环境文件 | Secret Manager,权限和轮换 |
部署区域优先接近授权行情和用户,最终由数据授权、服务合规和供应商可用区域共同决定。不得默认用国际推送和模型区承担全部中国大陆数据处理。
17.2 CI/CD
提交检查:格式、静态检查、类型检查、契约生成差异、依赖安全、核心测试。构建不可变镜像与 App 工件,产生版本清单。上线采用 staging 验证→生产小范围灰度→指标检查→扩量,保存审批与回滚点。
数据库使用扩展→迁移数据→收缩模式;先添加兼容字段,再升级服务,旧字段删除另一个版本执行。备份不是自动回滚方案,回滚服务镜像必须与当前 Schema 兼容。策略/Prompt/模型配置与应用代码可独立发布,但必须有兼容矩阵和审计。
17.3 监控与告警
| 类别 | 指标 | 初期告警方向 |
|---|---|---|
| API | P95/P99、错误率、限流、连接数 | 超出容量验收基线 |
| 行情 | 源延迟、覆盖、缺口、乱序、异常价、完成 bar 延迟 | freshness 超限即降级并通知运营 |
| 任务 | 最老任务年龄、积压、租约超时、失败率 | 监控/通知优先;回测不抢占 |
| AI | 时延、token、失败、Schema/证据校验、备用率 | 质量下降阻断发布,预算超限熔断 |
| 账本 | 数量/现金不变量、投影差异、重放失败 | 严重异常冻结受影响账户写入 |
| 推送 | 网关受理、回执错误、token 失效、过期抑制 | 按供应商分类,不能只统计“成功率” |
| 业务 | 候选有效数、审核时长、计划触发、偏离、撤回 | 同时看质量与风险,不以推送数量作为成绩 |
| 安全 | 异常登录、越权、密钥访问、敏感导出 | 会话撤销与事件处置 |
每条链路关联 trace_id / event_id / job_id / aggregate_id / model_config_version。观测平台脱敏,配置审计与业务资产日志分开权限。
17.4 容灾与恢复目标
规划目标:已提交的同数据库账本事务无部分入账;数据库灾难场景 RPO ≤ 5 分钟、核心只读/账本恢复 RTO ≤ 60 分钟,具体取决于采购的备份和 HA 能力,必须演练证明。Redis 丢失通过数据库重建,不造成账本丢失。
每日备份、持续归档和异地保留按服务条件落实;每月至少抽样恢复,每季度完成一次故障演练。恢复顺序:身份与数据库→历史查询与账本核验→数据接入与日历→确定性监控→通知→AI 与新建议。未通过行情质量和时效校验前,不恢复主动买入提示。
18. 测试与验收标准
18.1 测试层级
Go 单元测试覆盖 Domain 规则;真实 PostgreSQL 集成测试覆盖事务、幂等与竞争;Python 黄金样本和历史 replay 覆盖因子与成交模型;OpenAPI 契约测试覆盖 App/管理端客户端;Web 使用 Playwright,App 使用真机/自动化流程工具完成端到端验收。
不靠逐字段镜像实现的测试证明正确性。核心测试以业务不变量、并发场景、历史已知样本和跨端结果为依据。
18.2 核心验收用例
| 编号 | 场景 | 通过标准 |
|---|---|---|
| A01 | 新用户无持仓 | 能发现有效候选;没有机会时显示真实空状态 |
| A02 | 管理端发布候选 | App 可读最新修订;未发布内容不可越权访问 |
| A03 | 候选撤回后旧推送打开 | 显示失效原因,不能继续创建对应买入计划 |
| A04 | 两个计划争用资金 | 总保留额度不超过允许值;并发提交也成立 |
| A05 | 触发后未成交 | 不产生持仓、不扣现金,仅记录提醒 |
| A06 | 重复提交同一成交 | 只入账一次,返回原幂等结果 |
| A07 | 两笔并发卖出 | 不超卖;失败请求不留下半笔流水 |
| A08 | 当天买入和跨交易日可卖 | 按证券与日历规则计算,节假日不提前解锁 |
| A09 | 非统一买入单位证券 | 按对应规则校验,不硬编码全部 100 股 |
| A10 | 部分买入/卖出 | 批次、费用、现金、计划数量与保留额度一致 |
| A11 | 历史补录和冲正 | 按时间重放;缺失历史显式待核对;审计保留 |
| A12 | 无完整现金的真实记录账户 | 不虚构 10 万余额,不显示完整账户收益率 |
| A13 | 行情断流/乱序/旧数据 | 不产生新买入触发;恢复不推陈旧“实时”提醒 |
| A14 | 策略暂停/版本更新 | 待买触发停止;旧历史版本不变;存量风险监控保留 |
| A15 | 主模型超时,备用也失败 | 规则提醒继续,新 AI 解释标记不可用,无伪造结果 |
| A16 | 模型输出虚构证据/错误金额 | 校验失败,不进入正式发布 |
| A17 | 提示注入公告 | 不执行命令,不越权调用工具,不泄露敏感数据 |
| A18 | 通知关闭/通道失败 | 站内通知仍存在;界面如实显示通道状态 |
| A19 | 过期提醒重试 | 拒绝发送,产生抑制/过期记录 |
| A20 | 只读角色/跨用户 ID 篡改 | 所有写入或越权查询在服务端拒绝并记录 |
| A21 | WebSocket 重连/游标过期 | 去重或快照重同步,无重复入账与永久旧状态 |
| A22 | 回测前视/不可成交样本 | 已知未来字段不可用,停牌等样本按预定模型处理 |
| A23 | 模拟与真实切换 | 缓存、提醒、计划、净值互不串账户 |
| A24 | 数据库恢复与投影重建 | 通过账本不变量,恢复步骤和实际 RTO/RPO 可测 |
| A25 | 国内 Android 真机与 iOS 冷启动 | token 注册、推送点击、白名单深链、最新状态拉取成功 |
| A26 | 320/390 宽度、字体放大、深色 | 无遮挡、可操作、不依赖绿色/蓝色状态 |
18.3 账本不变量与发布门槛
账本至少保证:剩余批次数量非负;可卖量不大于总量;卖出分配量等于卖出数量;资金流水与成交/费用一致;冲正一一关联;用户不能访问他人账户;投影重建结果与增量结果一致;计划成交进度只来自被确认的关联成交。
发布门槛:P0 验收通过、核心风险/账本测试全通过、无未解决严重安全问题、数据授权与服务能力符合上线范围、模型评估合格、真机通知通过、容量与恢复演练完成。真实建议服务另须完成第 15.4 节门禁,不把技术测试通过等同于商业许可完成。
19. 开发目录与团队协作
19.1 推荐仓库结构
veyra/
apps/
mobile/ # Expo App
admin/ # React 管理端
packages/
api-client/ # OpenAPI 生成 TS 客户端
design-tokens/ # 颜色、间距、字体与业务色义
contracts/ # JSON Schema 与事件规格
services/
api/
cmd/api/
cmd/worker/
internal/
identity/ profile/ market/ strategy/ research/
planning/ risk/ portfolio/ notification/ operations/ audit/
platform/ # DB、缓存、日志、时钟、事务
db/migrations/
db/queries/
api/openapi.yaml
quant/
app/ # 内部受控任务 API
factors/ strategies/ backtest/
tests/golden/
pyproject.toml
specs/
trading-rules/ # 版本化规则与黄金样本
events/
risk-policies/
infra/
compose/ environments/ dashboards/ runbooks/
docs/
architecture/ product/ operations/
共享设计 Token 和 API 契约,不强行共享 RN 与 Web UI 组件。Python 与 Go 共享规则规格及测试样本,不复制未经对照的规则实现。
19.2 责任分工与工作约定
| 角色 | 主要交付 |
|---|---|
| 产品/设计 | 页面状态、业务文案、用户确认、异常与降级流程 |
| App | 原生路由、查询缓存、账户隔离、真机通知、发布 |
| Web | 十个工作区、审核版本冲突、权限呈现、图表报告 |
| Go | 业务状态、风险、账本、API、事件、供应商适配 |
| 量化 | 因子规格、时点数据、回测、样本外与前向验证 |
| 测试 | 业务不变量、跨端 E2E、故障、真机、容量 |
| 运维/安全 | 密钥、环境隔离、监控、备份、发布与恢复 |
| 合规/业务负责人 | 数据合同、服务资格、适当性、审核职责与留痕范围 |
每个需求先写触发、前后状态、失败路径、契约与验收用例。API 变更先改 OpenAPI 与事件 Schema,再更新客户端。价格规则、Prompt 和策略配置与代码同样走评审和版本控制。
20. 分阶段实施计划
20.1 推荐实施顺序
| 阶段 | 规划时长 | 工作内容 | 退出条件 |
|---|---|---|---|
| 第 0 阶段:规格与采购验证 | 1–2 周 | 确认数据供应商、功能边界、规则规格、契约、视觉组件、国内推送 PoC | 数据字段与授权可用,技术依赖与真机路径验证 |
| 第 1 阶段:工程骨架 | 2 周 | 双端工程、Go 分层、账户、身份、迁移、任务、审计、CI | 双端连通服务,隔离环境可部署 |
| 第 2 阶段:交易闭环 | 3–4 周 | 候选、审核、计划预览、风险、成交账本、持仓、通知 | 使用固定回放数据跑通 A01–A12、A20、A23 |
| 第 3 阶段:数据与 AI | 2–3 周 | 授权源、日历、因子、模型适配、证据、实时监控、故障降级 | 回放与真实小范围数据结果一致,质量门禁有效 |
| 第 4 阶段:研究与硬化 | 2–3 周 | 真实回测、复盘、容量、真机、恢复、灰度、运营流程 | 所有 P0 验收通过,具备受控试运行条件 |
| 第 5 阶段:前向跟踪 | 持续 | 模拟表现、错误分析、规则优化、商业上线审核 | 根据数据质量和业务资格决定开放能力 |
按 1 名 App、1 名 Web、2 名 Go、1 名量化、1 名测试,产品设计与运维部分参与估算,技术闭环约 10–15 周;可重叠开发,但关键数据采购和规则验收影响总体路径。单人开发不能直接沿用该并行排期,建议先做模拟闭环,再接真实数据。
此估算不包含证券建议服务资质、合同采购、应用备案/审核、商店审核的确定办理时间,也不把前向策略验证压缩成工程开发周数。
20.2 首个可用版本必须完成的纵向切片
一个授权或明确模拟证券 → 一个策略版本 → 一份可核验证据 → 管理端审核发布 → 空仓 App 看到候选 → 计划预览与确认 → 数据事件触发 → 站内/远程提醒 → 用户录入成交 → T+1 批次监控 → 卖出计划与成交 → 成本后复盘。
先证明一条纵向切片的正确性,再扩大策略数量和全市场扫描,能尽早暴露跨端状态、账本和时效问题。
20.3 第一批研发任务
- 建立 monorepo、主题 Token、OpenAPI 和账户模式枚举。
- 实现登录、对象权限与模拟账户初始化;真实记录账户不默认赋现金。
- 定义证券/规则/交易日历版本与 Go/Python 黄金样本。
- 实现成交账本、冲正和可重建持仓,先通过并发与 T+1 测试。
- 实现候选修订、审核、计划预览/确认、预算保留与 Outbox。
- 完成 App 空仓路径和管理端候选工作区。
- 接入回放数据监控、站内通知,再测试真机远程推送。
- 接入主/备模型与证据校验,最后接真实回测和完整复盘。
21. 容量、成本与扩展路径
21.1 首期容量基线
以下仅用于压测设计,不能当成已实现吞吐能力:注册用户 5,000、日活 1,000、前台峰值连接 300、活动计划 10,000、持仓条目 5,000、候选发布每日 0–50、公共 AI 分析每日约 500–3,000 次。全市场分钟扫描范围按数据合同和批处理预算确定,活跃证券优先监控。
压测同时包含开盘数据波峰、集中通知、多人创建计划、用户补拉、回测资源占用和供应商降级,不只测一个 /health 接口。达到基线后记录实测 P95、资源和成本,再决定扩容。
21.2 数据量估算
用 证券数 × 每日 bar 数 × 交易日数 × 单行存储 估算分钟线,另加索引、版本和备份。例如假设 5,000 只证券、240 个完整分钟 bar、250 个交易日,则约 3 亿行/年;这是容量算例,不是对实际证券总数和每年交易日的断言。
因此全量长期分钟线不能简单长期堆在同一个业务表里。冷热分离、Parquet 分区和研究任务数据切片需从第一版规划;在线数据库只保存规定窗口和服务所需结果。
21.3 成本模型
| 成本项 | 计算方式 | 控制方法 |
|---|---|---|
| 行情与公告授权 | 覆盖范围、时延、终端数、展示/分析与留存许可 | 按真实功能采购,不能以免费抓取代替生产授权 |
| API/Worker | 实例时长、资源、流量 | 分队列、批处理、缓存与弹性扩容 |
| PostgreSQL/Redis | 存储、IO、连接、HA 与备份 | 窗口、分区、连接池、定期归档 |
| 对象存储 | 压缩数据、版本、读取和出网 | Parquet、生命周期与受控下载 |
| AI | 各路由输入/缓存/输出 token × 当时单价 | 公共结果复用、事件触发、短上下文、预算 |
| 推送/短信 | 供应商计费与请求量 | 通道去重、通知合并、验证码防滥用 |
| 监控与安全 | 日志、指标、留存、扫描、密钥服务 | 脱敏和按用途分层留存 |
| 人力与业务 | 开发、研究、运营、审核、采购及资格 | 与技术费用分开估算 |
模型成本公式:Σ(input_tokens×input_price + cached_tokens×cache_price + output_tokens×output_price),注意单价单位通常为每百万 token,不同区域、时段和供应商可能不同。[R9][R10] 若每日 1,000 次、每次 6,000 输入/1,000 输出,则每日约 600 万输入与 100 万输出 token,再加备用、评估和重试;按采购时单价计算,而不是用调用次数直接估价。
在未确定供应商合同、部署区域、行情许可与真实负载前,不给出伪精确月费。第 0 阶段取得报价后形成低/中/高用量预算,并设硬额度与通知。
21.4 扩展触发条件
| 观察到的问题 | 优先措施 | 后续选项 |
|---|---|---|
| 数据库任务领取/事件回放成为瓶颈 | 优化索引、批量派发、任务分区 | 独立事件总线 |
| 长期行情分析 IO 超载 | 扩展 Parquet 分区、缓存与任务切片 | ClickHouse 研究仓库 |
| 前台连接拖累 API | 网关进程独立部署与订阅限额 | 独立实时服务 |
| 回测占满资源 | 计算队列隔离与配额 | 按任务拉起临时计算资源 |
| AI 费用随用户线性增长 | 公共分析复用与事件去重 | 精细分层路由/合格小模型 |
| 权限与运营范围复杂 | 范围化 RBAC、审计与业务授权 | 多租户机构工作区 |
22. 关键决策、待定项与开发起点
22.1 本版已定决策
| 决策 | 结论 |
|---|---|
| 端形态 | React Native + Expo App;React Web 管理端 |
| 品牌 | 中文「见势」、英文「Veyra」;完整名称「见势 · Veyra」 |
| App 视觉 | 白底/石墨黑/少量柔紫,无绿色,不用蓝色主品牌 |
| 管理端视觉 | 保留暖白/炭黑/焦糖橙后台主题,品牌入口统一更新 |
| 后端 | Go 模块化单体+独立 Worker,Python 量化服务 |
| 存储与队列 | PostgreSQL 业务事实/Job/Outbox,Redis 缓存,对象存储归档 |
| 核心业务 | 从空仓推荐到计划、成交、持仓、退出、复盘 |
| 模型职责 | Qwen 主路由、DeepSeek 备用;解释与证据分析,不能取代风险和账本 |
| 实时 | 规则先触发,AI 异步解释;前台事件+后台推送 |
| 账户 | 模拟与真实记录隔离;不默认生成真实现金余额 |
| 执行 | 用户自行在券商操作;首期没有自动下单 |
| 发布 | 候选修订+人工审核+服务授权门禁 |
22.2 启动开发时需要落定的外部条件
| 待定项 | 默认处理 | 对进度的影响 |
|---|---|---|
| 行情供应商与许可 | 先用固定回放数据开发;真实连接仅在授权后启用 | 实时质量、源字段与采购周期 |
| 首批板块与权限核验方式 | 主板白名单;其他板块默认不提供可执行建议 | 规则与适当性工作量 |
| 商业经营与合作模式 | 研发/模拟完整流程,正式能力按门禁开放 | 真实建议是否可上线 |
| 推送供应商 | Expo/APNs 可用路径+国内 Android PoC | 原生 SDK、真机与隐私要求 |
| 云供应商与区域 | 受控托管服务与中国大陆用户可用性验证 | 数据地区、网络、成本 |
| 团队人数 | 按第 20 节团队假设排期 | 并行能力与实际工期 |
这些不是阻止编写接口和业务代码的前置问题:可先完成固定数据回放、模拟账本和双端闭环。真实生产数据、实际建议发布和商业收费应在对应条件满足后启用。
22.3 文档用途与实现边界
本报告可用于拆研发任务、确定模块和契约、评审数据库与风险、规划测试和基础设施。它不包含已经运行的后端、真实历史回测结果或已经采购的服务。工程开始后以版本化 OpenAPI、规则规格、迁移文件、ADR 和验收结果持续维护,不让实现细节与此设计长期分离。
23. 官方参考资料
参考日期为 2026-10-04。下列资料用于核验技术能力或业务边界;供应商功能、版本、计费和法律要求可能变化,上线与采购时需再次确认。本文的模块划分、容量、排期和风险阈值是本项目设计判断,不是官方承诺。资料只作短摘要引用,未复刻原文。
| 编号 | 官方资料 | 对应设计依据 |
|---|---|---|
| R1 | Expo Router Introduction | App 路由与深链 |
| R2 | TanStack Query Overview | 服务端状态与查询缓存 |
| R3 | Expo SecureStore | 敏感凭据本地存储 |
| R4 | Expo Notifications | 推送 API、开发构建与原生配置 |
| R5 | Ant Design Customize Theme | 管理端主题 Token |
| R6 | Gin Documentation | Go 路由与中间件框架 |
| R7 | sqlc Documentation | SQL 与类型化代码生成 |
| R8 | PostgreSQL Explicit Locking | 行锁、任务领取与并发约束 |
| R9 | 阿里云百炼 qwen3.7-plus | 快照 ID、结构化输出、工具能力与计费核验 |
| R10 | DeepSeek Models & Pricing | 模型别名、接口能力与计费变化 |
| R11 | Go Release History | 稳定分支与补丁维护核验 |
| R12 | 上交所修订发布《上海证券交易所交易规则》 | 交易规则按版本与生效时间维护;不是所有板块的完整规则清单 |
| R13 | 上证所信息网络有限公司:行情服务 | 行情服务与采购核验入口,具体许可取决于合同 |
| R14 | Expo:Send Notifications / Delivery Guarantees | 回执、重试与设备送达限制 |
| R15 | 证监会:规范利用“荐股软件”从事证券投资咨询业务;江苏监管局:软件工具应说明方法和局限 | 商业能力与审核边界;须结合现行适用规定核验 |