Commit Graph
100 Commits
Author SHA1 Message Date
hjhan 5fcbebb4a6 style: 预付金模板区块标题加色条分层,追保表格输入框加宽、单元格垂直居中 2026-08-28 09:04:19 +08:00
hjhan 0e0a6d0962 style: 预付金模板左栏控件统一宽度,多选标签宽度自适应
- chosen 已选项去掉固定 130px 宽:短标签右侧留白、搜索框被挤到下一行撑高控件
- 左栏加 tpl-base 标识,input/select 统一 240px、说明 textarea 跟随列宽,
  去掉三页面各写一个内联宽度(320/460px 混用)
2026-08-28 09:03:52 +08:00
hjhan 0222c4abe4 fix: 预付金模板三页面「刪除」繁体字统一为简体「删除」 2026-08-28 09:01:48 +08:00
hjhan 3be4b48ca2 cleanup: 删除 roleEdit.js / errorInfo.js / demo/autocomplete.js 三个孤儿脚本
三者均为 2024-05-09 从山证v2.3.0拷贝带入后从未修改、全仓库零引用:
- roleEdit.js: RoleEdit.cshtml 无任何 script 引用
- errorInfo.js: 操作 #infoTable/pageObj.SacInfoList,无视图加载
- autocomplete.js: demo 示例残留
单独 revert 本 commit 即可整体找回。
2026-08-28 08:45:21 +08:00
hjhan 902731e2fb cleanup: 删除从未接线的 structureoptionV2.js 孤儿脚本
2024-05-09 从山证v2.3.0拷贝带入后从未修改、从未被任何视图/bundle/动态加载引用
(同名视图 structureoptionV2.cshtml 是活视图,但其加载的是 structureoption.js)。
全仓库大小写不敏感搜索引用数为 0。单独 revert 本 commit 即可找回。
2026-08-28 08:45:15 +08:00
hjhan 678ea1f52a cleanup: 删除 structure_dz.js / tradePricing_dz.js 并去掉 TradeEditV2 润和脚本分支
依据死代码分析报告第一轮零风险清理。
两个 _dz JS 仅被已删除的 _dz 视图链引用;
TradeEditV2.cshtml 国联下恒走 else 分支,简化后渲染结果不变。
单独 revert 本 commit 即可整体找回。
2026-08-28 08:25:50 +08:00
hjhan 91680a8f2f cleanup: 删除 _dz 链死视图 Structure_DZ.cshtml 与 _PricingItemTpl_dz.cshtml
依据死代码分析报告第一轮零风险清理。
Structure_DZ.cshtml 仅被已删除的 Structure_DZ() Action 使用;
_PricingItemTpl_dz.cshtml 仅被 Structure_DZ.cshtml PartialAsync 引用。
单独 revert 本 commit 即可整体找回。
2026-08-28 08:25:35 +08:00
hjhan c007037d36 cleanup: 删除 PricingController 中无人使用的 Structure_DZ 死 Action 及 StructureImport 润和死分支
依据 outputs/zszq-trs-pricing-structure-dz-死代码分析报告.md 第一轮零风险清理。
国联分支下 Is润和 恒为 false,Structure_DZ 无任何菜单/代码入口。
单独 revert 本 commit 即可整体找回。
2026-08-28 08:24:50 +08:00
hjhan 65cb3ff95c docs: 旧保证金链路存亡分析与下线重构方案
预付金引擎收口(4adfbabe)后对山证拷贝遗留的保证金链路做全量死活判定:
bond-oms HTTP接口/CalcDMAMargin全链死、V1模板链部分可删、client_marginrate
半死、远期结算链确定死、DMA仅剩2处真实分支;附分阶段下线方案与需确认清单。
2026-08-28 06:54:31 +08:00
hjhan 84b5a362e8 修复 SP_002 冒烟测试两处取数偏差
- 样本 join underlying_manager:取数链路 InnerGetEodPrice 从标的表出发 join 价格表,
  未登记为标的的代码取数必返回 null,冒烟样本须限定在已登记标的上
- 查询日期经 GetNonHolidayDefore 回退到最近交易日:dev 库 eod_stock_price 混有
  非交易日/未来日期脏行(如 2026-08-30 周日),取数链路按交易日历向后滚到下一交易日
  后无数据导致假失败
2026-08-27 18:46:10 +08:00
hjhan 117ea3e1d2 清理 SwapEodPositionService.GetAutoSwapCashRebate 冗余 Convert.ToDecimal
CreditRebate 已随资金标签链路改为 decimal,Convert.ToDecimal(decimal) 恒等转换,直接去掉。
2026-08-27 18:36:28 +08:00
hjhan 15d25228af 授信/现金资金标签分配链路 double→decimal 精度收敛
- FundTagCalc 全链路(LegAmount/LegFundPlan/UnwindTagSplit/TagRelease/MarginLegSettlement)金额类型改 decimal,消除 double 二进制误差在拆单倒挤、守恒校验中的分位尾差
- 边界处显式转换:writeCash 委托与 ClientCreditInoutService.Occupy/Release(仍 double)、GetAvailableCredit 返回值 (decimal) 强转
- SwapDealService.RecordMarginCashFlow/ReleaseMarginByFundTag 签名同步 decimal,测试桩 TestableSwapDealService 对齐
- 单测断言去掉 1e-6 容差(decimal 精确比较)
2026-08-27 18:22:56 +08:00
hjhan a7babb95a4 fix(EQD-7049): 期权定价首腿预载默认标的失败不再弹"标的信息缺失"
- 现象(国联民生反馈):新建定价页第一次新增单腿即弹"标的信息缺失",
  接口返回 {success:false,obj:null,msg:"标的信息缺失"}
- 根因:首腿 initFlag='first' 挂载后自动预载默认类型标的(Stock/CommodityFutures,
  由 OtcConfig.StockFirst 决定),固收环境下该类型无"已上线且未到期"标的时
  后端 FirstOrDefault 落空返回 JsonError;1c19d2f7 的"三者皆空跳过"守卫
  挡不住这条带默认类型的请求
- 修复:首腿预载改走 preloadDefaultUnderlying,以 silent 调 updateUnderlying——
  main.post 传 {alertFn:$.noop, suppressError:true} 静默失败(仅 console.warn),
  标的留空待用户自选;用户主动切换类型/选标的的查询路径完全不变
- 注:changeInstrumentType 被 v-on:input 绑定(首参为选中值),不能加位置参数,
  故预载单独成方法
- 同步修改东莞定制版 structure_dz.js
- 验证:mock 后端返回 success:false,断言静默选项传递/用户路径不变/旧守卫保留/
  首腿接线,两文件 12 项全过;下拉套件 20 项回归全过
2026-08-27 15:21:20 +08:00
hjhan 30bf3492bd fix(EQD-7049): 期权定价页标的下拉异步结果落地后刷新显示
- 现象(客户反馈):输入关键词接口返回20条但下拉只显示2条,继续输入又正常
- 根因:FastVue.autocomplete 对函数型 lookup 只同步取返回值渲染,服务端响应
  回来后仅写缓存、未触发重渲染,下拉永远显示"上一次请求结果+当前词再过滤",
  慢一拍且被前端二次过滤(品种/IsCombined/contains)进一步砍少
- 修复:响应到达且输入未变、下拉可见时重触发插件 onValueChange 重渲染;
  _fresh 命中当前关键词直接展示服务端结果(不再前端二次过滤,跨品种结果不误滤),
  _seq 单调递增丢弃乱序响应,_inflight 防同关键词重复请求
- 移除 mounted 中无效的 autocomplete('search') 调用(插件无此方法,一直为空操作)
- 同步修改东莞定制版 structure_dz.js
- 已用 Playwright 对照验证:旧代码复现"输入20只显2项/接口返回20条",修复后
  两文件 20 项断言全过(显示数=服务端返回、无请求风暴、乱序不污染、可选中)
2026-08-27 14:56:12 +08:00
hjhan 08d374a418 fix: 确认书勾选框渲染观感——占位符run显式指定符号字体
生成的确认书中 ☑/□ 占位符继承模板楷体,楷体无 U+2611/U+25A1 字形,
Word 按字体回退渲染导致符号与周围文字大小不一。

- 模板中 11 处勾选框占位符 run(协议段 9 处 + 利率类型 IsFixed/IsFloat 2 处)
  显式指定 Segoe UI Symbol 并将字号由 24 调至 28 对齐楷体正文视觉高度
