From a52b967b092c200ed85d39d7b8cf909a2e7bd8e5 Mon Sep 17 00:00:00 2001 From: zlt Date: Fri, 31 Jul 2026 10:08:26 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=B6=E6=AE=B5=E6=94=B6=E5=B0=BE:=20?= =?UTF-8?q?=E5=9B=BA=E5=8C=96=E5=AE=81=E7=BC=BA=E6=AF=8B=E6=BB=A5=E7=BA=AA?= =?UTF-8?q?=E5=BE=8B;=20=E8=AE=B0=E5=BD=95=E5=90=8Cdate=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E4=B8=8D=E5=B9=82=E7=AD=89=E7=9A=84=E8=A7=82=E5=AF=9F;=20READM?= =?UTF-8?q?E=E4=B8=8B=E4=B8=80=E6=AD=A5=E8=A1=A8=E9=87=8D=E6=8E=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 30 +++++++++++++++--------- UPSTREAM_PLAN_API.md | 56 ++++++++++++++++++++++++++++++++++++++++++++ config/settings.py | 3 +++ 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 64e61ac..91016e2 100644 --- a/README.md +++ b/README.md @@ -205,17 +205,25 @@ QMT ──trade/order_update──▶ pms-ws ──落 pms_qmt_inbox──▶ | # | 事项 | 状态 | |---|---|---| -| 1 | ~~ws 通道的账本侧改造(清单 4~6)~~ | ✅ 2026-07-29 完成 | -| 2 | **ws 通道联调**(协议 §9 的 S1/S2/S3) | 密钥已交换,可开工 | -| 2.5 | 部署便利性:`make deploy` 一句话完成 build + up + 各 profile | 待办(每次改动要敲 4 条命令太烦) | -| 2.6 | **行业硬拦截开闸**:跑一次「强刷 + 灌行业映射」把 `theme` 灌进 `pms_industry_map`,再把 `PMS_SECTOR_SOURCE` 改成 `custom_table` | 可做(数据源已就位,只差一次刷新 + 一个参数) | -| 2.7 | ~~主榜取全量~~ | ✅ 2026-07-30:拿到上游 `api.py`,`top`/`obs_top`/`theme_cap` 都是请求参数,已做成 PMS 三个显式参数;主题分散改由 `PMS_PLAN_THEME_CAP_LOCAL` 在候选阶段做 | -| 2.8 | 上游计划的剩余待确认口径(5 条) | 阻塞:等上游答复,见 `UPSTREAM_PLAN_API.md` §4 | -| 3 | T0 做T(二期) | 可做,设计已有,无外部依赖 | -| 4 | 择时实现 A(委托决策系统盘中择时) | 阻塞:等 bionic 侧接口 | -| 5 | 研判闸接通 | 阻塞:等 bionic 侧 `process_intraday_audit` 新增 PMS 请求 direction。客户端已就位,接口好了在页面填 `PMS_JUDGE_API_BASE` 即通 | -| 6 | bionic 侧配套改造(出口改道 + PMS direction) | 另一仓库 | -| 7 | `trading_buy_plan` 退场:PMS 已不读它(`PMS_CANDIDATE_SOURCE=plan_api`),确认无其他消费方后上游可停写 | 待上游确认(`UPSTREAM_PLAN_API.md` Q10) | +| 1 | ~~ws 通道的账本侧改造(清单 4~6)~~ | ✅ 2026-07-29 | +| 2 | ~~上游选股计划接入(`/plan`)~~ | ✅ 2026-07-31:候选池独占来源、交易日龄硬校验、盘前昨收兜底、ST 剔除、PMS 侧主题限额、页面抽屉与探活脚本。口径与实测记录见 `UPSTREAM_PLAN_API.md` | +| 3 | ~~行业硬拦截开闸~~ | ✅ 2026-07-31:`PMS_SECTOR_SOURCE=gp_stock_category`(`theme` 是传导主题不是行业,已放弃灌 `pms_industry_map`,理由见 `UPSTREAM_PLAN_API.md` §6.1)。**待验证**:`GET /api/industry` 的 `status.ready` 是否为 true、覆盖多少条 | +| 4 | **账本重建**:清账后账本为空,需对端持仓就绪后 `POST /api/ops/reconcile?apply_fix=true` 以下游为准补回 | 阻塞:等 QMT 侧按真实成本价重建模拟持仓(`QMT_SIDE_S3_CLOSEOUT.md` §5) | +| 5 | **ws 通道联调收尾**(协议 §9 S3) | 阻塞:`trade_no` 格式不合 §5.5(`QMT_SIDE_S3_CLOSEOUT.md` §1,这条挡住切 ws) | +| 6 | 上游计划的剩余待确认口径 | 等上游:`UPSTREAM_PLAN_API.md` §4 剩 5 条 + §7.3 新增两条(同一 `date` 计划不幂等、档位规模与文档不符) | +| 7 | `changes` 段做成页面提示(新进传导链 / 掉榜) | 可做,上游已确认该段是升降档,每日几十只 | +| 8 | T0 做T(二期) | 可做,设计已有,无外部依赖 | +| 9 | 择时实现 A(委托决策系统盘中择时) | 阻塞:等 bionic 侧接口 | +| 10 | 研判闸接通 | 阻塞:等 bionic 侧 `process_intraday_audit` 新增 PMS direction。客户端已就位,接口好了在页面填 `PMS_JUDGE_API_BASE` 即通 | +| 11 | `trading_buy_plan` 退场:PMS 已不读它 | 待上游确认无其他消费方(`UPSTREAM_PLAN_API.md` Q10) | +| 12 | 部署便利性:`make deploy` 一句话完成 build + up + 各 profile | 待办 | + +### 运行态注意(2026-07-31 收尾时的状态) + +- `pms-beat` **停着**——08:40 拉计划、盘中执行等调度位都不会自动跑,开发期用页面「上游计划 → 强刷」与「运维」抽屉手动触发。重开 beat 前先确认账本已重建,否则信号消化会把信号 ACK 掉(IGNORE 也照样 ACK,跨日拿不回来)。 +- 账本已清空(`reset_ledger --purge-channel --reset-ws --drop-reports`),ws seq 水位归零 → pms-ws 一重连对端会从 seq 1 全量补发约 1.2 万条。账本空的时候**不要**点「成交回放」。 +- 宿主机放行 docker 网段到 8300 的规则若用 `iptables -I` 加的,**重启就没了**,需 `netfilter-persistent save` 或改 firewalld permanent。不持久化的话服务器重启后候选池会静默变空。 +- 自主档位仍是 `propose_only`,下发通道仍是 `shadow`。 ### ws 通道实现清单 diff --git a/UPSTREAM_PLAN_API.md b/UPSTREAM_PLAN_API.md index 31c38ad..af72383 100644 --- a/UPSTREAM_PLAN_API.md +++ b/UPSTREAM_PLAN_API.md @@ -347,3 +347,59 @@ PMS_PLAN_TOP_N=30 # 摊开之后 2. **赛道硬门槛启用后主榜会收窄到约三分之一** (十五五前沿产业链: 核聚变、商业航天、通信、 算力、人工智能、低空经济)。上游说「已建成、暂未启用, 启用后另行通知」。到时候候选池 规模会跳变一次, `PMS_PLAN_TOP` 与 `THEME_CAP_LOCAL` 都要重新看。 + + +--- + +## 7. 阶段收尾 (2026-07-31) + +### 7.1 生效中的配置基线 + +``` +PMS_CANDIDATE_SOURCE=plan_api 候选池独占来源, 拿不到不回退旧表 +PMS_PLAN_API_BASE=http://host.docker.internal:8300 +PMS_PLAN_TOP=300 OBS_TOP=100 THEME_CAP=999 发给上游: 要宽池子 +PMS_PLAN_TIERS=强传导 只吃强传导 (见下"已定纪律") +PMS_PLAN_THEME_CAP_LOCAL=5 PMS 侧同主题限额, 在 TOP_N 之前生效 +PMS_PLAN_TOP_N=30 EXCLUDE_ST=true THEME_SYNC=false STALE_TDAYS=1 +PMS_SECTOR_SOURCE=gp_stock_category 行业硬拦截的数据源 (07-31 开启) +``` + +**已定纪律 (用户, 2026-07-31)**: **候选宁缺毋滥。** 不因当天强传导少就放宽到弱传导 —— +上游文档写明「强传导规模随市场结构波动, 无板块传导的日子可能一个都没有」, 那种日子候选池 +就该是空的。只有**热度启动信息经确认**时才考虑放宽, 且必须显式改 `PMS_PLAN_TIERS`。 + +### 7.2 07-31 两次跑批的实测对照 + +| | 08:44 那次 | 收尾那次 | 说明 | +|---|---|---|---| +| `date` | 2026-07-30 | 2026-07-30 | **同一天** | +| 打分池 主榜/观察 | 972 / 81 | **423 / 502** | 见下 7.3 | +| 强传导条数 (300 中) | 74 | 47 | 随市场结构波动, 符合文档 | +| 榜首 | 688717 艾罗能源 242.28 | 605598 上海港湾 241.55 | 艾罗能源整个掉出主榜 | +| 无 theme 占比 | 205/300 | 238/300 | 印证 theme 不能当行业标签 | +| 合格候选 | 10 | 10 | 储能×5 + 整机制造×5 | +| ST 剔除 | — | 0 | 今天前 300 的强传导段没有 ST | + +除 7.3 那一条外全部符合预期: 价格全部取到 (盘中实时价, 无 `(昨收)` 标记), +`白名单档位取全: 是`, 主题限额把 37 只挤出去, 候选池 10 只 —— 按 `STOCK_TARGET_DEFAULT=6%` +算正好 60%, 与 `PORTFOLIO_CAP=60%` 对得上, 不缺票。 + +### 7.3 要报给上游的观察: 同一 `date` 的计划会变, 且档位规模与文档不符 + +`/plan` 不是读静态文件, 是 `plan.collect()` **实时从库里算**的。同一个 `date=2026-07-30`, +相隔约一小时的两次请求给出了不同的结果: + +- **打分池 972/81 → 423/502。** 文档写的典型规模是「主榜 950~1000、观察档 80~110」, + 第二次是 **423/502 —— 主榜腰斩、观察档翻六倍, 两档几乎对调**。观察档的定义是「无券商 + 覆盖」, 所以这个变化意味着**大批股票从"有券商一致预期"掉成了"无覆盖"**。像是券商预期 + 数据在中途重载, 请求正好落在半截快照上。 +- **榜首换人**, 艾罗能源整个掉出主榜。 + +**请上游确认**: ① 同一 `date` 的计划是否应当幂等? 若否, 建议给个 `generated_at` 之类的 +版本戳, 下游才能判断"手上这份是哪一版"。② 券商预期是否有重载窗口, 那期间的请求要不要 +挡掉 (返回 409/503 比返回半截数据安全)。 + +对 PMS 的影响目前可控: 候选池只在**命令规划期**取一次, 规划完即落 `pms_plan`, 之后不再 +重取 —— 不会出现"方案在途中候选池换了"。但盘前拉与盘中下命令若跨了重载窗口, 两次看到的 +榜可能不一样, 心里要有数。 diff --git a/config/settings.py b/config/settings.py index a4985e8..1d17ebe 100644 --- a/config/settings.py +++ b/config/settings.py @@ -91,6 +91,9 @@ class Settings(BaseSettings): PMS_PLAN_THEME_CAP_LOCAL: int = 5 # PMS 侧同主题限额, 在 TOP_N 截断**之前**生效, 0=不限 PMS_PLAN_TOP_N: int = 30 # 主榜按 score 降序取前 N 进池 (900+ 只是排序池不是清单) PMS_PLAN_TIERS: str = "强传导" # 传导档白名单; 留空=不按档过滤 + # **已定纪律 (2026-07-31, 用户): 候选宁缺毋滥, 不因当天强传导少就放宽到弱传导。** + # 上游文档说强传导规模随市场结构波动、无板块传导的日子可能一个都没有 —— 那种日子 + # 候选池就该是空的。只有"热度启动信息经确认"时才考虑放宽, 且要显式改这个参数。 PMS_PLAN_INCLUDE_OBSERVE: bool = False # 观察档是否进候选池 (上游把它定位为备选, 无 upside) PMS_PLAN_MIN_SCORE: float = 0.0 # score 下限, 0=不设 PMS_PLAN_MIN_SOURCES: int = 0 # evidence.n_sources 下限, 0=不设