# 旧保证金链路存亡分析与下线重构方案 - 日期:2026-08-28 - 分析基线:`glms/feature/1.4.2` @ `cd615a61` - 背景:2026-08-26 `4adfbabe`(配套 `134e07c6`/`1969e292`)将互换预付金 EOD 计算收口为本端 .NET 引擎(`EodWorstClientPayableCalc` + `MarginTemplateV2RateHelper`,读 `margin_template_v2`),不再经 bond-oms Java 按旧 `marginrate` 数据算盯市。本文回答:**山证 v2.3.0 拷贝带过来的旧保证金相关代码(DMA 与否),在新引擎上线后还剩多少活口、如何分阶段下线。** ## 一、结论总览 | # | 链路 | 判定 | 一句话依据 | |---|------|------|-----------| | 1 | bond-oms HTTP 保证金接口(`/marginAlgorithm/realTimeMarginCalc` ← `CalcDMAMargin`) | **死,可删** | 全仓(含 YLWinSer/前端/配置)零调用方;`git log -S` 全历史自拷贝日起从未被调用 | | 2 | `margin_template` V1 模板管理链 | **部分可删** | 计算链已全部 V2 化;但 5 个 Razor 页面的模板下拉仍喂 V1 表 | | 3 | `client_marginrate` 旧预付金率链(MarginRateSwap) | **半死** | EOD 盯市消费方已随收口消失;剩 2 条活读链(流水导入落快照、录入页取率回显) | | 4 | `MarginRate`(不带 Swap)+ 远期保证金链 | **远期结算确定死;其余需业务确认** | `EodForwardMarginSettlement` 2025-04-16 已从 EOD 调度摘除,零调用方 | | 5 | DMA 分类(`Client.SwapTradeType`) | **活,但仅 2 处真实分支** | 其余全是透传展示与命名误导;`CalcDMAMargin` 死代码不影响判定 | ## 二、分链详解 ### 2.1 bond-oms HTTP 保证金接口(死,可删) 接口本体在 bond-oms Java 服务(`BondOmsInterface.BaseUrl = trs_hub_api`),本仓是唯一已知调用方,而调用方本身是死的: | 层 | 位置 | 状态 | |---|---|---| | 调用点 | `YLErpDAL/BLL/EodSettlement/RealtimePnlCalc.cs:722` `CalcDMAMargin()` | 全仓无任何调用方(全文件类型 grep) | | 方法内 URL | `RealtimePnlCalc.cs:725` 硬编码 | 随方法一起死 | | 配置键 | `YLWinSer/RealTimeCalcPositionService/appsettings.json:48` `CalculateDMAMarginUrl` | 无任何代码读取(URL 是硬编码的,配置键是摆设) | | DTO | `YLErpDAL/Model/CalculateMarginRequest.cs` | 仅被 `CalcDMAMargin` 使用,可连带删 | 排除项:YLWinSer 常驻任务(ClientPosiTask/Worker/ClientNoDMABalanceTask)不调它;YLErpWeb 无 `marginAlgorithm` 路由/代理,前端(含 Vue3 仓)架构上不可达;无反射/字符串调度。 **历史证据**:`git log -S "CalcDMAMargin()" --all` 仅两条 —— `f9d8a256`(山证拷贝,方法进仓)与 `4adfbabe`(只加注释)。即该方法从进仓第一天起就从未被调用,山证原版的 DMA 任务未随拷贝进来(本仓只有 `ClientNoDMABalanceTask`)。 **注意**:`EodCheckMonitoredTrade.cs:186` 注释(4adfbabe 加)把 `CalcDMAMargin` 描述为"迁移方案阶段三待切项"——与事实不符(无流量可切),删码时必须同步修正,否则迁移计划继续被带偏。 Java 端点能否删需在 bond-oms 仓自查内部调度,本仓证据只能证明"本仓侧调用链已死"。 ### 2.2 margin_template V1 模板链(部分可删) **计算链已全部 V2 化,无 V1 回退**: - 核心预付金:`MarginCalculationBase.cs:392,420` → `MarginTemplateV2RateHelper`(纯 V2 三级解析) - 追保/span:`SwapAdditionalMarginService.cs:115`、`SwapSpanBalanceQueryService.cs:91` 均走 V2 helper - 交易保存:`SwapTradeService.cs:162-209` 只查 `margin_template_v2` 并写 `trade_margin_template`(存 V2 id);`TradeSaveService.cs:654-697`、`TradeQueryService.cs:324`、`SwapMarginTemplateConfigService.cs:17` 同 - V1 管理页入口已死:`Menus.txt` 仅剩指向 V2;`margin_templateController.cs:9` 引用的 FunctionRight 权限已不存在 **V1 表仅剩 2 类活读点**: 1. `tradeController.cs:8861/8873`(`GetMarginTemplates`/`GetMarginTemplateItems`,直接 `db.margin_template.ToList()`),被 5 个在用页面 Razor 服务端调用做模板名下拉: `Views/SwapTrade2/TradeEdit.cshtml:17,33`、`Views/SwapTrade/tradeEdit.cshtml:15-16`、`Views/trade/TradeEditV2.cshtml:20-21`(远期编辑)、`Views/Pricing/Structure_DZ.cshtml:22-23`、`Views/Pricing/structure.cshtml` 2. `ForwardTradeImportService.cs:318-352,872` 远期导入消费 V1 比率(远期业务本身存亡见 2.4) **不可删(易误伤)**:`client_margin_template` 已 V2 化,是 V2 引擎第二级数据源(`MarginTemplateV2RateHelper.cs:256,341`、`ClientBalanceUtility.cs:631`);`margin_template_detail`、`trade_margin_template` 是 V2 的表,与 V1 同名前缀但归属 V2。 ### 2.3 client_marginrate 旧预付金率链(半死) 无独立 margin_rate_swap 表,整条链落在 `client_marginrate` 表(`Framework/YLErp.Core/DBModels/client_marginrate.cs:8`)。 - **写入/维护链**:菜单入口已于 `ab907122`(2026-08-12,EQD-6947)注释下线(Menus.txt:81-82"由预付金模板V2替代");`MarginRateSwapController` 的 CRUD/导入 action 仍可直接 URL 访问,FunctionRight 权限残留。 - **活读链(仅剩 2 条)**: 1. 流水导入:`SwapTradeFlowImportService.cs:351-354` 按 客户+品种+日期 取 `client_marginrate` → `:374` `InitialMargin = marginRate * StockEqvNotional` → `:393` 落 `trade_swap.GetMarginRate` 快照(TradeSwapService 8 处调用) 2. 录入取率回显:`SwapTradeController.cs:1152` `GetInitMarginRate` → `swapTradeEdit.js`(互换录入页实时回显) - **死读点**:`RealTimeClientBanlanceService.cs:1469` 加载后从未使用;`ClientBalanceUtility.cs:1517`、`ConfirmationGenerateContext.cs:1913`、`ITradeDocGeneratorContext.cs:443` 全仓零调用;`SwapTradeValidator` 只看 `trade_swap.GetMarginRate` 快照,`:24` 的调用已注释。 - **与新引擎零交叉**:已逐一确认 `EodWorstClientPayableCalc`、`MarginTemplateV2RateHelper`、`RealtimePnlCalc`、`SwapSpanBalanceCalc`、`SwapAdditionalMarginService` 均不读 `client_marginrate`;无 SQL/Dapper/存储过程读点;YLWinSer 无相关任务。 ### 2.4 MarginRate(不带 Swap)+ 远期链 - **`EodForwardMarginSettlement` 确定死**:`8e61f23e`(2025-04-16)已将其从 EOD 调度摘除,现全仓零调用方;`eod_forward_margin` 表唯一写入点随之失活,读方(`EodPositionSettleService.cs:870,967`、`RealtimePnlCalc.cs:1009`、`TradeForwardUnwindService.cs:96`)全部空转。`SettlementConfig.CalcForwradMargin` 零消费。 - **Forward 模块整体**:拷贝后零提交改动;录入页/导入/11 个 Views/API 均在,菜单在 DB `sys_menu`(仓内无法证明挂没挂);`tradeController.cs:6295` 仅渤海/广发商贸分支才查远期。**需业务确认**(菜单是否还挂、trade 表有无远期存量)。 - **`MarginRate` CRUD/导入**:UI 自闭环;表读方仅 `SwapTradeFlowImportService.cs:337`(且被 `PS.Config.Company==中金` 门控,本部署非中金)与 `VarietyDalService.cs:426`(防删校验);`GetMarginRate`(`MarginRateService.cs:210`)零调用。 - **`MarginParamProvider` 不可删**:`MarginCalcHelper.cs:30`(活引擎 `RunMarginCalculation` 内)与 `TradeDelaySettlementService.cs:72,163` 在用其涨跌幅/波动率;其预付金率读法(`:149-160`)才是死的。 ### 2.5 DMA 概念:字段活,概念基本只剩命名 字段 = `Client.SwapTradeType`(`Client.cs:1149`,1=DMA/MDA,0=非DMA)。**真实分支仅 2 处**: 1. `QuotaMonitorService.cs:5591` `CheckFund`:`SwapTradeType==0` 非 DMA 不做资金校验直接过(经 `RunQuotaTrial` ← `tradeController.cs:8502` 限额试算,活) 2. `YLErpWeb/App/KafkaTask/ClientBalanceTask.cs:62`:DMA 客户 `lastBalanceDate=valuedate`(起算日改为当日),活 其余全部是透传/展示/命名:`ClientSettleBalance.ClientTypeStr`、`ClientBalanceUtility`、`RealTimeClientBanlanceService`、监控/报表 js、客户编辑下拉等;`SwapFlowCombookingHub.cs:79` "DMA合成持仓" 只是 region 名(DMA 过滤已注释,与 DMA 无关,Hub 本身有前端连接方,活);`ClientNoDMABalanceTask` 的 "NoDMA" 纯任务名,`GetBalances()` 取全部客户无 DMA 过滤。 ## 三、下线重构方案(分阶段) ### 阶段 0:立即可删(零调用方,已实证) | 删除项 | 前置条件 | |---|---| | `RealtimePnlCalc.CalcDMAMargin()` + `CalculateMarginRequest.cs` + appsettings `CalculateDMAMarginUrl` 键 | 无 | | `EodCheckMonitoredTrade.cs:186` 注释修正(去掉"阶段三待切项"误导) | 随上条同提交 | | `EodForwardMarginSettlement.cs` + `SettlementConfig.CalcForwradMargin` | 无(可选:同步清 `eod_forward_margin` 读方空转代码) | ### 阶段 1:小改造后可删(V1 模板链) 1. `tradeController.GetMarginTemplates/GetMarginTemplateItems` 改为从 `margin_template_v2` 取数(或确认 5 个页面的 V1 下拉已无业务意义直接去掉下拉)。 2. 改造完成后删:`margin_templateController.cs`、`Views/margin_template/*`、`MarginTemplateService.cs`、`margin_templateReq.cs`、`DBModels/margin_template.cs`、`YLContext.cs` 中对应 DbSet。 3. 远期导入的 V1 比率消费随阶段 2 远期业务结论一并处理。 ### 阶段 2:需先迁移读链(client_marginrate / 远期) 1. 流水导入落快照(`SwapTradeFlowImportService.cs:351-393`)与录入取率回显(`GetInitMarginRate`)两条链迁 V2 引擎取率。 2. 迁完后整体下线 `MarginRateSwapController` + `MarginRateSwapService` + `client_marginrate` 表链,并清理 FunctionRight 残留权限。 3. 远期业务经业务确认后:无存量则 Forward 模块 + `MarginRate` 链整体清理;有存量则查询/平仓/对账页暂留、仅清结算死链。 ### 需确认清单(删除前必须逐项闭环) | 项 | 确认方式 | 风险 | |---|---|---| | Vue3 前端仓是否调用 `/trade/GetMarginTemplates`、ForwardTrade、MarginRateSwap 系列 action | 前端仓 grep(本仓不可见) | action 被直连调用 | | trade 表有无远期存量数据、`sys_menu` 是否还挂远期菜单 | DB 查询 | 存量交易无法查询/平仓 | | `client_margin_template` 历史行 `MarginTemplateId` 是否残留 V1 id | DB 查询 | join 不上会静默落到第三级默认 | | `client_marginrate` 表是否有 V2 之外的人工维护依赖(运营流程) | 业务确认 | 导入链迁 V2 后仍有人改旧表 | | bond-oms 内部是否有 `/marginAlgorithm/realTimeMarginCalc` 的其他触发方 | bond-oms 仓确认 | Java 端点下线 | ### 不可删清单(防误伤) `client_margin_template` / `margin_template_detail` / `trade_margin_template`(V2 数据源)、`MarginParamProvider`(涨跌幅/波动率在用)、`Client.SwapTradeType` 及其 2 处分支、`ClientBalanceTask`、`SwapFlowCombookingHub`。 ### 顺手项(命名去毒,不动逻辑) - `ClientNoDMABalanceTask` 任务名、`SwapFlowCombookingHub` "DMA合成持仓" region 名、`ClientBalanceForTrsResponse.ClientType` 注释口径,均与实际行为不符,可在触碰时改名。 ## 四、验证纪律(执行删除时) 沿用 2026-08 死代码清理的教训(见 `多租户死代码清理执行计划.md`): 1. 每个删除项独立小提交,删前全文件类型 grep(不止 *.cs,含 js/cshtml/xml/json/配置),删后 Release + Debug 双构建; 2. `git rm` 目录混批后必须重新 find 核对(笔误会静默回滚整批); 3. 涉及 DBModel/列的删除,列残留留给 DBA,不在应用层迁移; 4. action 删除必须先过"前端仓确认"关卡。