- 嵌在长文本 run 中的占位符(主协议NAFMII勾选、IsFixed/IsFloat)拆分为
  独立 run,使前后文字保持楷体、符号单独设字体
- 渲染测试补充 IsFixed/IsFloat 驱动,产物 11 处勾选框均验证为符号字体
2026-08-27 14:09:09 +08:00
hjhan ef4b73f1ce feat: 确认书协议段勾选框按客户主协议类型动态生成
在已合并为单段的协议段基础上,把 9 个勾选框(SAC/NAFMII 主协议与
补充协议、协会、三份定义文件)从模板硬编码(Wingdings 2 复选框与
固定文本□)改为占位符,由生成器按客户开户维护的
client_meta.MainProtocolType(1=NAFMII,其余 SAC)填 ☑/□,
避免 NAFMII 客户确认书错按 SAC 勾选展示。

- 修改 4 份确认书模板,移除全部 Wingdings 2 依赖
- TradeConfirmationGenerator 按主协议类型赋勾选值,
  主协议类型缺失时记录日志并按 SAC 展示(与原行为一致)
- 定义文件维度暂无客户协议数据,统一空框,待资料补齐后接入
- 新增 TestGuoLianConfirmTemplate 渲染测试覆盖 SAC/NAFMII 两类客户
2026-08-27 13:50:07 +08:00
hjhan 9121a13fc4 chore: 清理源码注释中的内部项目代号,避免交付歧义
BondCalcHepler 调用链注释 zszq-trs/zszq-bond-oms 改为中性表述
(TRS主服务/bond-oms);集成测试交易编号夹具 ZSZQ-IS- 前缀改为
TRS-IS-。OA 对接配置值与数据库名为功能性配置,不在本次范围。
2026-08-27 08:58:22 +08:00
hjhan 7fff6e8236 fix(swap-eod): 用 MarginModes.ForLinq 替换 EF LINQ 中的 MarginModes.Contains
swap_position 的 EF 查询在 Where 里使用 MarginModes.Contains(x.InterestMode),
该静态方法无法被 EF Core 翻译成 SQL,导致有数据时抛 Translation failed。
改用 MarginModes.ForLinq(List<int> 形态)即可翻译为 IN (...)。
内存集合(details/interests 已 ToList)不受影响,无需改动。
2026-08-25 11:09:13 +08:00
hjhan 610279c3aa chore(cleanup): 清理编译器已证明的死代码残留(CS0219/CS0162/CS0169)
- SwapEodPositionService: 删除衡泰推送残留的swapInsertEnum/swapPosiEnum赋值及fposition判空赋值块,赋值后从未读取(CS0219×2)
- TradeConfirmService: if(addlog)分支仅剩三个同源死赋值(原衡泰推送调用已删),删赋值并将if/else翻转为if(!addlog),保留原else的Task.Run实时持仓刷新(CS0219×3)
- QuotaMonitorService.checkTrade: 唯一存活case互换价格偏离比例恒return,删除switch后不可达收尾段(CS0162);删除从未使用的posiVal与重复的currentValue=null赋值
- YLErpWebApiHelper: 删除从未赋值/读取的私有字段baseUrl(CS0169)

UnderlyingDbDataSource.DataSourceUpdated(CS0067)为IDataSourceEvent接口契约成员且DataCacheManager经接口订阅,不属死代码,保留不动。全量重编YLErpDAL通过,0警告0错误。
2026-08-24 13:55:16 +08:00
hjhan 733ade024a revert: 补回d42742ab误随批删除的client三个下划线partial——_ClientDutyDirectorList/_ClientFileList/_ClientInvestorsList。d42742ab提交信息声明"待查库未删"但git rm混批时被一并带走,与声明不符。这3个走clientEditV2.cshtml:123/clientViewV2.cshtml:127的PartialAsync(item.viewPath)通道,viewPath源自DB AppConfig(PGroup=System,PName=ClientEditConfig),代码grep无法穷尽DB覆盖;默认嵌入配置(Resources.clientEditConfig)零引用已复核。恢复后维持"仅DB显式覆盖可达"的待查状态,查库确认后再处置 2026-08-22 10:29:57 +08:00
hjhan d7e6955132 revert: 恢复误删的Admin后台区域——用户澄清/admin管理后台是在用的,上条消息"没有使用"指的是admin页面也没引用jquery-3.6.0而非页面废弃。恢复Areas/Admin整目录28文件+Scripts/admin两文件。jquery三件套/3个业务死JS/11个死视图/NCrontab的删除仍然有效(admin布局零jquery引用,复验不受影响) 2026-08-22 10:19:36 +08:00
hjhan d42742ab10 chore(swap): 删除Admin后台区域与前端死文件——Areas/Admin整区(6控制器17视图,用户确认无人使用,主站零入口链接,/front/clientEditConfig由FrontController直走Service与该区无关,配置编辑界面移除但底层Service与DB配置不动)+Scripts/admin;jquery-3.6.0三件套(拷贝当天即零引用,运行时一直用Statics/libs 3.5.1);3个业务死JS(TradeMarketReport_DmaEodPosition/UserDefinedStructure/forwardTradeMarginCost,含Areas/App_Data语料双重复核);11个死视图(supervise2022副本3个/Picktrade两个/申万PDF模板等,渲染通道全代码内零命中);NCrontab.Signed零使用死包。client下划线3个partial因走DB配置viewPath通道待查库未删 2026-08-22 10:18:26 +08:00
hjhan 5436a88657 chore(swap): 删除YLErpUnitTest整个废弃测试项目——不进任何sln无法构建,全部文件冻结于2024-05-09分支拷贝日两年半零维护;68%是OptionCalculatorV1旧副本(sln内UnitTestProject自有副本且被实际引用),其余为被取代的DB依赖手工草稿测试与过期资源。-12351行 2026-08-22 08:21:23 +08:00
hjhan 7ac219ad0f chore(swap): 删除确认书/结算报告厂商定制死分支——国联专属分支Company恒定,24个厂商确认书编号生成器+批量开关收敛国联直调(瑞达/海通/格林大华批量方法连带),结算报告模板与HasExtendVol同款收敛;保留WCZD公开方法(插件接口ITradeDocGeneratorContext成员,防外部DLL ABI);顺手修正GenerateGuolianContractNo存量错注释(国贸→国联)。-1214行,Release/Debug/UnitTestProject构建0错误 2026-08-22 08:11:43 +08:00
hjhan 7b65ec0979 chore(swap): 删除全部期货公司定制保证金计算死代码——36个厂商类+东吴DongWu子目录+调度器四处厂商switch收敛Default直调+MarginTypeEnum三个不可达枚举项;连带YLErpUnitTest厂商类历史快照副本与4个厂商测试(3个零断言草稿/1个招证金标准)。本分支Company=国联无专属case,厂商路径本就永不执行;顺带消除Debug配置残留的格林大华#if DEBUG两处编译错误。-23231行,Release/Debug/UnitTestProject三处构建0错误 2026-08-22 07:58:25 +08:00
hjhan 0ff7375696 refactor(web): 百分比列展示嗅探一行式显式化——6处逐字重复抽PercentColumnText纯函数
structure.js×3/structure_dz.js/tradeEditV2.js/tradeEditGroup.js的setExtendInfo里同一行式:靠indexOf("%")>0嗅探值是否已带%,决定原样展示还是×100加%。抽为app/trade/percentColumnText.js纯函数(UMD,jest可测),表达式逐字符等价——含>0而非>=0、空值回退ColumnDefaultValue、回退源也无值时NaN%等历史行为全部被7个特征测试冻结(TDD:测试先红后绿)。四个页面cshtml在tradeHelper后补脚本序;jest覆盖率清单纳入。fe-tests 326/326通过
2026-08-22 07:46:58 +08:00
hjhan ef0e3b957b refactor(web): 收益互换平仓页(incomeSwapTrade)符号三元显式化——4处裸三元改UnwindLegSign调用
与unwindSwapTrade同款配方:interestPnlSign(利息盈亏,InterestDirection==1→+1)/payDirectionSign×2(浮动端与均价手续费方向)/positionTypeSign(多空方向,==1多头→+1)。语义逐处核对等价:本页无保证金返还本金列,不涉及marginRebatePrincipalSign反号。顺手删calcClosePnL注释死块与interestRatio注释行。SwapIncome.cshtml补unwindLegSign.js脚本序。node --check通过
2026-08-22 07:44:44 +08:00
hjhan 6ff068d70b chore(swap): 删除格林大华保证金#if DEBUG明显bug分支——Release下case空体误落国泰君安公式组
本部署CompanyEnum=国联(走default→DefaultMarginCalculation),且保证金正在其他分支重写,各家期货公司定制对本分支无意义;格林大华case体整体包在#if DEBUG里,Release编译时空case直接fall-through到国泰君安/光大光子/兴业商贸组——若格林大华环境用Release版,保证金一直在用别家公式。连同DAL的GLDHMarginCalculation.cs与UT下整文件注释的死备份一并删除。dotnet build 0错误
2026-08-22 07:44:23 +08:00
hjhan e90f2d9fc2 chore(swap): 删除dbf旧导入死簇与HTStatus死字段——SwapFlowImportService整条zip/dbf链+TradeBase.HTStatus
ImportSwapTradesFromZip标记[Obsolete]且全仓零调用,其私有依赖链GetDbfFiles→GetDbfDatas→GetSwapFlowData_SZ/_SH→ConvertDateTime仅被它触达,连同DotNetDBF/SharpZipLib两个using一并删除;Excel导入路径(ImportSwapTradesFromExcel)不受影响。TradeBase.HTStatus全仓无读无写,属性删除后EF不再映射该列(数据库列残留留给DBA评估)。

