578 lines
34 KiB
Markdown
578 lines
34 KiB
Markdown
# 下一阶段开发方案与规格书(2026-09-14)
|
||
|
||
> 供拍板与实施。开发者可以是人,也可以是大模型。
|
||
> 写法遵守 `.claude/output-styles/readable-chinese.md`。
|
||
> 第一到第九节是正文,读完就知道做什么、为什么、怎么验证。
|
||
> 附录是实现细节,标了「可不读」。但开发者动手前必须读自己那个工作包的附录。
|
||
> 评审依据见《三源合议阶段评审_2026-09-14.md》。
|
||
|
||
---
|
||
|
||
## 一、这件事为最终目标买什么
|
||
|
||
最终目标是持仓管理系统在真实仓上全自动运行。分工不变:选股系统出候选,决策系统出研判与择时,持仓管理系统定做什么与多少,下游只管执行。
|
||
|
||
到今天,模拟仓上三源合议的整条链已经部署,但一个交易日都还没跑过。真实仓卡在下游 QMT 侧,等对方。所以这一阶段不是再加功能。这一阶段做四件事。一,把已经上线的纪律变成能量化复核的纪律。二,把方案里欠的那块补齐。三,把写好的功能按不互相干扰的顺序开起来。四,为真实仓准备好追平清单。
|
||
|
||
这一阶段买三样东西。
|
||
|
||
1. 复核的依据。没有读数就没有复核,没有复核就不能把这套东西部署到真实仓。
|
||
2. 技术面对入场时点的盘中判断。现在技术面那一票全是昨夜数据,方案第三节的盘中确认没落地。
|
||
3. 真实仓上线的安全前提。一份初始参数清单加一个自检脚本,保证追平部署不会把模拟仓的默认值带进真实账户。
|
||
|
||
## 二、原则
|
||
|
||
沿用方案的三条设计原则。一是入场靠投票,离场靠纪律。二是无读数等于弃权。三是研判闸不当选票。本阶段再加四条。
|
||
|
||
1. 先观察后调参。台账 006 到 011 的阈值不按复盘读数回调。要调,先回台账写一条。
|
||
2. 一次只开一个会互相喂的开关。观察窗口不重叠。
|
||
3. 每一处改动都守「开关关掉逐字回旧」,并先写这条单测再改。
|
||
4. 判收只认真机。开发机单测绿只是进门票。
|
||
|
||
## 三、做哪几件事
|
||
|
||
八个工作包,按建议的动工顺序排。前四个是代码。第五个只改参数。第六个在另一仓库。第七个等 QMT 侧。第八个是文档。
|
||
|
||
每个工作包的名字就是它做的事,不另起代号。
|
||
|
||
### 观察读数包(最先做)
|
||
|
||
**做什么。** 把每轮扫描里合议相关的判定落表,一天最多写四次。给一个复核脚本与一个日报小节,把台账要的四个读数直接打出来。
|
||
|
||
**为什么先做。** 台账 006 到 009 的复核日期是合议分流上线后满三个交易日,也就是 09-17。到那天没有读数就复核不了。后面所有调参与上真实仓的决定都没有依据。
|
||
|
||
**做哪几件。**
|
||
|
||
1. 新表 pms_consensus_stat。一天一票一类一行,重复记到只加次数。
|
||
2. 动作引擎给合议相关的跳过项打上类别标签。只在开关开着时打,关掉时一个字都不多。
|
||
3. 新服务把一轮扫描的结果归类落表。只在四个检查点写,转空离场实弹随时写。试算不写。
|
||
4. 技术面映射重建时记下「相关票里没有读数的」和「覆盖只数」。
|
||
5. 复核脚本 `scripts/consensus_review.py`,外加 `make consensus-review` 目标。
|
||
6. 日报加「合议观察」小节。
|
||
|
||
细节见附录甲。
|
||
|
||
### 盘中确认包
|
||
|
||
**做什么。** 给技术面这一票加方案第三节写明的盘中确认,只用于入场。时段是 09:45 到 14:30。量比口径与解锁重问同源,也就是台账 003 的时段折算量比。
|
||
|
||
**两条规则。**
|
||
|
||
1. 收口突破。相位是收口等待的候选,盘中现价站上昨日布林上轨,且时段折算量比不低于 1.5,当轮视为开口向上。重新合议后进候选。
|
||
2. 开口确认。相位是开口向上的候选,盘中要求现价不低于当日均价,且量比不低于 1.5。不满足就当轮进观察,处置词是「等盘中确认」。下一轮再看。
|
||
|
||
**一个要拍板的读法。** 开口向上的候选在 09:45 之前与 14:30 之后进观察,等确认时段。收口等待的候选在时段之外照旧观察。
|
||
|
||
**为什么做。** 技术面决定「什么时候投」。没有盘中那一道,它只能说昨天。
|
||
|
||
细节见附录乙。
|
||
|
||
### 页面收尾包
|
||
|
||
1. 单票研究面接口补齐基本面、择时、合议、来源四块。页面抽屉那一节改成「研究面 · 三源合议」四枚芯片。
|
||
2. 候选栏每行加质地芯片与技术芯片。
|
||
3. 管理视图持仓总览加研究面列。
|
||
|
||
细节见附录丙。
|
||
|
||
### 加固包
|
||
|
||
1. 转空去重集只在映射明确为多时清除。
|
||
2. 持仓行的择时票带上盘中转多留痕。
|
||
3. 登记 PMS_CONSENSUS_WEAK_CONFIRM 并接进合议路由。
|
||
4. 第二十四批用例改成相对当前时刻构造陈旧告警。
|
||
|
||
细节见附录丁。
|
||
|
||
### 分段启用包(只改参数,不改代码)
|
||
|
||
**现状。** 今天 09-14 是合议分流跑的第一个交易日。策略层总开关已经是开的。解锁重问从 09-10 起就开着。这三样都在跑。
|
||
|
||
**顺序。**
|
||
|
||
| 段 | 做什么 | 前提 | 观察多久 |
|
||
|---|---|---|---|
|
||
| 零,进行中 | 合议分流、增持门、转空离场、策略层两道离场、解锁重问都开着。不再开任何新开关 | 无 | 到 09-16 收盘,三个交易日 |
|
||
| 一 | 09-17 用复核脚本做台账 006 到 009 的第一次复核。同时复核解锁重问,台账 001 已满三天 | 观察读数包已部署 | 一次 |
|
||
| 二 | 决策系统的强势扫描开观察档,只记不派 | 第一段复核无异常。动决策系统要先答三题并经审批 | 两个交易日 |
|
||
| 三 | 强势扫描真派单 | 第二段读数正常 | 三个交易日 |
|
||
| 四 | 资金流分发半开 | 必须单独一段 | 两个交易日 |
|
||
| 五 | 资金流分发全开 | 第四段全绿,且当日兜底卖出恒为零 | 两个交易日 |
|
||
| 六,候选 | 模拟仓新建仓自主档从 propose_only 提到 full | 合议链路两轮复核无系统性偏差。要拍板 | 三个交易日 |
|
||
|
||
**策略层那件事。** 如果总开关是有意打开的,今天 09:40 那一跳就是 SAR 止损线刷新与弱基本面紧止盈挂载的第一次实弹。今天盘后要看那一跳的摘要,命令在第六节。如果不是有意的,今天就关掉,等合议观察期过了再单独开一段。
|
||
|
||
### 选股打分包(另一仓库,单独审批)
|
||
|
||
按方案第五节工作包四执行,不改设计。质地好加 8 分,差减 8 分,在同一传导档内重排,不跨档。环境变量设为零即关。台账记到选股系统第 058 条。细节见附录戊。
|
||
|
||
### 真实仓准备包(准备件现在做,执行等 QMT 侧)
|
||
|
||
1. 一份真实仓初始参数清单,写进台账。
|
||
2. 一个自检脚本 `scripts/real_init_params.py`,只读比对当前值与清单,有偏差就报。表名前缀不是 real_ 时拒绝执行。
|
||
3. 一份追平差异清单,列清 188 落后的表、调度位、参数。
|
||
|
||
细节见附录己与附录庚。
|
||
|
||
### 文档包
|
||
|
||
1. README 第 173 到 207 行关于影子模式的过时说法改掉。改成「下发模式由参数决定,页面顶部横幅为准」,并写清模拟仓与真实仓各自现在是什么模式。
|
||
2. CLAUDE.md 入库。
|
||
3. 方案文档第六节加一句标注。PMS_CONSENSUS_WEAK_CONFIRM 在加固包登记,三个盘中确认参数在盘中确认包登记。
|
||
4. 台账追加 012 盘中确认阈值、013 观察读数与复核口径、014 真实仓初始参数清单。
|
||
5. 开发节点记录按五段式追加。
|
||
6. 接口契约文档补单票研究面接口的返回结构。
|
||
|
||
## 四、顺序与时间
|
||
|
||
按交易日排。部署一律收盘后,先经审批,看容器内时间判盘中盘后。
|
||
|
||
| 交易日 | 做什么 |
|
||
|---|---|
|
||
| 09-14 到 09-16 | 合议链路第一轮观察。期间只做不改行为的活:观察读数包、加固包、文档包。观察读数包要重建容器,安排在 09-14 或 09-15 收盘后 |
|
||
| 09-17 | 用复核脚本做台账 006 到 009 与 001 的第一次复核。决定要不要调阈值,要调先回台账 |
|
||
| 09-17 收盘后 | 部署盘中确认包与页面收尾包 |
|
||
| 09-18 到 09-22 | 盘中确认观察三个交易日。同时启动分段启用包第二段 |
|
||
| 09-23 | 盘中确认第一次复核,台账 012 |
|
||
| 等审批 | 选股打分包 |
|
||
| 等 QMT 侧 | 真实仓准备包的执行部分 |
|
||
|
||
## 五、开关与参数
|
||
|
||
全部经参数中心读,页面可改即时生效。每个键都有真实读取处,否则死参数扫描会红。
|
||
|
||
| 键 | 默认 | 属于 | 说明 |
|
||
|---|---|---|---|
|
||
| PMS_CONSENSUS_STAT_TIMES | 0935,1030,1330,1445 | 观察读数包 | 落表的检查点,四位时刻用逗号分隔。设为空串即不写检查点行,只写转空实弹行 |
|
||
| PMS_TECH_INTRADAY_CONFIRM | True | 盘中确认包 | 盘中确认总闸。关掉两条规则都不走,行为逐字如旧 |
|
||
| PMS_TECH_INTRADAY_BREAKOUT | True | 盘中确认包 | 收口突破规则的开关。关掉只剩开口确认规则 |
|
||
| PMS_TECH_VOL_CONFIRM | 1.5 | 盘中确认包 | 时段折算量比阈值。与解锁重问的 PMS_OPEN_REASK_VOL_MIN 同值同义 |
|
||
| PMS_TECH_INTRADAY_WINDOW | 0945-1430 | 盘中确认包 | 确认时段。与解锁重问的时段同义 |
|
||
| PMS_CONSENSUS_WEAK_CONFIRM | True | 加固包 | 只有一方表态时交人。关掉则放行 |
|
||
|
||
## 六、验证方式
|
||
|
||
每条命令标明在哪台机器上运行。一个命令块只放一台机器的命令。
|
||
|
||
### 观察读数包
|
||
|
||
**开发机。** 预期最后一行 ALL SUITES PASS。第二十四批那条时钟用例在加固包修掉之前,要在 09:36 之后跑。
|
||
|
||
```bash
|
||
cd /Users/baobao/Documents/work/project/tradingSystem && /private/tmp/claude-501/-Users-baobao-Documents-work-project-tradingSystem/f7c4a696-e3d8-4465-961a-04f82eb3e424/scratchpad/venv/bin/python scripts/run_tests.py
|
||
```
|
||
|
||
**模拟仓 155,收盘后,先经审批。** 预期 make test 最后一行 ALL SUITES PASS,建表输出 21 张表,其中有 pms_consensus_stat。
|
||
|
||
```bash
|
||
cd /home/factor/project/tradingSystem && git pull --ff-only && make deploy && make test
|
||
```
|
||
|
||
**模拟仓 155,下一个交易日 09:37 之后。** 预期打出当天的表:相关票数、无读数占比、等开口只数、跳过原因分布、增持门拦截次数、转空离场条数。第一天转空离场应为零。
|
||
|
||
```bash
|
||
cd /home/factor/project/tradingSystem && make consensus-review DAYS=1
|
||
```
|
||
|
||
### 盘中确认包
|
||
|
||
**模拟仓 155,交易日 09:45 到 14:30 之间,只读试算。** 预期跳过项里出现处置词 wait_confirm,或者出现「盘中收口突破」的候选。两种至少见到一种。若当天没有收口等待或开口向上的候选,就看不到,改天再看。
|
||
|
||
```bash
|
||
cd /home/factor/project/tradingSystem && docker compose run --rm --no-deps pms-web python -c "from app.services import proposal_service as p; import json; d=p.scan_and_route(dry_run=True); print(json.dumps([s for s in d.get('skipped',[]) if s.get('disp') in ('wait_confirm','wait_tech') or '盘中' in str(s.get('why'))], ensure_ascii=False)[:1500])"
|
||
```
|
||
|
||
**模拟仓 155,任意时间。** 预期四个参数都在快照里,且带范围。
|
||
|
||
```bash
|
||
cd /home/factor/project/tradingSystem && docker exec pms-web python -c "from app.services import param_store as ps; print({k: ps.get(k, None) for k in ('PMS_TECH_INTRADAY_CONFIRM','PMS_TECH_INTRADAY_BREAKOUT','PMS_TECH_VOL_CONFIRM','PMS_TECH_INTRADAY_WINDOW')})"
|
||
```
|
||
|
||
### 页面收尾包
|
||
|
||
**开发机。** 预期两道页面守卫都打 ALL OK。
|
||
|
||
```bash
|
||
cd /Users/baobao/Documents/work/project/tradingSystem && python3 scripts/test_page_wiring_guard.py && python3 scripts/test_page_enum_guard.py
|
||
```
|
||
|
||
**页面判收,模拟仓 155 部署后。** 点任一持仓,抽屉第一节标题是「研究面 · 三源合议」,有基本面、技术面、择时、合议四枚芯片。候选栏每行有质地与技术两枚芯片。管理视图持仓总览多一列研究面。
|
||
|
||
### 加固包
|
||
|
||
**开发机。** 预期第三十批与第二十八批新增用例全部通过,且第二十四批在任何时刻跑都通过。
|
||
|
||
```bash
|
||
cd /Users/baobao/Documents/work/project/tradingSystem && /private/tmp/claude-501/-Users-baobao-Documents-work-project-tradingSystem/f7c4a696-e3d8-4465-961a-04f82eb3e424/scratchpad/venv/bin/python scripts/test_batch30_units.py && /private/tmp/claude-501/-Users-baobao-Documents-work-project-tradingSystem/f7c4a696-e3d8-4465-961a-04f82eb3e424/scratchpad/venv/bin/python scripts/test_batch28_units.py && /private/tmp/claude-501/-Users-baobao-Documents-work-project-tradingSystem/f7c4a696-e3d8-4465-961a-04f82eb3e424/scratchpad/venv/bin/python scripts/test_batch24_units.py
|
||
```
|
||
|
||
### 分段启用包
|
||
|
||
**模拟仓 155,今天 09:40 之后,看策略层那一跳。** 预期摘要里的时刻是今天 09:4x,没有 error 字样。若策略层是有意打开的,这就是第一次实弹的读数。
|
||
|
||
```bash
|
||
cd /home/factor/project/tradingSystem && docker exec pms-web python -c "from app.services import param_store as ps; print((ps.get('PMS_AUTO_LAST_SCAN','') or '')[:1200])"
|
||
```
|
||
|
||
**模拟仓 155,任意时间,解锁重问的三天读数。** 预期打印当日被驳回的票数与逐只解锁判定。每天解锁一到五次是正常,零次说明太紧,超过八次说明太松。
|
||
|
||
```bash
|
||
cd /home/factor/project/tradingSystem && docker compose run --rm --no-deps pms-web python -c "from datetime import datetime; from app.services import proposal_service as ps, reask_service as rs; jk = ps._judge_rejected_open_keys(); print('当日被研判驳回:', len(jk), '只'); print('解锁:', rs.evaluate_all(jk, datetime.now()) or '(无)')"
|
||
```
|
||
|
||
### 选股打分包
|
||
|
||
**模拟仓 155,改之前先记基线。** 预期打印主榜前五十名里质地好的只数。今天的基线是前一百名里六只。
|
||
|
||
```bash
|
||
curl -s "http://192.168.16.155:8300/plan?top=50" | python3 -c "import sys,json; d=json.load(sys.stdin); rows=d.get('main') or []; print('前50质地好:', sum(1 for r in rows if (r.get('company_review') or {}).get('overall')=='好'), '/', len(rows))"
|
||
```
|
||
|
||
**模拟仓 155,重启桥容器后,避开 07:10,先经审批。** 预期同一条命令的读数上升,且每一行的 rank 连续。
|
||
|
||
### 真实仓准备包
|
||
|
||
**真实仓 188,只读,现在就能做。** 预期打印 51bd6dc 附近的提交与两个容器。这一步只是确认起点,不动任何东西。
|
||
|
||
```bash
|
||
cd /mnt/work/project/tradingSystem && git log -1 --format='%h %ad %s' --date=iso && docker ps --format '{{.Names}}\t{{.Status}}' | grep pms
|
||
```
|
||
|
||
**真实仓 188,追平部署之后,先经审批。** 预期打印表名前缀 real_ 与一张对照表,每一行都是「符合」。任何一行「偏差」都不许进阶段 B。
|
||
|
||
```bash
|
||
cd /mnt/work/project/tradingSystem && docker compose run --rm --no-deps pms-web python scripts/real_init_params.py --check
|
||
```
|
||
|
||
## 七、回退
|
||
|
||
每个工作包独立回退,互不牵连。
|
||
|
||
| 工作包 | 回退方式 | 要不要重启 |
|
||
|---|---|---|
|
||
| 观察读数包 | 页面把 PMS_CONSENSUS_STAT_TIMES 设为空串。要彻底撤,回滚提交再部署。表留着不删 | 改参数不用;回滚要重建容器 |
|
||
| 盘中确认包 | 页面把 PMS_TECH_INTRADAY_CONFIRM 设为关,行为逐字回旧 | 不用 |
|
||
| 页面收尾包 | 回滚提交再部署 | 要重建容器 |
|
||
| 加固包 | PMS_CONSENSUS_WEAK_CONFIRM 默认开就是旧行为。其余三处回滚提交 | 回滚要重建容器 |
|
||
| 分段启用包 | 每一段把对应开关改回去。决策系统侧的开关改环境文件后重建那一个容器 | 持仓管理系统侧不用 |
|
||
| 选股打分包 | 环境变量把加分设为零,或回滚提交,重启桥容器 | 要重启桥容器 |
|
||
| 真实仓准备包 | 自检脚本只读,无需回退 | 不用 |
|
||
|
||
## 八、拍板点
|
||
|
||
这八条要用户拍板,拍板前对应的活不动。
|
||
|
||
1. 策略层总开关现在是开的,是不是有意的。若不是,今天就关。
|
||
2. 盘中确认里,开口向上的候选在 09:45 之前与 14:30 之后进观察。这个读法认不认。
|
||
3. 策略票的网格买入腿,技术面看空时要不要也停。方案没写,现在不停。
|
||
4. 选股打分包动 akg-factor-bridge 仓库,批不批。
|
||
5. README 影子模式的过时说法按文档包第 1 条改,认不认。
|
||
6. 检查点默认四个时刻,认不认。多了写库多,少了读数粗。
|
||
7. 观察读数表用新表而不是运行参数承载。新表要改 DDL 表数哨兵。认不认。
|
||
8. 分段启用包第六段,新建仓自主档提到 full 的时机,等两轮复核后再议。
|
||
|
||
## 九、交付要求
|
||
|
||
给开发者的硬要求,人和大模型一样。
|
||
|
||
1. 每个工作包一个提交。提交信息用短中文说行为,带台账号。
|
||
2. 先写「开关关掉逐字回旧」的单测,再改代码。开关关掉时,输出的字典要用 JSON 序列化后逐字节相等。
|
||
3. 新批次同时登记进 `scripts/run_tests.py` 的 SUITES 清单与例数表。哨兵按附录辛逐条过一遍。
|
||
4. 开发机全量绿之后,才在模拟仓 155 收盘后部署。部署要重建容器,先经审批。判收命令在第六节,判收读数记进开发节点记录的五段式节点。
|
||
5. 不动真实仓 188。真实仓准备包的执行部分等 QMT 侧就绪后另开一轮。
|
||
6. 服务器上只做 git pull,不跑 git stash。
|
||
7. 判盘中盘后看容器内时间,不看宿主时间。宿主是世界协调时。
|
||
8. 业务参数一律经参数中心读。密钥只从 .env 注入。
|
||
9. 一条 SQL 只碰一张表。要联的数据在服务层分两次查再在内存里拼。
|
||
|
||
---
|
||
|
||
## 附录甲(可不读):观察读数包的表、标签与落表规则
|
||
|
||
### 表
|
||
|
||
新表名 pms_consensus_stat,加进 `ddl_pms_v1.sql`,是第 21 张表。
|
||
|
||
```sql
|
||
CREATE TABLE IF NOT EXISTS pms_consensus_stat (
|
||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||
stat_date INT NOT NULL, -- 北京日期 yyyymmdd
|
||
ts_code VARCHAR(16) NOT NULL, -- 代码; 全局行用 *
|
||
kind VARCHAR(24) NOT NULL, -- 类别, 见下表
|
||
reason VARCHAR(255) NULL, -- 一句原因, 取跳过原因原文截断
|
||
detail TEXT NULL, -- JSON: 三票 / 方向 / 强弱 / 相位 / 路由 / 盘中确认
|
||
first_at DATETIME NOT NULL, -- 北京时间, 首次记到
|
||
last_at DATETIME NOT NULL, -- 北京时间, 最近记到
|
||
rounds INT NOT NULL DEFAULT 1, -- 记到的次数
|
||
UNIQUE KEY uk_day_code_kind (stat_date, ts_code, kind),
|
||
KEY idx_day_kind (stat_date, kind)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||
```
|
||
|
||
### 类别
|
||
|
||
| kind | 含义 | 来源 |
|
||
|---|---|---|
|
||
| open_skip_fund | 新建仓因没有买方评析跳过 | 合议路由为跳过,原因是没有买方评析 |
|
||
| open_skip_bear | 新建仓因方向看空跳过 | 合议路由为跳过,其余原因 |
|
||
| open_wait_tech | 等技术面开口或转向 | 合议路由为观察 |
|
||
| open_wait_confirm | 等盘中确认 | 盘中确认包 |
|
||
| open_breakout | 盘中收口突破视为开口 | 盘中确认包 |
|
||
| open_confirm | 合议交人 | 合议路由为交人 |
|
||
| open_pass | 合议放行 | 合议路由为放行 |
|
||
| gate_block | 增持门拦下 | 持仓扫描的跳过项,detail 里记 fill、add、dca 三者之一 |
|
||
| tech_exit | 转空离场实弹,执行或入队 | 扫描后真处理过的集合 |
|
||
| tech_noread | 相关票没有技术面读数 | 映射重建时相关票减去有状态的票 |
|
||
| fund_noread | 基本面无读数 | 装配结果 |
|
||
| timing_noread | 择时无读数 | 装配结果 |
|
||
| map_cover | 映射覆盖只数,ts_code 为 * | 映射重建时,detail 记 codes 与 states 两个数 |
|
||
|
||
### 打标签
|
||
|
||
在 `app/core/action_engine.py` 里,合议分流与增持门产生的跳过项加一个 tag 键,值就是上表的 kind。只在 consensus_on 或 cblocks 为真的分支里加。开关关掉时这些分支一行不执行,所以 tag 键不会出现,逐字回旧成立。
|
||
|
||
增持门的跳过项 detail 里带 gate_kind,取值 fill、add、dca。
|
||
|
||
### 装配时留一份紧凑记录
|
||
|
||
`proposal_service._attach_consensus` 每装配一只候选,往 out["consensus_seen"] 追加一条紧凑记录:ts_code、fund、tech、timing、direction、route、phase。这份记录给落表用,也给候选处置快照用。
|
||
|
||
### 落表
|
||
|
||
新服务 `app/services/consensus_stats.py`,一个入口函数 record_round(out, scanned, params, now)。
|
||
|
||
1. 从 out["consensus_seen"] 生成 open_* 三类无读数行与 open_pass、open_confirm 行。
|
||
2. 从 out["skipped"] 里带 tag 的项生成 open_skip_*、open_wait_*、gate_block 行。
|
||
3. 从 scanned["candidates"] 里来源是 tech_exit 且没被闸拒的项生成 tech_exit 行。
|
||
4. 检查点判断:now 的时分在 PMS_CONSENSUS_STAT_TIMES 任一时刻或它的下一分钟之内才写第 1、2 类。tech_exit 行任何时候都写。dry_run 一律不写。
|
||
5. 写失败只记警告,返回 ok 为假,不影响扫描。这个函数登记进第十批 SOFT_FAIL 名单。
|
||
|
||
调用点在 `proposal_service.scan_and_route` 末尾,去重集写回之后。
|
||
|
||
`tech_service.build_map` 在写映射之后,写 tech_noread 行与 map_cover 行。失败只记日志。
|
||
|
||
### 仓库
|
||
|
||
新文件 `app/repo/consensus_stat_repo.py`,三个函数,每个只碰这一张表。
|
||
|
||
1. upsert_many(rows)。用 INSERT 加 ON DUPLICATE KEY UPDATE。更新子句用 VALUES(列) 引用插入值,rounds 写成 rounds 加一。绝不在更新子句里放绑定参数,那是 09-11 真机踩过的坑。
|
||
2. list_range(date_from, date_to, kinds=None)。
|
||
3. count_by_kind(date_from, date_to)。返回按日期与类别的计数字典。
|
||
|
||
### 复核脚本
|
||
|
||
`scripts/consensus_review.py --days N`,默认 3。打印四张表。
|
||
|
||
1. 逐日:相关票数、技术面无读数占比、基本面无读数只数、择时无读数只数。占比用 map_cover 行算。
|
||
2. 逐日:等开口只数、等盘中确认只数、跳过原因分布、交人只数、放行只数、增持门拦截次数。
|
||
3. 转空离场逐条:日期、代码、确认与否、数量。
|
||
4. 合议方向与人工裁决的比对:从提议表取这几天带合议六键且已被人裁决的提议。合议看多而人驳回,或合议交人而人采纳,逐只列出。终态的名字用提议服务里现有的枚举,不另造。
|
||
|
||
Makefile 加目标 consensus-review,接受 DAYS 变量,默认 3。
|
||
|
||
### 日报
|
||
|
||
`ledger_service.build_daily_report` 加一节 consensus,内容是当天按类别的计数。取不到就写空,不拖垮日报。
|
||
|
||
## 附录乙(可不读):盘中确认包的判定函数与接线位置
|
||
|
||
### 纯函数
|
||
|
||
加在 `app/core/tech_rules.py`。
|
||
|
||
```python
|
||
def intraday_confirm(state, *, price, vwap, upper_prev, vol_ratio, now,
|
||
window="0945-1430", vol_min=1.5, breakout_on=True) -> dict:
|
||
"""返回 {"state": 新技术面块或原块, "changed": bool,
|
||
"kind": None | "breakout" | "opened_ok" | "opened_wait" | "outside_window",
|
||
"why": str, "reads": {"price", "vwap", "upper_prev", "vol_ratio", "at"}}"""
|
||
```
|
||
|
||
判定次序如下。
|
||
|
||
1. 相位不是收口等待也不是开口向上,原样返回,kind 为空。
|
||
2. 不在时段内。相位是开口向上,返回 outside_window。相位是收口等待,原样返回。
|
||
3. 相位是收口等待。breakout_on 为真,且 price、upper_prev、vol_ratio 三个都有值,且 price 大于 upper_prev,且 vol_ratio 不低于 vol_min,返回 breakout。新块的立场是看多,强弱是强,相位是「盘中开口向上」。任何一项不满足,原样返回。
|
||
4. 相位是开口向上。price、vwap、vol_ratio 三个都有值,且 price 不低于 vwap,且 vol_ratio 不低于 vol_min,返回 opened_ok,块不变。任何一项取不到或不满足,返回 opened_wait。取不到按等待处理而不是放行,因为这是入场的门,方向要保守。
|
||
|
||
时段判断复用 `app/core/reask_rules.py` 的 in_window。量比由调用方算,用 reask_rules.vol_ratio。单测要钉住是同一个函数对象,这是台账 003 三处同源的哨兵。
|
||
|
||
### 映射多带一个值
|
||
|
||
`tech_rules.synthesize` 的 base 加 boll_upper。`tech_service._compact` 加 boll_upper。收口突破要拿昨日上轨,从映射里取,不再回库。
|
||
|
||
### 接线
|
||
|
||
在 `proposal_service._attach_consensus` 里,每只候选装配完四块之后加一段。开关 PMS_TECH_INTRADAY_CONFIRM 关掉时整段不执行。
|
||
|
||
1. 相位不在收口等待与开口向上之内,跳过。
|
||
2. 取读数:price 与 vwap 来自 market.day_snapshot,vol_ratio 用与 reask_service 相同的算法,upper_prev 来自技术面块的 boll_upper。本轮用一个字典缓存,同一只票不取两次。任何取数失败按取不到,传 None。
|
||
3. 调 intraday_confirm。
|
||
4. 结果是 breakout:把新块写回 blocks["tech"],用新立场重新调 consensus.decide,更新 blocks["consensus"]、c["consensus"]、硬数字六键。硬数字的 tech 块里加 intraday 一键记 reads 与 kind。
|
||
5. 结果是 opened_wait 或 outside_window:把 c["consensus"]["route"] 改成观察,route_reason 写 why,另加 disp 键为 wait_confirm。
|
||
6. 结果是 opened_ok:只在硬数字的 tech 块里记 intraday。
|
||
|
||
`_scan_open` 与 `_attach_consensus` 都要多接一个 now 参数,从 scan_and_route 传下来。
|
||
|
||
### 处置词
|
||
|
||
`action_engine` 加常量 DISP_WAIT_CONFIRM 为 wait_confirm。scan_open 里路由为观察时,con 带 disp 就用它,否则用 wait_tech。
|
||
|
||
页面 dispOf 加一行:wait_confirm 显示「等盘中确认」,样式与在盯那一档相同。页面文案守卫若登记了处置词枚举,补这一项。
|
||
|
||
### 参数登记
|
||
|
||
四个参数登记进 param_store 的 RUNTIME_EXTRA 与范围表。PMS_TECH_VOL_CONFIRM 范围 0.5 到 10。PMS_TECH_INTRADAY_WINDOW 的校验照 PMS_OPEN_REASK_WINDOW 的写法。
|
||
|
||
### 观察读数
|
||
|
||
open_breakout 每天零到三只。open_wait_confirm 每天零到十只。突破超过五只说明太松。这两条写进台账 012。
|
||
|
||
## 附录丙(可不读):页面收尾包的接口字段
|
||
|
||
### 单票研究面接口
|
||
|
||
`GET /api/research/{ts_code}` 的返回结构改成六块。
|
||
|
||
| 键 | 内容 | 来源 |
|
||
|---|---|---|
|
||
| company | 质地档、估值、十视角计数、三类、硬疑点、报告日龄、报告链接、评析摘要 | 持仓票从逻辑状态映射取 company_review。候选票从当日计划的主榜与观察档取。都没有就是空 |
|
||
| fund | fund_rules 的结果块 | 用 company 算 |
|
||
| tech | 现有的技术面块 | 不变 |
|
||
| timing | 立场、昨夜定性、结论日期、盘中转多时刻 | consensus_service.nightly_map 取一只。转多时刻点击时不回扫,留空 |
|
||
| consensus | consensus.decide 的结果 | 用上面三票算 |
|
||
| sources | 每一路的状态:ok、无读数、或错误文字 | 逐路标 |
|
||
|
||
页面单票抽屉那一节标题改成「研究面 · 三源合议」。四枚芯片依次是基本面、技术面、择时、合议。每枚芯片悬停显示一句理由。芯片下面保留现有的三个指标块。有报告链接就显示「评析报告」。
|
||
|
||
### 候选栏
|
||
|
||
候选处置快照的每行加三小块:fund 带立场与质地档,tech 带立场与相位,consensus 带方向与路由。数据从 out["consensus_seen"] 来。页面每行加两枚芯片,颜色沿用 techStanceCls 与 propCompanyTag。
|
||
|
||
### 管理视图持仓总览
|
||
|
||
加一列研究面,内容与我的持仓那一列相同,用同一个渲染函数。
|
||
|
||
## 附录丁(可不读):加固包的改动点
|
||
|
||
### 去重集清除条件
|
||
|
||
`app/services/proposal_service.py` 第 150 到 154 行,把「SAR 方向是空才保留」改成「SAR 方向明确是多才清除」。
|
||
|
||
```python
|
||
params["tech_exit_done"] = {c for c in _done
|
||
if (_tech_states.get(c) or {}).get("sar_side") != "多"}
|
||
```
|
||
|
||
第三十批加三例。映射里没有这只票则保留。明确为多则清除。明确为空则保留。
|
||
|
||
### 持仓行的转多留痕
|
||
|
||
decorate_positions 的 flip_map 由调用方传入。来源与候选相同,就是信号消化写在候选行上的当日转多时刻。持仓行没有这个字段时,按持仓代码从同一来源取。第二十八批加一例:持仓行昨夜中性、当日转多,择时票升为看多。
|
||
|
||
### 弱表态开关
|
||
|
||
consensus.decide 加参数 weak_confirm,默认真。_route 里「只有一方表态」那一行,weak_confirm 为真返回交人,为假返回放行。consensus_service._params 读 PMS_CONSENSUS_WEAK_CONFIRM 并传入。第二十八批加两例:开着交人,关着放行。
|
||
|
||
### 第二十四批用例
|
||
|
||
把 `_today_ms(9, 35)` 改成「当前时刻减十分钟」。断言里的时刻字符串从那个时间戳算,不写死 09:35。
|
||
|
||
## 附录戊(可不读):选股打分包的规格
|
||
|
||
仓库是 akg-factor-bridge,文件是 `plan.py`。
|
||
|
||
1. 装配阶段已经读到评析字典。对主榜与观察档的每一行算质地调整分:质地好加 8,差减 8,其余 0。
|
||
2. 分数编码是主榜等于 200 加传导档位乘 20 加组内分,组内分夹在正负 9.9 之间。加 8 后最大 17.9,仍小于档步长 20,先档后分的次序不破。
|
||
3. 主榜与观察档按调整分重排并重编名次。原分数保留在 score 字段供档位解码。新字段 score_adj 进接口与快照。
|
||
4. 不动因子表。不在每早 07:10 的因子构建里读数据基座库。判决收敛仍只降不升。
|
||
5. 环境变量 PLAN_QUALITY_BONUS,默认 8,设为 0 即关。
|
||
6. 新测试文件 test_plan_quality_rank.py,守四条不变式。加分从不跨档。加分为 0 时次序与原来逐字相同。重编后名次连续。快照带 score_adj。
|
||
7. 台账记到选股系统第 058 条。
|
||
8. 部署:代码与自测本地做完并提交。155 上拉代码后重启桥容器,先经审批,避开 07:10。
|
||
|
||
顺带守一条既有不变式:POOL_TOP 不低于 PMS_PLAN_TOP_N。决策系统的夜间分析池从这份排名取前 50,质地进了排序,好公司才进得了分析池,择时那一票的覆盖才会上来。
|
||
|
||
## 附录己(可不读):真实仓初始参数清单与自检脚本
|
||
|
||
### 清单
|
||
|
||
进阶段 B 之前必须是这些值。写进台账 014。
|
||
|
||
| 键 | 值 | 为什么 |
|
||
|---|---|---|
|
||
| PMS_DISPATCH_MODE | shadow | 影子期先不写下游 |
|
||
| PMS_AUTONOMY | propose_only | 持仓自主动作交人 |
|
||
| PMS_OPEN_AUTONOMY | off | 新建仓关 |
|
||
| PMS_TECH_EXIT_AUTONOMY | propose_only | 转空离场交人,不自动卖 |
|
||
| PMS_STRATEGY_ENABLED | false | 策略层关 |
|
||
| PMS_LOGIC_DOUBT_TRIM | false | 研究走弱减持关 |
|
||
| PMS_OPEN_REASK_ENABLED | false | 新建仓关着时无意义,明确关掉免误读 |
|
||
| PMS_CONSENSUS_ROUTE | true | 合议只拦不放,开着更保守 |
|
||
| PMS_TECH_GATE_INCREASE | true | 增持门只拦不放 |
|
||
| PMS_PLAN_RANK_BY_QUALITY | true | 排序无副作用 |
|
||
| PMS_TECH_ENABLED | true | 前提是接口根地址指向 188 的决策系统 |
|
||
| PMS_FUND_REQUIRED | true | 无评析不建仓 |
|
||
| PMS_TOTAL_SCALE | 按真实资金 | 与账户实际资金要对得上 |
|
||
|
||
### 脚本
|
||
|
||
`scripts/real_init_params.py`。
|
||
|
||
1. --check 只读。打印表名前缀,再打印一张对照表:键、期望值、当前值、符合或偏差。有偏差退出码为 1。
|
||
2. --apply 写入,必须同时带 --yes。写之前再打印一遍对照表。
|
||
3. 表名前缀不是 real_ 时拒绝执行,除非带 --allow-sim。这是防止在模拟仓上误跑。
|
||
4. Makefile 加目标 real-params-check。
|
||
|
||
单测三例。对照表算对。前缀为空时拒绝。有偏差时退出码为 1。
|
||
|
||
## 附录庚(可不读):真实仓 188 追平差异清单
|
||
|
||
按开发机上 51bd6dc 到 969d189 的差异统计。
|
||
|
||
| 项目 | 差异 |
|
||
|---|---|
|
||
| 提交 | 落后 69 个 |
|
||
| 表 | 多两张:pms_nav_daily、pms_tech_daily。观察读数包之后再多一张 pms_consensus_stat |
|
||
| 调度位 | 多两个:06:30 tech_pull、15:20 nav_snapshot。188 阶段 A 不起调度器,暂不生效 |
|
||
| 参数 | 多四十多个键。默认值按模拟仓定,见附录己的清单 |
|
||
| 页面 | 登录与两角色不变。提议卡重构、研究面、合议行都是新的 |
|
||
| 接口 | 多技术面状态、手动拉取、单票研究面、按代码回扫信号四个 |
|
||
|
||
追平步骤,全部先经审批。
|
||
|
||
1. 按真实仓部署方案阶段 A 把 ws 协议判收完。
|
||
2. 在 188 拉代码到最新。
|
||
3. 用 ws 剖面重建容器,建表自动带 real_ 前缀。输出必须出现「表名前缀 real_ 生效」。
|
||
4. 跑 real_init_params.py --check,全部符合才继续。
|
||
5. 按真实仓部署方案阶段 B 进影子期。
|
||
|
||
## 附录辛(可不读):哨兵同步与登记清单
|
||
|
||
改了对应的东西就得回到这里改断言,断言不动就是漏了。
|
||
|
||
| 哨兵 | 位置 | 本阶段要改什么 |
|
||
|---|---|---|
|
||
| DDL 表数 | scripts/test_batch6_units.py 约第 593 行 | 20 改 21 |
|
||
| 批次登记 | scripts/run_tests.py 的 SUITES 与例数表 | 加第三十一、三十二、三十三批,改总数 |
|
||
| 软失败函数 | scripts/test_batch10_units.py 顶部 SOFT_FAIL | 加 consensus_stats.record_round |
|
||
| 死参数名单 | scripts/test_batch10_units.py 的 KNOWN_DEAD | 不变。六个新参数都要有读取处 |
|
||
| 桩签名比对 | scripts/test_batch10_units.py 用例 M1 | 不改 pms_repo 签名就不用动。新仓库是独立文件 |
|
||
| 路由清单 | scripts/test_wiring.py 的 need 列表 | 不加新路由就不动 |
|
||
| 页面枚举名单 | scripts/test_page_enum_guard.py 的 ENUM_FIELDS | 处置词若在名单里,加 wait_confirm |
|
||
| 动作求值器次序 | scripts/test_batch12_units.py | 不变 |
|
||
| 密钥名单 | 两处 | 不变 |
|
||
|
||
新批次与例数估计。
|
||
|
||
| 批次 | 内容 | 例数 |
|
||
|---|---|---|
|
||
| 第三十一批 | 观察读数包:标签只在开关开着时出现;四种路由各打对应标签;增持门三种拦截打标签;归类落表;检查点窗口;转空实弹随时写;试算不写;upsert 用 VALUES 列;单表;映射重建记无读数与覆盖;复核脚本聚合;合议与人工裁决比对;参数登记与校验;日报小节失败不拖垮 | 约 14 |
|
||
| 第三十二批 | 盘中确认包:时段边界四点;收口突破要价与量同时满足;开口确认要均价与量;取不到按等待;突破开关关掉不升;总闸关掉时候选的合议块 JSON 逐字相同;接线后路由从观察变放行;开口未确认进观察带处置词;硬数字带 intraday;量比同源哨兵;映射带上轨;参数登记与范围 | 约 16 |
|
||
| 第三十三批 | 页面收尾包:研究面接口持仓票、候选票、都没有三情形;来源逐路标明;处置快照带三小块;页面守卫 | 约 6 |
|
||
| 第三十批加 | 去重集三例 | 3 |
|
||
| 第二十八批加 | 转多留痕一例、弱表态开关两例 | 3 |
|
||
| 第二十四批改 | 时钟用例改相对时刻 | 0 |
|
||
|
||
合计新增约四十二例,总数约 862。以实跑为准,例数表按实跑校正。
|