tradingSystem/app/core/copy.py

49 lines
2.3 KiB
Python
Raw Permalink Normal View History

PMS 文案第二批:规则闸、仓位约束、资金、计划取数 抽了一个公共的显示层函数 app/core/copy.py,把句首那个大写判据码剥掉再给人看。 这一步是有讲究的。那些判据码是承重的:账本靠它取去重键(同一条被拒指令当日只记一条), 命令进度靠它做原因聚类。2026-07-29 账本被同一条指令按分钟灌满,病根就是去重键失效。 所以码必须留在句首,只能在显示层剥。此前后端两处各写了一份剥前缀的逻辑,现在共用一份。 改写的文案: 规则闸六句。冻结原因原先写「该股处于 COMMAND_HALT, 禁止增持」,既印了枚举值,也没分开 三种来路——你下的命令、你手设的、系统刹车期间,对交易员是三件不同的事。昨夜信号原先写 「决策系统昨夜定性 SELL (形态恶化)」,SELL 是枚举值,而「形态恶化」是给三种信号硬安的 定性,回避未必是形态问题。 仓位约束六句,原先全是「加后总仓 82.3% > 上限 80%」这种电报体。大于号要人翻译,而且 没说清百分比是占什么。行业占比那条还漏了设计要点——两条都超才拦,不写会被当成误拦 来投诉。 资金四句改在源头。这个字段有三个下游都直接显示给人看,改一处三处一起干净。异常原文 只进日志。 计划取数两句会渲染成页面顶部整条红色横幅。原先网络抖一下就顶一条异常原文给基金经理 看。改成说清三件事:现在拿不到什么、多久之后重试有意义、还不行找谁。其中「过 1 分钟 再试」不能省——失败结果会被缓存一分钟,早于这个点重读拿到的还是同一条失败。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 13:26:57 +08:00
# -*- coding: utf-8 -*-
"""给人看的文字的统一处理。后端与前端共用同一套口径。
## 为什么要有这个文件
系统里有一批字符串**同时背两份职责**既给机器用又给人看典型是规则闸的未通过项
形如 `PORTFOLIO_CAP: 买了这一笔总持仓会占到`句首那个大写代码是承重的
app/services/executor.py 靠它取账本去重键同一条被拒指令当日只记一条
app/core/planner.py 靠它做原因聚类命令进度那行注记
所以**代码不能从句首挪走也不能删**2026-07-29 那次账本被同一条指令按分钟灌满的
事故病根就是去重键失效正确的做法是码留在句首到了显示层再剥掉
这个文件就是那个显示层后端两处与前端各一份全部走同一口径不再各写各的
## 长远的根治
更彻底的做法是让产出方直接返回 {"code": ..., "text": ...} 两个字段机器只读 code
页面只读 text代码名泄漏这件事在结构上就消失了那是更大的改动本文件是它之前的
过渡口径也是那之后前端仍然需要的兜底
"""
from __future__ import annotations
def strip_code(text) -> str:
"""剥掉句首那个给运维看的大写代码前缀,只留中文说明。
判定条件写得严冒号之前必须全部是大写字母数字或下划线且非空这样
PORTFOLIO_CAP: 总持仓会被剥掉前缀预期空间: 算不出这种正常带冒号的
中文句子不会被误伤认不出的原样返回宁可多显示几个字也不要把人家的话截半句
"""
s = str(text if text is not None else "").strip()
head, sep, tail = s.partition(":")
if sep and head.strip() and all(
ch.isupper() or ch.isdigit() or ch == "_" for ch in head.strip()):
return tail.strip() or s
return s
def join_reasons(items, sep: str = "") -> str:
"""把多条原因拼成一句给人读的话:逐条剥掉代码前缀,用中文分号连起来。
分隔符用中文分号而不是 " | "因为这一栏是句子不是表格空条目丢掉
全空时返回空串让调用方自己决定显示什么
"""
out = [strip_code(x) for x in (items or [])]
return sep.join(x for x in out if x)