dotnet build 0错误
2026-08-22 07:38:08 +08:00
hjhan e936a2f853 chore(swap): 删除衡泰死配置链与DataCompare孤儿Dto——OtcAppConfigHelper整个文件+HedgingSource/HTUpdate配置字段+DataCompare/Dto四件套
死链全貌:appconfig的"对冲交易数据源/接衡泰修改回执"两键→OtcAppConfig两属性→AppHelper启动复制→OtcAppConfigHelper两静态属性→全仓零读取方。OtcAppConfigHelper除这两属性外无其他成员,整文件删除;配置经JsonHelper.Deserialize加载,存量JSON多余键自动忽略,无需动线上配置。DataCompare模块仅剩Dto无服务无Controller,HengTaiLiquidationTime全仓无写入点。

保留:Configcolumn.衡泰对账列名常量(可能被DB列配置引用)。dotnet build 0错误
2026-08-22 07:36:48 +08:00
hjhan 5035854ca1 chore(swap): 删除衡泰旧直连方案孤儿DTO——HengTaiModel下22个零引用报文模型+3处无用using
排查背景:UnderlyingEntryFullPriceLeg头注提及"GetUnwindInterestsByHT已随死链清理移除",全仓核实其配套报文模型(SwapTradeReq/SwapPosiReq/ReqQryIRSDbReq等)自拷贝入库起即无任何调用点,属"查询衡泰数据库"旧直连方案残留。存活的风控DTO(ClientRiskCheckReq/Resp)保留,KafkaTask/riskController/QuotaMonitorService的活using不动。

验证:逐类名grep全仓外部引用=0;dotnet build 0错误(编译通过同时证明所删3处using确无类型引用)
2026-08-22 07:35:41 +08:00
hjhan d6c1f192aa chore(web): 删除前端注释死代码——7个脚本文件的注释代码块及孤儿调用链
tradeEndConfirmList.js:两段被注释的main.open2弹窗(生成/批量下载确认书旧交互)、ModifyPayDate三函数簇(唯一入口按钮已被注释,cshtml的myModal弹窗同步删除,BatchDownLoadDoc中仅为死弹窗服务的tip/htmlContent变量一并清理);swapTradeList/SwapflowList/TradeMarketReport×2/structure:散落的注释代码行(旧日期校验/sortGrid/layer.open/表头分组等)。

