Merge remote-tracking branch 'origin/glms/feature/1.4.2' into glms/feature/1.4.2

This commit is contained in:
张名锐
2026-07-16 19:55:57 +08:00
10 changed files with 204 additions and 25 deletions
@@ -726,6 +726,30 @@ namespace YLErp.Modules.SwapModule
return (closePrincipal, posiPrincipal, newClosePercent);
}
/// <summary>
/// 平仓比例口径转换(解决"显示占期初 / 计算占剩余"双语义问题)。
/// 前端与事件列表展示用"占期初(original)"语义(A);后端 CalcNotionalByMode / 费用递减 /
/// 全平判定均按"占剩余(remaining)"语义(B)消费。
/// A → BB = A × 期初名义本金(NotionalValue) / 剩余名义本金(PosiNotionalValue),并 cap 到 1。
/// B → A:A = B × 剩余名义本金 / 期初名义本金。
/// 分母为 0(无持仓等异常场景)时原样返回,避免除零。
/// </summary>
public static decimal ToRemainingClosePercent(decimal originalClosePercent, decimal notionalValue, decimal posiNotionalValue)
{
if (posiNotionalValue <= 0) return originalClosePercent;
var remaining = originalClosePercent * notionalValue / posiNotionalValue;
return remaining > 1 ? 1 : remaining;
}
/// <summary>
/// B(占剩余) → A(占期初),用于落库 / 事件列表展示还原。见 ToRemainingClosePercent。
/// </summary>
public static decimal ToOriginalClosePercent(decimal remainingClosePercent, decimal notionalValue, decimal posiNotionalValue)
{
if (notionalValue <= 0) return remainingClosePercent;
return remainingClosePercent * posiNotionalValue / notionalValue;
}
/// <summary>
/// 获取固定利率
/// </summary>
@@ -1226,6 +1250,9 @@ namespace YLErp.Modules.SwapModule
}
//CheckLastEod(unwindData.ValueDate, td.StartDate.Value, unwindData.SwapTradeId); //去掉平仓收盘限制
ValidateFrontendPnL(unwindData, isIncome: false); // 只读校验告警,不阻断交易
// 前端按"占期初(original)"语义传 ClosePercent(A);后端全链路按"占剩余(remaining)"语义(B)消费。
// 入口统一转换为 B,落库展示用的 A 由 SaveSwapDealInternal 还原。
unwindData.ClosePercent = ToRemainingClosePercent(unwindData.ClosePercent, unwindData.NotionalValue, unwindData.PosiNotionalValue);
bool cofirm = false;
ExecuteInTransaction(() =>
{
@@ -1843,7 +1870,13 @@ namespace YLErp.Modules.SwapModule
}
var flowList = new List<swap_flow_event>(unwindData.FlowEvents);
unwindData.FlowEvents.Clear();
// 落库展示用"占期初(original)"语义(A);计算链(费用递减/全平判定)用"占剩余(remaining)"语义(B)。
// 序列化前把 ClosePercent 还原为 A,序列化后立即还原回 B 供后续使用。
var storedClosePercent = ToOriginalClosePercent(unwindData.ClosePercent, unwindData.NotionalValue, unwindData.PosiNotionalValue);
var incomingClosePercent = unwindData.ClosePercent;
unwindData.ClosePercent = storedClosePercent;
string data = JsonConvert.SerializeObject(unwindData);
unwindData.ClosePercent = incomingClosePercent;
var swapEvent = new SwapEventService(this).AddSwapEventDate(unwindData.ValueDate, unwindData.SwapTradeId, eventType, data, clientCashId, true, eventResason);//将平仓、互换总额存入事件
foreach (var item in flowList)
{