mirror of
https://github.com/shy3130/tick-stock-panel.git
synced 2026-11-02 02:16:13 +00:00
- AI 助手: RunningHub 推广位(标题行跑马灯、一周静默、无缝循环、悬停暂停), 抽屉头部与侧边栏模型名完整显示 - 测试: mining manager 终态事件轮询收敛, 消除状态先于事件落盘的读侧竞态 - 文档: 新增虚拟账户(模拟盘)功能设计方案 docs/paper-trading-plan.md
9.3 KiB
9.3 KiB
虚拟账户(模拟盘)设计方案
状态: 设计稿(未实现)。本文档描述目标形态与实现路径, 供评审与分期开发。 遵循 CONTRIBUTING.md 的数据口径、插件化与测试矩阵要求。
1. 目标与非目标
目标
- 把「策略 → 信号 → 决策 → 收益」打通为实时闭环: 用户用虚拟资金跟单自己的策略/信号, 以真实行情价格模拟成交, 每天看到虚拟净值曲线与回合统计。
- 与回测互补: 回测重放历史, 模拟盘实时向前, 无未来函数, 验证的是「我现在敢不敢按这个信号操作」。
非目标
- 不接入券商、不做实盘下单、不提供任何资金通道。
- 不做高频/tick 级撮合模拟(分钟/快照级足够)。
- V1 不做多账户并行(数据结构预留, UI 只开放单账户)。
2. 核心概念与账务模型
| 概念 | 说明 |
|---|---|
| Account 账户 | 初始虚拟资金 + 费用参数 + 状态(active/frozen/closed) |
| Order 订单 | 买/卖意向; 来源 manual / auto(规则触发); 含订单类型与时效 |
| Fill 成交 | 订单的一次实际成交(价格、数量、费用); append-only 台账 |
| Position 持仓 | 由成交台账推导物化(avg_cost、可卖数量), 可随时重建 |
| NAV 净值 | cash + Σ(qty × 市价); 收盘后用日线收盘价定版, 盘中用实时价估算 |
| 回合 Round-trip | FIFO 配对的开->平周期, 统计胜率/盈亏比/持有天数 |
账务正确性原则(镜像财务报表口径): 成交台账是唯一事实源, 持仓与净值全部可由台账重放推导; 任何修复动作以「冲正成交」记录, 不允许直接改持仓文件。
3. 数据模型与存储
沿用 app/strategy/lots.py 的域模块模式: 每实体一个 JSON + atomic_write_text 原子写, 目录挂 data_dir 下, 跨请求写互斥(镜像 lots API 的 _write_lock 与「全部校验通过才落盘」)。
data/paper/
account.json # 单账户 V1: id, initial_cash, fees, status, created_at
orders/order_{id}.json # 含 status: pending / filled / cancelled / expired
fills.jsonl # append-only 成交台账(每行一笔, 带序号与时间戳)
positions.json # 物化持仓(可由 fills.jsonl 重建, rebuild 接口兜底)
nav/daily.jsonl # 每交易日一条定版净值 {date, cash, mv, nav, benchmark_nav}
auto_rules/rule_{id}.json # 自动跟单规则
关键字段口径:
- 价格一律不复权 raw 价(与真实交易一致); 持仓市值用
raw_close。 - 除权处理: 日终结算时检测持仓 symbol 当日有除权因子(
adj_factor_etf/adj_factor), 按因子调整数量与成本(送转 → 数量乘因子、成本除因子; 现金分红 → cash 入账), 并记一条corporate_action冲正成交, 保证净值曲线连续。 - 费用:
commission_pct(双边, 默认万 2.5, 最低 5 元)、stamp_tax_pct(卖出印花税, 默认千 1)、slippage_bps(默认 5)——与回测引擎app/backtest/engine.py的参数名和默认值完全一致, 用户心智一份口径。
4. 撮合规则(金融口径, 必须逐条测试)
| 规则 | 口径 |
|---|---|
| 即时市价单(盘中) | 以订单创建后的下一次实时快照价成交 + 滑点; 非交易时段创建则转为次日开盘单 |
| 次日开盘单 | 次一交易日 raw_open 成交 + 滑点; 当日无行情(停牌/新股)则顺延, 顺延满 N 日(默认 3)自动 expired 并留痕 |
| 当日收盘单 | 当日 raw_close 成交(盘后管道执行) |
| 买入数量 | 100 股整数倍(ETF 同); 资金不足按可用现金向下取整到百股, 不足一手则拒绝 |
| T+1 | 当日买入份额次日方可卖; Position.available_qty 在日终结算解锁 |
| 涨跌停 | V1 简化: 触及涨停价的买单 / 跌停价的卖单直接 expired(留痕); V2 可选「排队次日重试」 |
| 停牌 | 无法取价即不成交, 按顺延规则处理 |
| 撤单 | 仅 pending 可撤; 已成交不可逆(只能反向平仓) |
时点约束: 所有成交时间戳取北京墙钟(复用仓库既有北京时间口径); 交易日判断复用交易日探针, 非交易日不撮合不结算。
5. 运行时挂点(全部复用现有引擎)
盘中: quote_service._evaluate_monitors 的同一 tick
└─ paper_engine.evaluate(now)
├─ 处理 pending 即时单(用实时快照价)
└─ 自动规则监听信号事件 → 生成订单(带 cooldown 去重, 复用监控事件去重思路)
盘后: daily_pipeline 新增 stage: paper_settle
├─ 收盘价定版: 未成交的收盘单/顺延单撮合
├─ mark-to-market: 写 nav/daily 定版(含基准 000300.SH 同日收盘)
├─ 除权调整 + T+1 解锁
└─ 异常(缺行情/缺因子) warning 留痕, 不中断管道
- 自动跟单规则 V1 形态:
{signal_source: 策略id|信号id, side: buy, size_mode: fixed_amount|pct_equity, order_type: next_open, cooldown_days: 5, scope: 自选分组|全信号}; 触发链路复用信号库/策略扫描的产出事件, 不新增采集。 - 语音/推送: 成交与规则触发事件走监控中心既有 SSE + 语音播报 + 飞书通道(新增事件类型, 前端无需新管道)。
6. API 设计(/api/paper/*, 薄胶水 + 域模块)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET / PUT | /api/paper/account |
账户详情/费用参数(初始化向导) |
| GET | /api/paper/overview |
现金 + 持仓(实时估值) + 今日订单/成交 + 盘中估算净值 |
| POST | /api/paper/orders |
手动下单 {symbol, side, qty | amount, order_type} |
| GET | /api/paper/orders |
订单列表(可按 status 过滤) |
| DELETE | /api/paper/orders/{id} |
撤销 pending 订单 |
| GET | /api/paper/trades |
成交台账(分页) |
| GET | /api/paper/nav |
净值序列 + 基准(沪深300 归一化) |
| GET | /api/paper/stats |
回合统计: 胜率/盈亏比/平均持有天数/最大回撤/对比基准 |
| CRUD | /api/paper/auto_rules |
自动跟单规则 |
| POST | /api/paper/rebuild |
由 fills.jsonl 重建 positions(修复兜底, 管理入口) |
约定: symbol 经 repo.resolve_asset_type 区分 stock/etf(镜像 lots API); 资产类型影响涨跌停与最小单位判断。
7. 前端设计
新页面「模拟盘 Paper」(侧边栏一级菜单, 图标 💰/PiggyBank):
- 总览区: 净值曲线 vs 沪深300(复用 ECharts 组件)、现金/市值/总资产/当日盈亏卡片、盘中估值角标「实时估算, 收盘定版」
- 持仓表: 复用 Lots/自选的表格交互——现价(实时)、成本、浮盈、可卖数量、占比; 行内「卖出」按钮
- 下单面板: symbol 搜索 + 数量/金额 + 订单类型; 入口同时嵌到个股分析页与自选行内的「虚拟买入」按钮
- 流水区: 今日订单/成交、全部成交台账
- 自动跟单页签: 规则列表 + 新建(选策略/信号 + 仓位方式 + cooldown)
- 统计页签: 回合明细与汇总(口径与回测报告一致, 降低理解成本)
8. 统计口径(与回测对齐)
- 回合配对: FIFO; 胜率 = 盈利回合数 / 总回合; 盈亏比 = 平均盈利 / 平均亏损
- 最大回撤基于 nav/daily 定版序列
- 基准:
000300.SH同期归一化(数据已有); 盘中估算净值不参与统计, 只展示
9. 边界、并发与风控
- 写并发: 域模块内全局写锁; 盘中 evaluate 与手动下单竞争同一把锁(镜像 mining_manager 的互斥模式)
- 单账户限制: 持仓标的数上限(默认 50)防误操作; 单笔金额上限(默认不超过可用现金, 不提供杠杆)
- 冻结: 账户 frozen 后拒绝新订单, 持仓只读; 保留数据可重建
- 数据缺失: 缺行情/缺因子一律留痕 warning + 顺延, 绝不臆造成交价(金融数据错误原则)
- 回滚: 停用功能 = 冻结账户 + 隐藏菜单; 数据目录独立(
data/paper/), 删除即卸载
10. 测试矩阵(per CONTRIBUTING)
| 层 | 测试 |
|---|---|
| 撮合域模块 | T+1 解锁、涨跌停拒单、百股取整、最低佣金、印花税单向、滑点方向、停牌顺延与过期、除权数量/成本调整、资金不足拒绝 |
| 账务 | fills.jsonl 重放 == positions.json(性质测试)、净值 = cash + Σ市值、冲正成交后曲线连续 |
| 管道挂点 | 盘后结算幂等(重跑同日不重复成交)、非交易日不结算 |
| 自动规则 | 信号触发生成订单、cooldown 去重、scope 过滤 |
| API 契约 | 下单/撤单/overview 成功与错误响应 |
| 前端 | tsc + vite build; 关键交互本地 dev 目测 |
修复 bug 一律先写复现测试再修(先失败后通过)。
11. 分期与工作量
| 期 | 内容 | 预估 |
|---|---|---|
| V1 核心闭环 | 账户+手动下单(即时/次日开盘/收盘)+撮合域模块+盘后结算+净值曲线+持仓/流水页 | 3-4 个 PR, 约 1.5-2 周 |
| V2 自动化 | 自动跟单规则、涨跌停排队可选、多账户、统计页签完整化 | 约 1 周 |
| V3 增强 | 成交推送/语音、导出 CSV、与回测报告同构对比页、AI 复盘注入模拟盘数据 | 约 1 周 |
V1 交付即有完整价值: 手动跟单信号 → 看实时虚拟净值。
12. 明确不做 / 后续再议
- 实盘通道、融资融券、期权期货
- tick 级盘口撮合
- 龙虎榜游资席位跟单(可作 V3 的规则信号源之一)