保留swapTradeEdit.js 440-455的部署踩坑文档注释。行为零变更:node --check×7通过,fe-tests 319/319通过
2026-08-22 07:34:12 +08:00
hjhan 3c7e25820a feat(admin): EQD-5320 邮件模板配置下拉补资金通知书两项——原下拉为cshtml写死HTML仅4个确认书类型,后端AjaxGet/Save按EmailType查存email_template本不限类型;新增追保资金通知书/轧差资金通知书两option,value与bond-oms Java FundEmailHandler查询串一字不差(注释冻结约定),此场景{{文档编号}}/{{交易列表}}渲染为空 2026-08-21 16:55:13 +08:00
hjhan 4fcbc15f05 refactor(web): EQD-5320 清理不可达的互换日终估值导入死代码——#importEod弹窗div与showImport/importEodFile/importClose三函数整块删除:全库无任何按钮调用showImport()(弹窗不可达,业务无从使用),其内部/trs_hub_api/valuationEndOfDay/import直连反代为死代码且是全库最后一处可执行trs_hub_api依赖(剩余引用均为历史注释);bond-oms侧接口不动;如需恢复按BatchSendSettleEmail同款C#代理模式(注释留指引) 2026-08-21 16:01:47 +08:00
hjhan 23a02e06c4 fix(swap): EQD-5320 单行发送Email按钮报'平仓流水id解析为空'——同事fa927b21新增的单行按钮传swap_flow_event.EncryptId(加密串,全站enid惯例),而端点原只按逗号分隔数字解析long.TryParse必败;控制器兼容双形态令牌:非数字即DecryptLong解密(失败返0不抛,非法串忽略),错误文案附原始入参便于定位;批量按钮(数字id)行为不变 2026-08-21 15:41:56 +08:00
hjhan b9968dc80a feat(swap): EQD-6953 后端值域闸门补疑似到期债券判定——IsResultAbsurd新增分支:IsMaturedDegenerate(ytm=0且净/全价均为面值100,抽为public纯函数供单测)命中即返回null+真实原因文案,走既有'宁可不回写'守卫链;判定条件与前端swapCalc.js同款闸门一致(注释互指);新增6个单测(命中/正常券180205实测值/零息平价/息票平价/ytm null/IsResultAbsurd分支接线)全过 2026-08-21 15:29:17 +08:00
hjhan cd981527ab feat(web): EQD-6953 前端值域闸门补疑似到期债券判定——ytm=0且净/全价均为面值100三者同时成立(现实在市券几乎不可能,UAT 060203.IB实证jquantlib空现金流退化形态)时按既有'不回写+toast真实原因'处理,提示核对到期日或手工填写;录入页/平仓页共用此闸门同步生效;判定条件与后端BondCalcHepler.IsMaturedDegenerate同口径(注释已互指);新增4个jest用例(命中/正常券/ytm=0但价格非面值/价格面值但ytm非0)61/61通过 2026-08-21 15:26:46 +08:00
hjhan fa927b2133 fix(zszq-trs): 结算确认书列表新增每行发送邮件按钮,复用 BatchSendSettleEmail
- 新增 tradeEndConfirmSendEmail.js(独立文件降冲突),含纯函数 buildSettleEmailSendPayload 便于单测
- tradeEndConfirmList.js showToolName 加按钮,受 pageData.canSendEmail + ContractDocUrl 控制,跳过"多空组合"
- cshtml 引入新脚本;后端零改动(复用 SwapEndConfirmService.BatchSendSettleEmail -> bond-oms Java)
- 安全: 新按钮不引入新增 XSS/CSRF 暴露; CSRF token 缺失为全站既有问题,与批量按钮同源
2026-08-21 13:21:15 +08:00
hjhan 0567955434 fix(swap): EQD-5320 批量发送确认书改走C#服务端代理——原前端直连/trs_hub_api反向代理在未配nginx的环境404(UAT实测),与计算器(SendConfirmEamil同款BondOmsInterface_BaseUrl服务端出口)通路不一致;新增SwapEndConfirmService.BatchSendSettleEmail(POST代理bond-oms batchSend,契约DTO+成败日志)与SwapTrade2Controller.BatchSendSettleEmail(逗号id串防呆解析);前端改调同源/swaptrade2端点保留error兜底;232/232前端测试通过 2026-08-21 09:40:01 +08:00
hjhan 00ae047e01 docs(swap): EQD-5320 EmailTemplateService补设计守卫注释——占位符朴素替换/不做HTML转义均为有意决策,与bond-oms Java SwapEmailHandler同构,勿单边升级模板引擎或加转义,新占位符两侧同步 2026-08-21 09:24:23 +08:00
hjhan 433bca9530 fix(web): EQD-5320 批量发送确认书按钮点击无反应——$.ajax原无error回调,/trs_hub_api代理不通/超时/返回非JSON(如被登录页重定向)时完全静默;补error回调给HTTP状态+排查指引(控制台同步详错),success兜底非标准返回结构并提示笔数,成功后刷新列表;232/232前端测试通过 2026-08-21 09:16:28 +08:00
hjhan 640c78b5a9 refactor(swap): EQD-6977 trace可读性第二批:①②与p{id}语义化——承接①→已并复利本金(capitalized)、②→段内已计利息(carryIn),日志/类头注/方法注/测试断言四处同步,运维凭日志即知两承接量含义;SwapDealService×12+SwapEodPositionService×1的p{position.id}统一改融资腿{position.id}(FIX GetFloatRate/Resolve/Segments/EodCloseRefix全系列);测试断言同步更新(此前漏查到一处trace断言已一并改);27/27罚息单测通过,Swap全套644例中仅2例DB依赖失败(干净树复验为既有环境问题) 2026-08-21 08:54:47 +08:00
hjhan 9d68e56797 refactor(swap): EQD-6977 罚息trace腿标识p{id}改为融资腿{id}——原缩写p可读性差(用户反馈),全文件9处统一升级;无测试断言/外部消费依赖该字符串,27个罚息单测全过 2026-08-21 08:41:51 +08:00
hjhan 771bd6798b feat(swap): EQD-6977 罚息承接①三分支补全程推导trace——段中平仓+有快照主路径此前零留痕(用户反馈定位难),现打出快照日期/TdInterestPrincipal/share/平仓本金/原始差/钳0结果,原始差为负额外提示疑口径不一致;重置日+有快照补InterestIncomeSum×share推导;无快照兜底补事件基数-平仓本金推导;①异常凭单行日志即可区分快照基数/份额/平仓本金三因;27个罚息单测全过 2026-08-21 08:38:42 +08:00
hjhan 7209ffc16b Merge branch 'glms/feature/1.4.2' of http://git.yiliantech.com/gitlab/otc-dev/zszq-trs into glms/feature/1.4.2 2026-08-21 08:07:39 +08:00
hjhan e8d0a76442 refactor(web): 平仓页收付方向符号显式化unwindLegSign.js+4例单测——裸三元(x==1?±1:∓1)抽为命名函数并冻结业务事实:利息盈亏与保证金返还本金对同一InterestDirection枚举必须反号(利息=买方持有标的向交易商融资的成本,保证金返还=退客户自己交的钱,业务确认非笔误),不变量断言两符号之和恒0,顺手统一必挂;interestPnlSign对利息/保证金两腿通用(changeInterestAmount模板对两类行都绑定,已核实);另删死代码:this.ratio/this.shortRatio数据属性+赋值全库无读取(模板亦无绑定)及注释掉的历史三元;SwapUnwind.cshtml补script标签,两个执行型测试沙箱喂真实模块;行为等价(Number===1与==1对实际入参等价已验证),全套315例绿 2026-08-21 07:17:20 +08:00
hjhan 6e76f1c10d fix(swap): EQD-6977 无preEod兜底①=0且账龄超重置周期补退化告警trace——interestWindowEmpty(当日已结息)早退不重放覆盖种子值时①静默0(重置日分支本有同类告警,段中分支漏)复利每周期并本理应①>0;trace含事件基数/平仓本金两侧对比值+账龄天数+重置周期+疑似成因指向(interestWindowEmpty种子未重放/日终归档缺失)足够事后定位根因;承接块抽为ResolveCompoundCarry私有纯方法(Merge瘦身,三分支数据契约注释随行,行为零变化);TDD先行3例trace钉子:退化必告警(先红)/兜底>0不告警/真首日不告警;罚息域27例+GetInterests入口语义9例全绿 2026-08-21 07:10:04 +08:00
hjhan 8b66875098 test(swap): EQD-6977 罚息兜底补share<1恒等式用例——50%平仓+无preEod场景钉merger复刻GetInterests本金口径的接缝(标的期初全价CalcNotional=posiNotional×closePercent vs 重放基数按closePosiNotionalValue缩放);现有用例全closePercent=1m,两处口径若有偏差在share=1下不可见、share<1时①混入本金差;变异验证:CalcNotional临时忽略closePercent唯此用例红(1败7过)证明鉴别力;RunFee加closePercent参数默认1m存量调用零影响 2026-08-21 07:09:57 +08:00
hjhan 3728d45cc4 test(web): swapPricePrecisionHelper补19例特征测试冻结字符串精确十进制核心——shiftDecimal/roundDecimal/multiplyDecimal/getRule/roundForSubmit/format全golden值断言(0.1×0.2精确0.02、1.005→1.01绕开浮点陷阱、roundDecimal绝对值四舍五入与ExitYtm约定同向、乘法保留小数标度1.5×2=3.0、Bond字段拼错→null回落umprice而Stock回落品种级的不对称冻结);require直连加载替代readFileSync沙箱(可被插桩);覆盖率清单纳入该文件;实锤注释:源码在rootDir外致babel(无transformer)与v8(逃逸路径无法归因,含roots/绝对路径变体实测jest29.7)两提供器覆盖率恒0且门槛不触发,真修需重构rootDir另行立项 2026-08-21 07:09:51 +08:00
hjhan a5a78eab10 feat(swap): EQD-5320 结算确认书邮件链路补定位日志——资金提示/结清确认/生成三条链路此前几乎无日志且存在静默失败:①SendConfirmEamil查不到合同原return空串(前端当已发送)改Error日志+明确返回发送失败原因;②CheckConfirmDoc/CheckSettlementDoc抛错前补打库内trade_contract_r行状态(无行=从未生成/IsValid=false=重生成作废/doc缺失);③DealNoDmaEmail与生成服务两处客户+日期扩张查询补Info日志对齐勾选vs实际处理;④GetFileName物理文件缺失原静默null改Error;⑤生成器未生成交易确认书报错补事件id/客户/平仓日便于关联扩张日志;IYcLogger无Warn统一用Error 2026-08-20 18:14:40 +08:00
hjhan fb9cf9eadd feat(web): EQD-6953 BondController计算器调用补source场景日志——平仓页请求带source=unwind(可选参数向后兼容,录入页不传);BondCalcHepler本就记录完整参数/结果/失败原因,补场景维度即可区分入口定位是参数还是别的问题 2026-08-20 17:41:41 +08:00
hjhan 4bd528f966 feat(web): EQD-6953 平仓页接入期末结算收益率互算——SwapUnwind浮动端新增列(仅普通债券类收益互换,控件/事件/源AUTO REV标识与录入页同款vue-swap-price-input);DP回车→算ExitYtm(4位)、YD回车→反算交割全价并重算平仓盈亏、手填未回车=REV可覆盖;估值日=平仓日,改日期清陈旧值;防御:applyCalcFailure非法driver只清标识防误清交割全价(补回归测试);closePercentInterestRefresh沙箱补UnwindBondCalc mock对齐页面脚本序;209/209通过 2026-08-20 17:38:43 +08:00
hjhan 45d4bc1d26 feat(web): EQD-6953 平仓页DP↔YD互算纯函数库unwindBondCalc.js+17个jest单测——冻结三条易错约定:发计算器展示态直传不×100/ExitYtm四位四舍五入AwayFromZero(确认书导出固定4位不去零)/失败只清对方字段;修复roundExitYtm(null)会被取整成0覆盖手输的隐患(单测拦截);jest覆盖率清单纳入新文件;纯新增零接线,不影响生产 2026-08-20 17:34:52 +08:00
hjhan 71683083ef feat(swap): EQD-6953 平仓期末结算收益率字段载体+结算确认书Excel导出——[NotMapped]ExitYtm随UnwindData进swap_event.EventData(零表结构变更);生成器从浮动腿回读导出固定4位不去零(0.0000);模板nodma_01.xlsx新增S列;命名遵《互换价格字段命名规范决策文档》平仓=Exit(非End/Close/Final) 2026-08-20 17:29:10 +08:00
hjhan 828dc237ab fix(swap): EQD-6977 trace利率来源标签纠偏——固定腿不取价时不再误标定盘取价(UAT tradeId=2450反馈) 2026-08-20 16:21:46 +08:00
hjhan 286a834aa5 fix(swap): EQD-6977 无日终快照时承接①兜底取事件基数——复利重放把 normalEvent.InterestPrincipal 写为末次并本金后基数(=被平份额本金+①),同为实际值;UAT实测(无快照+已有8/19重置)原①=0少算≈3.17元已消除;重置日+无快照退化场景补告警trace;新增兜底路径恒等式测试(23/23) 2026-08-20 16:09:43 +08:00
hjhan 8d7bc1b457 feat(web): EQD-6977 簿记页是否罚息开关(ExtendObj 直绑,保存经既有 JSON.stringify 自动落 ExtendJson) 2026-08-20 15:53:13 +08:00
hjhan 4f1b55b843 feat(web): EQD-6977 平仓页是否罚息下拉(改选即重取利息含罚息) + 其他费用改标签其他费用含罚息 + 预览参数透传(提交经 UnwindData 随 deal 自动回传) 2026-08-20 15:53:13 +08:00
hjhan 5552402a7c feat(swap): EQD-6977 罚息开关簿记默认值管道——TradeExtendJson.IsPenaltyInterest(存量缺省false零回填) + InitUnwind 平仓页带出簿记值 + GetUnwindInterestList 参数透传 2026-08-20 15:53:11 +08:00
hjhan d6646f9c90 fix(swap): EQD-6977 重置日当天平仓承接①修正——快照基数还是上一段的,须改取 InterestIncomeSum(昨日全部待实现于今日并入);新增边界矩阵测试:重置日当天(算尾/不算尾)/重置日前一日/到期日=重置日/锚点偏离(延期腿)/起息日当天,恒等式 22/22 全绿 2026-08-20 15:46:57 +08:00
hjhan ffffe842c6 fix(swap): EQD-6977 罚息精确续接落地——承接量改用实际计息状态(preEod基数+事件实结,弃冻结重放)、锚点统一PosiStartDate、罚息并入既有利息流InterestFee(去独立事件/去is_penalty_interest列及DDL/回退closeList与EOD两处守护)、接缝加eventType==平仓守卫、trace逐腿全程落盘、新增多区间不同定盘恒等式测试(旧冻结重放实现必挂) 2026-08-20 15:11:33 +08:00
hjhan 09660fffea test(swap): EQD-6977 同步金标准测试——删除CalcPenalty valueDate具名实参 2026-08-20 13:37:26 +08:00
hjhan 48ae429fb8 refactor(swap): EQD-6977 消除罚息接缝代码臭味道——CalcPenalty 去掉冗余valueDate参数、ComputeCarryBreakdown 去掉未使用position、GetIntradayUnwindInterests 内联块抽为私有AppendPenaltyInterests 2026-08-20 13:37:24 +08:00
hjhan bb8130698f test(swap): EQD-6977 罚息接缝 headless 单测——固定/浮动腿追加 IsPenaltyInterest 标记 + 承接恒等式(全期=已结+罚息) 2026-08-20 13:23:12 +08:00
hjhan 35a84cd60d feat(swap): EQD-6977 罚息计息接缝——GetIntradayUnwindInterests 按 IsPenaltyInterest 在 GetInterests 返回后追加同构罚息流 2026-08-20 13:23:10 +08:00
hjhan 10a12b7eef fix(swap): EQD-6977 EOD 手动结息守护排除罚息
SaveAutoEodWithCloseInterestPosition 的 manualSettledInterestAmount 求和加 Where(IsPenaltyInterest!=1),防 auto-swap 重算相减时丢失罚息(评审8.1双守护之防御层)。
2026-08-20 12:59:13 +08:00
hjhan 3777022bac fix(swap): EQD-6977 closeList 排除罚息事件
GetUnwindInterests 的 closeList 查询加 IsPenaltyInterest!=1 过滤,使已落库罚息事件不进去重基数,避免当日二次部分平仓时正常利息被错误抵扣。DDL(stage1 Ver-5.7.0)须随发布。
2026-08-20 12:59:12 +08:00
hjhan 99ca8ebf2c refactor(swap): EQD-6977 罚息标志管道——UnwindData/InterestCalcRequest/GetUnwindInterests 透传 isPenaltyInterest
新增 UnwindData.IsPenaltyInterest(bool);InterestCalcRequest 加 IsPenaltyInterest 字段+私有ctor参数+IntradayUnwind 工厂可选参(default false);GetUnwindInterests 加 isPenaltyInterest 可选参并透传 IntradayUnwind。零行为变化,现有调用方经默认值不受影响,Penalty 套件 11/11 通过。
2026-08-20 12:57:29 +08:00
hjhan 11459ed73f feat(swap): EQD-6977 swap_flow_event 增加 is_penalty_interest 列
模型属性 IsPenaltyInterest + Column(is_penalty_interest) 显式映射;增量 DDL 落 DbUpdate/Ver-5.7.0/prod.sql。存量 DEFAULT 0 自动为否。列命名 snake_case 与全表 PascalCase 不一致,评审文档已标注待拍板。
2026-08-20 12:31:43 +08:00
hjhan f712dfc98f refactor(swap): EQD-6977 拆分 CalcPenalty 计息分支提升可读性
将 CalcPenalty 内复利/单利两个 if/else 大块抽为 AccrueCompound/AccrueSimple 私有方法(返回 (accrued, finalBasis)),主体只表达分派+组装事件。签名与行为零变化,Penalty 套件 11/11 通过。
2026-08-20 12:31:41 +08:00
hjhan ed86402aba test(swap): EQD-6977 罚息契约钉死——金标准恒等式(全期=已结+罚息,含不算尾/中段平仓双承接量) + 边界四象限 + 部分平仓 + 冻结取率规则 2026-08-20 11:51:25 +08:00
hjhan 6a32181ef7 feat(swap): EQD-6977 新增 Penalty 罚息模块——冻结利率解析 + 罚息窗口计息器(复用 Accrual 纯函数,产出同构罚息利息流) 2026-08-20 11:51:24 +08:00
hjhan d1985231ee feat(swap): EQD-6977 复利纯函数支持 carryInInterest——窗口前已结利息随首个重置日资本化并持续留在基数(与全窗口重放轨迹严格一致);默认0零行为变化,含数学不变量测试 2026-08-20 11:43:27 +08:00
hjhan 952295a78a fix(fr007): 界面手工录入定盘精度 4→6 位——1.4150% 不再被截成 1.4200%
UAT 实测发现(EQD-6968 测试期间):录入 1.4150 落库变 0.0142。两层拆解:
- ÷100 为设计(界面按百分数录入,SwapflowList.js toNumber(value/100,6) 已传 6 位)
- Math.Round(price,4) 为精度截断:FR007 官方发布百分数下 4 位=小数 6 位,
  4 位舍入只保百分数下 2 位,丢 0.5bp(1 亿本金 7 天约 96 元)
