147 lines
9.7 KiB
Markdown
147 lines
9.7 KiB
Markdown
# PMS 个股交易方案(策略)框架 · 设计 v1.1
|
||
|
||
> 2026-08-11。这份 governs 下单口的改动,是全系统风险最高的一段。v1.1 并入用户四点拍板。
|
||
> **已定方向**:v1 做 **做T + 网格 + 跟踪止盈**(同一自动机的三种配置);新挂策略**默认自动执行**
|
||
> (`autonomy=auto`,仍可逐策略改成「待确认」);**挂了策略的股票从动作引擎自动提议里排除**。
|
||
> 纪律:只做加法(不改既有执行/闸门/动作引擎逻辑)、与现有引擎清晰隔离、**开发期先 shadow 验代码再切实盘**。
|
||
>
|
||
> **四点拍板(2026-08-11)**:① 网格跌破下界 = **继续持有、不再买**(停买入腿、保留已买、回升仍按已买档卖、告警);
|
||
> ② 做T 当日次数上限 = **3 次**;③ 新挂策略默认自主档 = **直接自动执行**;④ **跟踪止盈补进 v1**。
|
||
|
||
---
|
||
|
||
## 一、目标与判收
|
||
|
||
**最终检验**:用户能给某只持仓挂一套价格触发的交易方案(做T / 网格 / 跟踪止盈),系统在 **T+1 与仓位纪律**
|
||
约束内、按方案自动(或待确认)地做买卖;全程留痕、可暂停、可看实时状态、有熔断/上限/平回兜底。
|
||
|
||
**输出级判收(实机,shadow 先行)**:
|
||
1. 做T:一笔**完整平回** —— 当日买卖数量对齐,T 仓过夜为 0;当日达 3 次后不再做;
|
||
2. 网格:一档买入 + 一档卖出各走通并落账本;跌破下界后**不再买**、已买仓位保留;
|
||
3. 跟踪止盈:价格从高点回落到设定比例时**触发一笔卖出**并落账本;
|
||
4. 任何策略动作都**过规则闸** —— 违反单股上限 / T+1 可卖 / 暂停买入 时被拦下;
|
||
5. 挂了策略的票,**不再冒自动提议**;暂停某策略后它**不再出手**;全局暂停买入 / 休假 / 一键清仓对策略同样生效。
|
||
|
||
---
|
||
|
||
## 二、现状(以代码为准)
|
||
|
||
**做T = 搭了架子、没通电**:参数全(`PMS_T0_RATIO_MAX`、`PMS_T0_PULLBACK_PCT`、`PMS_T0_RALLY_PCT`、
|
||
`PMS_T0_ROUND_TARGET`、`PMS_T0_CLOSE_TIME`、单票/全局当日T亏熔断)、授权命令(`T0_ENABLE`)、
|
||
账本全(`t0_qty/t0_ratio/t0_count_today/realized_t_profit`、T0 批次、卖出先核销 T0、日初重置、成本含T利润)、
|
||
`planner` 有 `A_T0="T0_ROUND"`;**但 `executor.run_tick` 的动作集不含 T0,无正T/反T触发逻辑**。设计标「二期、默认关」。
|
||
|
||
**网格、跟踪止盈 = 无**(跟踪止盈与既有「保垫减仓」同源但那是动作引擎里按安全垫自动跑的,非逐股用户配置)。
|
||
|
||
**执行链(可整条复用)**:`run_tick` 每分钟一跳,遍历在途 `pms_instruction` → `exec_advisor` 择时 → 切片 →
|
||
(卖)按 `avail_qty` 封顶(**T+1 在此挡住**)→ `rule_gate.check` 合规终检 → `dispatcher.dispatch`(→ws→QMT)→
|
||
子单 + 评审账本。指令来源 = 命令方案 / 提议采纳 / 信号。
|
||
|
||
---
|
||
|
||
## 三、一条铁律定了整个框架:T+1
|
||
|
||
当日买入不可当日卖出 → 「今天低买高卖同一批股」做不到 → 做T / 网格 / 跟踪止盈本质都是「在一只**底仓**上、
|
||
用 T+1 可卖的存量股做买卖」→ **同一自动机的三种配置**。`run_tick` 已按 `avail_qty` 封顶卖出,T+1 天然被挡住。
|
||
|
||
---
|
||
|
||
## 四、框架:策略层 = 一个新的「指令来源」(只做加法)
|
||
|
||
新增 `strategy_runner`,挂在**现有每分钟调度位**(与 `run_tick` / `scan_proposals` 并列)。每跳:载入 `ACTIVE`
|
||
策略 → 取该股 `day_snapshot` + 持仓(`avail_qty`/成本)→ 按类型 `evaluate()` 出决策 → 过**策略层 rails** →
|
||
触发就:`autonomy=auto` 发一张**短窗口指令**(`window_tdays=1`、`is_command=True`、`origin_type="strategy"`),
|
||
交 `run_tick` 用现有管线执行;`autonomy=confirm` 落一条提议进「等我拍板」。再更新 `state_json`。
|
||
|
||
**复用全部闸门**(单股上限/一手/T+1/冻结/黑名单/暂停买入),一道不重写。**不碰动作引擎**,唯一加法是下一条 skip。
|
||
|
||
**动作引擎唯一触点**:`action_engine.scan` 跳过「有 ACTIVE 策略」的票 —— 避免两个大脑抢同一只。命令驱动(用户手动清/减该股)不受影响。
|
||
|
||
---
|
||
|
||
## 五、数据模型(新增一张表,走 ddl 文件、非例行事务内嵌 DDL)
|
||
|
||
`pms_strategy`:`strategy_id`(唯一) / `ts_code` / `type`(T0|GRID|TRAIL) / `status`(ACTIVE|PAUSED|DONE|CANCELLED) /
|
||
`autonomy`(auto|confirm,**默认 auto**) / `params_json` / `state_json` / `created_at`/`updated_at`/`note`。
|
||
- `state_json`:做T=`{t_count_today, open_leg, day_realized}`;网格=`{filled_levels[], below_floor}`;跟踪止盈=`{high_water, armed}`。
|
||
- `pms_instruction.origin_type` 增加取值 `"strategy"`(≤8 字符,列宽兼容;注释同步)。
|
||
|
||
---
|
||
|
||
## 六、做T 规格(把已有架子接通)
|
||
|
||
- **触发**:正T = 距当日高点回落 ≥ `PMS_T0_PULLBACK_PCT` 且近支撑 → 买 `t_qty`(=持仓×`t_ratio`,`≤ PMS_T0_RATIO_MAX`
|
||
即 1/3),按 `PMS_T0_ROUND_TARGET` 价差高卖;反T = 近压力或日内涨 ≥ `PMS_T0_RALLY_PCT` 滞涨 → 卖 `avail` 的 `t_qty`,低买回。
|
||
- **rails**:**当日 ≤ 3 次**(`t_count_today`);**`PMS_T0_CLOSE_TIME`(14:50)强制平回**(当日买卖数量对齐、绝不过夜);
|
||
单票 `PMS_T0_STOCK_DAY_LOSS` / 全局 `PMS_T0_GLOBAL_DAY_LOSS` 当日T亏熔断后当日禁T;须有底仓且 `avail_qty` 足。
|
||
|
||
---
|
||
|
||
## 七、网格 规格(新)
|
||
|
||
- **配置**:中枢价(手动或取当前价)、档距(% 或元)、上界/下界、每档股数或金额、最大投入额(须落在单股上限内)。
|
||
- **规则**:现价跌破某未买档 → 买 1 份(过单股上限/资金闸);现价涨破某已买档 → 卖 1 份(从 `avail`,T+1 挡);越上界停做。
|
||
- **跌破下界(已定)**:**继续持有、不再买** —— 停掉买入腿,保留已买的档位,若价格回升到已买档之上仍按规则卖出;
|
||
并在页面/账本告警「跌破下界,已停止网格买入」。不清仓、不继续往下接。
|
||
- **state**:`filled_levels` + `below_floor` 标记。不强制平回(多日底仓策略);今天买的今天卖不了(管线挡)。
|
||
- **安全**:最大投入额 = 硬上限;单股上限闸兜底。
|
||
|
||
---
|
||
|
||
## 七·B、跟踪止盈 规格(新,v1 纳入)
|
||
|
||
- **用途**:锁住已有浮盈 —— 价格创新高就抬止盈线,从高点回落到设定比例就卖出离场。**只卖不买**(纯离场保护)。
|
||
- **配置**:启动线(浮盈 ≥ X% 才开始跟踪,默认取 `PMS_CUSHION_SOLID` 一线)、回撤比例 giveback(从高点回落 ≥ Y% 触发卖)、
|
||
卖出比例(触发时卖 `avail` 的百分之多少,默认全清)、可选硬止盈目标(浮盈 ≥ Z% 直接全清)。
|
||
- **state**:`high_water`(启动后的最高价)、`armed`。
|
||
- **规则**:每跳更新 `high_water=max(high_water, 现价)`;浮盈达启动线则 `armed=true`;已武装且现价 ≤ `high_water×(1−giveback)`
|
||
→ 卖出(从 `avail`,T+1)。命中硬止盈目标直接全清。
|
||
- **与既有「保垫减仓」的关系**:挂了跟踪止盈的票已从动作引擎排除,不会和自动保垫减仓双触发;这是该股的用户版止盈。
|
||
|
||
---
|
||
|
||
## 八、补充策略(同一自动机,v1 之后、留接口)
|
||
|
||
`evaluate()` 加一个 `type` 分支即可:**分批建仓/定投**、**区间高抛低吸**(两档简化网格)、**突破加仓**。
|
||
|
||
---
|
||
|
||
## 九、隔离与安全(重点:动的是下单口)
|
||
|
||
1. **逐股显式挂载**(opt-in),绝不自动套用;
|
||
2. 挂策略的票**从动作引擎自动提议排除**;
|
||
3. 策略动作走**命令口径**(过规则闸、不过研判闸);
|
||
4. **每策略自主档**:默认 `auto`(直接自动执行,你的拍板);可逐策略改 `confirm` 进「等我拍板」观察;
|
||
5. **双保险**:rails 在策略层先拦(熔断/上限/平回/当日次数/下界),规则闸再拦一道(合规);
|
||
6. **开发期先 shadow 后实盘**:`PMS_DISPATCH_MODE=shadow` 下先验证策略只发到影子出口、不碰真 QMT,判收通过再切 live
|
||
—— 这是验**新代码**下单对不对,不是给你的策略设门槛;
|
||
7. 全局开关对策略同样生效:暂停买入 → 策略买入被闸拦;休假 → 策略不出手;一键清仓照常。
|
||
|
||
---
|
||
|
||
## 十、UI(交易员视图,只做加法)
|
||
|
||
- 「我的持仓」每行加**挂交易方案**:选类型(做T/网格/跟踪止盈)→ 填该类型参数(带当前价/持仓量参照,不盲填)→
|
||
选自主档(默认自动,可改待确认);
|
||
- 显示策略**实时状态**:做T「今日 2/3 次,日内 +¥320,平回 ✓」;网格「6 档已买 3,投入 ¥180k/上限 ¥240k」;
|
||
跟踪止盈「高点 ¥18.6,回落 3.1%,未触发」;可**暂停/恢复/撤下**;
|
||
- 策略动作在「今日在办与动向」里与普通指令一起看,标来源 = 策略。
|
||
|
||
---
|
||
|
||
## 十一、分步落地(每步你实机验,shadow 先行)
|
||
|
||
1. 建表 `pms_strategy` + `strategy_runner` 骨架 + `origin_type=strategy` + 动作引擎 skip(先不含任何策略规则,空跑通);
|
||
2. **做T** `evaluate` + rails(含 3 次/平回/熔断) → shadow 验「一笔完整平回」;
|
||
3. **网格** `evaluate` + rails(含下界=继续持有不再买) → shadow 验「一档买 + 一档卖」;
|
||
4. **跟踪止盈** `evaluate` + rails → shadow 验「回落触发一笔卖出」;
|
||
5. UI 挂载/状态/暂停;
|
||
6. 三种各切实盘观察 → 稳定。
|
||
|
||
---
|
||
|
||
## 十二、已定(本轮四点,无遗留待决)
|
||
|
||
① 网格跌破下界 = 继续持有、不再买;② 做T 当日 ≤ 3 次;③ 新挂策略默认自主档 = 自动执行;④ 跟踪止盈纳入 v1。
|
||
开工顺序按第十一节;每步 shadow 先行、单测你实机跑。
|