修复:抽 RoundFr007Price(6位) 替换三处 Round(,4),与前端 6 位对齐;
DB 列 double(18,10) 已验证容纳;bond-sync 自动同步链(BigDecimal 全精度透传)
不经此路径零影响。已截断的历史行(如 2026-08-19 的 0.0142)不自愈,需重录。
附带修复 GLMS20260819Fr007TradeDiscoveryTest 编译错误:@"" 逐字字符串内
应用 "" 转义、UnderlyingCode→FutureContractId(实际列名)、EF6 Database.Connection
→ EF Core GetDbConnection()。

验证:SwapFlowFr007EntryPrecisionTest 2/2;全量 985 例 145 败与基线 diff=0
2026-08-19 14:29:16 +08:00
hjhan 43fb83ed00 refactor(swap): relaxedFixingFromDate 改名 exclusionStart——名实归位
该参数诞生于"有价则取/缺价回退"口径(55363e9f 由 exclusionEndDate 改名而来),
自洽化(fafae5ca)后排除日一概不取价,"放宽取价"语义已不存在——名字回到
排除区间本义,并与 FIX 日志既有用词"排除起点"对齐:
- BuildSegmentRates/CalcDailyCompoundInterest/CalcDailySimpleInterest 三签名
  + 全平重放传参点 + 方法摘要补 exclusionStart 参数语义文档
零行为变更。

验证:内存套件 113/113;全量 981 例 145 败与基线 diff=0
2026-08-19 11:41:18 +08:00
hjhan f8049f81f8 refactor(swap): InitInterestDate 删除死子句 td.StartDate>interestStart + 触发场景注释归因修正
分析定谳:interestStart 经三条赋值路径(=开始日/不算头+1天/preSettleDate 且仅当
≥interestStart 才覆盖)恒 ≥ td.StartDate,第二 OR 子句恒 false——死代码删除。
注释归因同时修正两侧旧错误:
- 原注释把"不算头首日"笼统挂在返回 true 上——实际由第一子句
  interestStart>interestEnd 兜住(StartDate+1>StartDate);
- 候选修正案"观察日当日已结息(preSettleDate 覆盖窗口末)"亦不精确——日期相等
  时函数返回 false,当日已结息的利息归零在 GetInterests closeList 净额层;
  只有相等叠加到期日不算尾回拨(endDate-1)才严格大于而触发。
新增三条 InitInterestDate 直测钉边界:不算头首日空窗/同日已结息日期相等非空/
同日已结息+到期日回拨空窗。

验证:GLMS20260817Fr007UnwindMorningTest 36/36;全量 981 例 145 败与基线 diff=0
2026-08-19 11:36:53 +08:00
hjhan 7b70030216 test(swap): 补快照利率携带契约——单利+不算头+有preEod 盲区定谳
该组合此前零覆盖。定谳结论:带 preEod 时 fetchAfter=preEod.ValueDate +
seed=preEod.FloatRate 是设计分工(≤上一日终的重置日沿用快照携带利率,>的重新
取价),与无日终场景的根本区别是种子有正确来源——开始日EOD因窗口为空走正常
取价,快照 FloatRate=开始日定盘(链条起点),并非旧 bug 复发。
- CarryForward_Simple_NoHead_PreEodAtStartCarriesFirstPeriodRate:
  preEod{ValueDate=开始日, FloatRate=开始日定盘} → PricedDates=0(不重复取价)、
  事件利率=快照利率、金额=上日待实现+3天×(spread+快照利率) 精确断言
- Eod_NoHead_StartDay_SnapshotRateCarriesFirstFixing:开始日EOD("00",窗口
  为空)→快照利率=首重置日定盘,钉死携带链条起点
Run 扩展:Outcome 暴露 Svc(取价审计) + BuildPreEod 支持指定利率。

验证:GLMS20260817Fr007UnwindMorningTest 33/33;全量 978 例 145 败与基线 diff=0
2026-08-19 11:31:19 +08:00
hjhan decbd83d0b refactor(swap): 误导布尔 swap 改名 interestWindowEmpty——按"计息窗口为空"本质命名
InitInterestDate 返回 true 的语义是"计息窗口为空→不计利息"(利率与金额归零),
判定只看日期窗口(interestStart>interestEnd)、与事件类型无关;旧名 swap 把
典型原因(互换当日已结息)当成了效果的名字,读者会误读为事件类型判断。
- SwapDealService: GetInterests 局部变量 + GetFloatRate/CalcUnwindInterest/
  InitSwapDealInterest/CalcMarginInterest 四个签名参数及分支/日志/注释同步
- SwapTradeBaseService.InitInterestDate 返回值语义补入 XML 文档
- MarginInterestGoldenReplay/Shadow 测试命名参数同步
零行为变更。

验证:相关套件 51/51;全量 978 例 145 败与基线 diff=0
2026-08-19 11:31:03 +08:00
hjhan 6e2cae7c1f test(swap): EQD-6968 自洽化契约钉死——事件利率确定性+快照再定盘载体+CI_007/008 新口径
- Determinism_NoTail_EventFloatRateIndependentOfPublishTime:尾日价缺(上午) vs
  有(下午)两世界,金额与事件 FloatRate 完全一致(=末段已消费利率0.01425)
- CloseOnly_平仓日为重置日_剩余持仓快照再定盘(+非重置日反例):经 DealInterests
  真路由断言快照 FloatRate=当日新定盘(RefixCalls 计数)——载体职责显式化验收
- CalcFirst 用例去掉 closeRate 免疫 hack:priorValueDate 根治后首重置日恒取价
- CI_007 更名+断言翻转:平仓日=重置日+不算尾 → 事件利率=末段已消费利率(旧);
  原断言(取新定盘)正是被替换的旧口径契约,根因注释留痕 GLMS-JIATT-20260805
- CI_008:本金结转断言保留,利率断言改为末段旧利率

验证:ConsumedInterestScenario 9/9、InterestEodTailSnapshot+Fr007 36/36、
全量 976 例 145 败与基线 diff=0
2026-08-19 11:07:10 +08:00
hjhan fafae5cac0 refactor(swap): EQD-6968 取价口径自洽化——排除日纯跳过+持仓延续重置日显式再定盘
取价规则只由交易属性决定(算不算尾/interest_rule/重置日历),平仓只切窗口:
① BuildSegmentRates 排除日(不算尾尾日)一概不取价(有价也不取)——事件利率恒为
   末段已消费利率,与金额同源、与平仓时刻无关(旧口径下午平仓落库新利率,金额
   却用旧利率,且上午/下午记录不同);金额零变更(排除日本就零消费)。
② GetFloatRate 不算尾重置日不再先试取尾日定盘(原'有价则取'分支删除)。
③ 剩余持仓的新周期利率改由 SwapEodPositionService 显式获取:平仓日恰为重置日
   且剩余>0 时,快照 FloatRate 经 ResolveOngoingResetFixing 再定盘为当日新定盘
   (生产 GetFixingOrThrow,缺价抛——与 ByEod 重置日/EodCheckSettlePrice 同口径;
   原'有价则取'顺带承担此载体职责,现显式分离)。全平/算尾/观察日无需再定盘。
④ 无日终快照播种 priorValueDate 恒=开始日-1:首重置日(=开始日)的定盘覆盖
   [开始日,下一重置日)全部计息日(不算头时 7/7 起仍属首段),必须落在取价窗内。
   原仅算头回拨一天,不算头时首段误用种子利率(靠②的尾日取价回填掩盖,现已根治)。
   '不算头少计一天'仍由计息边界 IncludeStart=false 承担,天数不变、利率归位。
FIX 日志同步:排除日不取价/EodCloseRefix 再定盘 全程可审计。

验证:全量 976 例 145 败与改动前基线失败名单 diff=0;内存套件(含
ContractReferenceOracle 金标准/InterestEodTailSnapshot)全绿
2026-08-19 11:06:52 +08:00
hjhan e779347488 test(swap): EQD-6968 补到期日当天全平补计分支——replayEndDate+1 的尾日取价豁免
relaxedFixingFromDate 的存在理由回归钉死:不算尾时 InitInterestDate 回拨
endDate 一天,最终全平的历史差分重放需补回真实平仓日(replayEndDate=endDate+1),
该边界日定盘经 relaxedFixingFromDate 走"有价则取/缺价跳过"——
否则到期日上午全平被尾日价误拦(EQD-6968 在到期日当天的镜像场景)。
- FinalClose_OnMaturityDay_NoTail_...Succeeds:不算尾+到期日缺价 → 放行
- Guard_FinalClose_OnMaturityDay_Tail_...StillThrows:算尾+到期日缺价 → 仍拦
注:全平重放分支 relaxedFixingFromDate 恒非 null(Red_Compound_FullClose_WithPreEod
已覆盖),本提交补的是 endDate<valueDate 时的 +1 补计子分支。

验证:GLMS20260817Fr007UnwindMorningTest 30/30 内存全绿
2026-08-19 10:53:34 +08:00
hjhan bf2adf0fae test(swap): EQD-6968 补 EOD 收盘归档取价链——此前 settment=true 零覆盖
EOD 不取尾日价靠两道闸:InitInterestDate 到期日回拨(endDate=D-1) +
CalcEodInterest calcToday=false(到期日且不算尾)跳过 ByEod 重算——ByEod 的
isResetDay→ResolveFloatRate 不看 calcLast,任一环回归即到期日收盘重新索要尾日价。
- Eod_NoTail_MaturityDayFr007Missing_Succeeds:不算尾+到期日(重置日)缺价 → 放行
- Eod_Tail_MaturityDayFr007Missing_StillThrows:算尾+到期日缺价 → 仍拦
- Eod_MidTradeResetDayFr007Missing_StillThrows:非到期重置日缺价 → 仍拦
  (盘中重置日新利率被持续持仓消费,ByEod 取价链是真实依赖,不算尾也不豁免)

验证:GLMS20260817Fr007UnwindMorningTest 28/28 内存全绿
2026-08-19 10:53:34 +08:00
hjhan 4d68133dcb test(swap): EQD-6968 补不算头不算尾(00)组合——CalcFirst=false 零覆盖盲区
- Red_Compound_NoHeadNoTail:00+缺平仓日价 → 放行(calcLast 同 false,与 10 同口径)
- CalcFirst_Simple_NoHeadDropsExactlyStartDayInterest:单利下 00 与 10 利息差
  恰好=开始日一天利息(精确断言,钉 CalcFirst 回归)。closeRate 取 7/6 定盘同值,
  免疫既有取价细节——排查中发现:无日终快照+00 时 fetchAfter=interestStart-1 会
  跳过开始日取价、首段利率用种子(GetFloatRate 回写的尾日定盘),与 10 的
  fetchAfter=开始日-1 不同(FIX 日志可复现,niche 场景:首个日终前平仓)。
Run 运行器扩参:settment / exerciseDate(供后续 EOD 与到期日用例)。

验证:GLMS20260817Fr007UnwindMorningTest 25/25 内存全绿
2026-08-19 10:53:34 +08:00
hjhan 54c4bf21c6 test(swap): PrevBizDay 用例对进程内 QDP 日历状态脱敏(修全量运行偶发红)
全量运行实测:其他用例会把 QDP "chn" 日历替换为"全营业日"退化态
(GetNonHolidayDefore(7/19)=7/19 不再回拨周五),三个 PrevBizDay 放行用例
单跑绿、全量红(取价日 7/19 不在市场)。生产库恒有真实日历无此问题。
- Fr007MarketPrevBizDay 同时供回拨日(7/3、7/10、7/17)与退化日(7/5、7/12、7/19)
  两套价——被测对象是取价放宽语义,不是日历本身;
- FixingDayMissing 守卫同时扣 7/17+7/19,两种日历态下都缺价仍拦。
验证:套件 23/23;全量 960 例 145 败与改动前基线失败名单 diff=0,11 个新用例全绿
2026-08-19 09:44:59 +08:00
hjhan 1e6abb4547 refactor(swap): 重置日判定收口 IsResetDay 私有谓词(零行为变更)
EQD-6968 三判定之一的"是否重置日"公式原在 GetFloatRate(days%period) 与
CalcUnwindInterest 当日归周期判定(daysFromStart%rest_days) 各写一遍,
收口为单一谓词;锚点差异(td.StartDate vs position.PosiStartDate,
非初始持仓两锚点可能不同)在注释中显式注记,只收口公式不统一锚点——
统一锚点属行为变更需业务定调。

验证:内存套件 102/102 全绿
2026-08-19 09:33:15 +08:00
hjhan 0418d9f3d3 refactor(swap): InterestCalcMode 算头算尾解析收口至 TradeExtendJson.CalcFirst/CalcLast
三处重复的 StartsWith/EndsWith 字符串解析(GetInterests / InitInterestDate /
SwapEodPositionService EOD平仓后结息)收口为 TradeExtendJson 计算属性:
- [JsonIgnore] 保证 ExtendJson 序列化字节不变;
- InitInterestDate 原写法在 InterestCalcMode 为显式 null 时会 NRE,
  收口后与其他两处 null-安全语义对齐(缺省=算头算尾,实际不可达,属性缺省 11)。
EQD-6968 三判定之一的"算不算尾"至此单点可查。

验证:内存套件 102/102 全绿(GLMS20260817Fr007 23 + Cache 7 + CloseInterest/
InterestScenario/TailSnapshot/EntrySemantics 72)
2026-08-19 09:31:38 +08:00
hjhan 7cfa85a7cc test(swap): EQD-6968 补前一营业日基准组合+算尾非重置日放行(方案一场景2/3落格)
- PrevBizDay_TailCalced×2:算尾(11)+rule=-1+当日(7/20)未发布 → 放行(取价日回拨至7/17已发布)
- PrevBizDay_NoTail:不算尾(10)+rule=-1+当日未发布 → 放行
- PrevBizDay_FixingDayMissing:rule=-1 但取价日(7/17)本身缺价 → 仍拦(真实依赖守卫)
- TailCalced_NonResetDay×2:算尾(11)+当日非重置日(7/22)+当日缺价 → 放行(非重置日不取当日价)
新增 Fr007MarketPrevBizDay 市场:重置日7/6、7/13、7/20 回拨取价日7/3、7/10、7/17

验证:GLMS20260817Fr007UnwindMorningTest 23/23 内存全绿
2026-08-19 09:28:27 +08:00
hjhan f069c38d48 test(swap): EQD-6968 补算尾依赖守卫——重置日缺价仍拦+newCalcLast覆盖算尾仍拦
防'不算尾放宽'误扩到依赖场景(方案一场景4):
- Guard_TailCalced×2:算尾(11)+当日重置日+当日缺价 → 必须仍抛(复利/单利)
- Baseline_TailCalced:算尾+当日有价 → 成功(对照)
- Guard_NewCalcLast:交易10不算尾但本次平仓指定算尾 → effectiveCalcLast=true 仍拦
- Baseline_NewCalcLast:指定算尾+有价 → 成功
Run 运行器扩参:calcMode/interestRule/newCalcLast/market(本提交仅用 calcMode/newCalcLast)

验证:GLMS20260817Fr007UnwindMorningTest 17/17 内存全绿
2026-08-19 09:26:30 +08:00
hjhan e94c8c25e2 Merge branch 'glms/feature/1.4.2' of http://git.yiliantech.com/gitlab/otc-dev/zszq-trs into glms/feature/1.4.2 2026-08-18 20:17:16 +08:00
hjhan 90d1d85b4a test(infra): DbDiagnose 用例库不可达自守卫——真探测一次+进程级缓存结论
原守卫 try 挂在 GetYLDbContext() 上永远打不中(EF context 构造不连库,
Connect Timeout 发生在首个查询),无库裸跑 14 个用例逐个假红且各耗 15s。
改为 DbDiagnoseGuard.RequireTestDb():CanConnect 真探测一次并缓存,
不可达全批 Inconclusive——裸跑不再有假失败噪音,探测成本 14×15s→1×15s。
连上库的机器行为不变(照常真跑)。
2026-08-18 09:58:16 +08:00
hjhan 7a5089555d fix(fr007-cache): 直查命中失效快照+去冗余排序+重载失败保旧快照防重试风暴
- EodPriceQueryService.TryGetPrice: FR007 快照 miss 直查库命中后 Invalidate,
  下次访问整表重载回 O(1),否则该键 TTL 窗口内每次读取都退化为点查
- 移除点查多余的 OrderByDescending(主键等值查询取首行即可)
- Fr007FixingCache.EnsureFresh: 重载失败(DB抖动)保留旧快照不抛并重置TTL时钟
  ——历史定盘不可变旧值依旧正确,同时防重试风暴;版本失效路径不受TTL掩盖
- 补两测试: 重载失败保快照窗口内不重试 / 首次装载失败miss不抛窗口内不重试
2026-08-18 09:33:28 +08:00
hjhan e219bdae18 feat(swap): FR007定盘整表快照缓存——预载全历史O(1)命中,miss不缓存,写侧失效+1min TTL兜底
数据形态:每工作日一行、发布后不变、全历史仅数千行 → 整表快照优于逐键缓存。
① Fr007FixingCache:首次访问批量SELECT全历史进字典,此后读取O(1)零查询;
   快照以引用替换发布(Volatile),读侧无撕裂,重载加锁去抖;
② 负缓存防线:miss(当日~11:15未发布/补录历史)永不进快照,TryGetPrice 回退直查库——
   否则发布后TTL窗口内仍查不到,上午平仓会一直用回退利率;
③ 写侧版本失效:SwapFlowService 新增/修改/删除 FR007 后 Invalidate,下次访问立即
   整表重载不等TTL;其余通用写入口(导入/复制/合成/直改库)靠TTL兜底,可见性≤1分钟;
④ TryGetPrice 仅 FR007 走缓存路由(全仓生产调用方仅 SwapDealService.TryGetFloatRate
   与 Fr007IndexFixer 两处,均定盘链),其他标的照旧直查,零影响;
⑤ YLErpDAL 增加 InternalsVisibleTo("UnitTestProject"),时钟/装载器测试接缝保持 internal。

验证:Fr007FixingCacheTest 5/5(预载命中/miss不缓存/写侧立即生效/TTL过期重载/稳态零重载);
GLMS20260817Fr007UnwindMorningTest 等内存套件 55/55 全绿。
2026-08-18 08:24:21 +08:00
hjhan a97476c4da EQD-6968: 不算尾缺价改沿用已有利率(删期初回退) + 取价决策FIX常驻日志
① GetFloatRate 不算尾缺价不再回退取期初定盘,改沿用已有利率
   (preEod.FloatRate/position.FloatRate)——其返回值仅作 preEod.id==0 的种子
   且会被分段首段强制取价覆盖,期初取价是无消费者的多余DB读且语义误导;
② BuildSegmentRates 等价重排为 if/else-if 结构,注释改"跳过取价/沿用"准确措辞
   (行为不变:排除日有价仍取新利率,缺价沿用上一重置日利率);
③ 防历史bug"取错重置日利率"复发:GetFloatRate/ResolveFloatRate/BuildSegmentRates
   三处取价决策经 SwapCalcTrace.Critical 常驻 Info 落盘——重置日判定、取价日
   (interest_rule回拨)、命中/缺失、不算尾缺价沿用来源、排除日跳过全程可审计;
④ 测试真内存化:Stub 补 GetConsumedInterest=>0 override(复利路径原偷连96库,
   与类注释"内存,不连库"矛盾);一致性断言措辞对齐新语义;
⑤ 修复 SwapDealService.cs 文件头双 BOM 损坏。

验证:GLMS20260817Fr007UnwindMorningTest 12/12 内存全绿;
邻近套件 67过/15败与改动前基线完全一致(15败均为沙箱无96库 Connect Timeout)。
2026-08-18 08:10:30 +08:00
hjhanandClaude Opus 4.7 cb5ba86d85 EQD-6968: 不算尾缺价改沿用已有利率(删期初回退) + 取价决策FIX常驻日志
① GetFloatRate 不算尾缺价不再回退取期初定盘,改沿用已有利率
   (preEod.FloatRate/position.FloatRate)——其返回值仅作 preEod.id==0 的种子
   且会被分段首段强制取价覆盖,期初取价是无消费者的多余DB读且语义误导;
② BuildSegmentRates 等价重排为 if/else-if 结构,注释改"跳过取价/沿用"准确措辞
   (行为不变:排除日有价仍取新利率,缺价沿用上一重置日利率);
③ 防历史bug"取错重置日利率"复发:GetFloatRate/ResolveFloatRate/BuildSegmentRates
   三处取价决策经 SwapCalcTrace.Critical 常驻 Info 落盘——重置日判定、取价日
   (interest_rule回拨)、命中/缺失、不算尾缺价沿用来源、排除日跳过全程可审计;
④ 测试真内存化:Stub 补 GetConsumedInterest=>0 override(复利路径原偷连96库,
   与类注释"内存,不连库"矛盾);一致性断言措辞对齐新语义;
⑤ 修复 SwapDealService.cs 文件头双 BOM 损坏。

验证:GLMS20260817Fr007UnwindMorningTest 12/12 内存全绿;
邻近套件 67过/15败与改动前基线完全一致(15败均为沙箱无96库 Connect Timeout)。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 22:21:55 +08:00
hjhan fb5bbfaa99 test(swap-eod): 场景4 跨日毒链携带守卫改为生产自身 DailyAccrual 不变量(真捕获 mode9 误反推)
- 原引擎级差分版(734683ea)为假绿:固定 obsDate=2026-05-12 在 td.StartDate 重置日判定下恒为重置日,
  basis=notional+priorAccrued 不取 priorNotional(被误反推的 TdInterestPrincipal),故未捕获 bug。
- 现改为直接复用生产单一真相源 SwapEodPositionService:1388 的 TdInterestIncome=DailyAccrual(TdInterestPrincipal,…)
  纯函数:正确本金与“生产实际”本金各算一次 D+1 应计,二者唯一差异即 TdInterestPrincipal;误反推(膨胀~2.3x)
  使 D+1 应计同步膨胀,差远超容差→红。该不变量与重置日/平仓比例无关,稳健。
- 守卫置于单日 TdInterestPrincipal 不变量之前,使其成为首要捕获点(实跑验证:注入 mode9 误反推后
  首失败点即“场景4[跨日] 毒链携带 D+1 应计偏差 -5501.96”,correct=-4126.47 / poisoned=-9628.43)。
- 移除不再使用的 CalcNextDayInterest 引擎级辅助方法。
2026-08-17 18:53:30 +08:00
hjhan 734683eaca test(swap-eod): 场景4 跨日毒链携带断言——引擎级差分(正确本金 vs 生产实际本金各喂一次 GetInterests)
- 前一版在 rollforward eod 层断言 TdInterestPrincipal 被证伪(该 harness 中 DealInterests 收到 eodPosition=null,rollforward eod 恒 0;复利写带符号重放值)——正常日该字段非计息基数载体,断言选错层
- 现改为引擎级差分:partialEod.Clone() 修正 TdInterestPrincipal=expectedTdPrincipal 作对照组,与生产实际 partialEod 各喂 GetInterests(05-12,settment:true),比对次日本金 InterestPrincipal——经 SwapDealService:1045 priorNotional 通道验证携带,容差 max(0.01, 5%)
- 变异验证(已还原):临时令 :1422 守卫放行 mode9 复现 GLMS-20260421-0004 → 三守卫齐红:本文件不变量断言(Expected 212135529.97 / Actual 494982903.27 精确命中历史签名值)、DI_GLMS_20260421_0004、DI_EXCEL_SCENARIO4;还原后 24/24 + 全量 576/566/10/0 复绿
- 生产代码零变更
2026-08-17 18:36:54 +08:00
hjhan c42335363b test(swap-eod): SwapInterestScenario3And4FloatingTest 的 TdInterestPrincipal 改独立不变量(封死假绿)
场景4 原 TdInterestPrincipal 断言 = 生产公式镜像(reverseMode2 ? base*(1-cp)/cp : base),
与生产 if(calcLast && mode2) TdInterestPrincipal *= (1-cp)/cp 逐字同构,永远跟自己一致,
故 mode9 被错误反推(GLMS-20260421-0004 膨胀 ~2.3x)时测试仍绿——假绿。

改为:mode9 用独立 else if 锁死 expected=LastBaseInterestPrincipal(反推前 base),
彻底脱离 reverseMode2 布尔拼写,封死重基线陷阱。已实跑证明:注入 mode9 反推 bug 后
唯一变红 T+1浮动减点算头算尾(实测 TdInterestPrincipal=494982903.27),回滚生产恢复 24/24。
零生产改动。
2026-08-17 18:18:02 +08:00
hjhan 09fa96a93f refactor(swap-eod): L1 类内去重——CopyInterestLegFields/FinalizeInterestEodRoll 收口四 Save* 重复段(行为保真)
- 腿字段拷贝 3 处×14 行 → 入参化 helper(FloatRate 来源随场景传入,勿统一)
- 滚存收尾 4 处 → FinalizeInterestEodRoll(方向源参数化:三处 position、Copy 一处 eodPayPosition,勿统一;Persist 与日志留调用点保持原序)
- 差异保真:WithClose 不设 InterestFeePending;勿缩放注释保留升级
- 安全网:InterestEodTailSnapshotTest 三格尾部快照(AutoSettle/AutoSettleWithClose/CloseOnly,钉值特征化)+ golden 两格 + DI_EXCEL 家族
- 验证:快照 3/3 逐字段一致;全量 SwapModule 576/566/10/0 与去重前基线完全相同
- 注:本提交为工作区被还原后按原编辑重放,验证结果与首次执行一致
2026-08-17 18:15:09 +08:00
hjhan 65a367e139 test(swap-eod): 补 A 三个路由分支断言 DI_BRANCH_003/004/005(经真实 DealInterests 路由器,零生产改动) 2026-08-17 17:43:25 +08:00
hjhan 9ae2e66b75 refactor(swap-eod): L0 纯函数出仓——InterestEodScenario/ResolveInterestScenario/FindObservationInterval 移至独立 InterestEodScenarioDispatch(零行为变更)
- 上帝类减重 42 行;枚举与两个纯函数零实例状态、零 DB 依赖,符合 Accrual/ 既有纯函数迁移模式
- 测试不再继承 TestableSwapEodPositionService(原仅为够到 protected),plain 测试类
- SwapEodPositionService 两处调用点改为 InterestEodScenarioDispatch.FindObservationInterval 限定名
- 编译 0 错误;表驱动 8/8 通过
2026-08-17 17:36:41 +08:00