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依赖失败(干净树复验为既有环境问题)
This commit is contained in:
@@ -157,40 +157,40 @@ namespace UnitTestProject.Modules.SwapModule.Penalty
|
||||
[TestMethod]
|
||||
public void 无preEod复利段中兜底为零且账龄超重置周期_留退化告警trace()
|
||||
{
|
||||
// 场景:无日终快照 + 复利 + 段中平仓,事件 InterestPrincipal 仍是种子值(=平仓本金)→兜底①=0。
|
||||
// 账龄 25 天 ≥ 7 天重置周期:复利每周期并本理应①>0,①=0 属退化——
|
||||
// 场景:无日终快照 + 复利 + 段中平仓,事件 InterestPrincipal 仍是种子值(=平仓本金)→兜底已并复利本金=0。
|
||||
// 账龄 25 天 ≥ 7 天重置周期:复利每周期并本理应>0,已并复利本金=0 属退化——
|
||||
// 典型成因=interestWindowEmpty(当日已结息)早退未重放覆盖种子、或日终归档缺失。
|
||||
var e = NormalEvent(settledAmount: 50_000m);
|
||||
e.InterestPrincipal = Notional; // GetInterests 种子值:interestWindowEmpty 早退路径不会用重放基数覆盖它
|
||||
var trace = new AccrualTrace();
|
||||
RunMerge(Leg(InterestTypeEnum.复利), e, preEod: null, trace: trace);
|
||||
|
||||
StringAssert.Contains(trace.ToString(), "无preEod兜底①=0",
|
||||
"①=0 且账龄超周期必须留告警,供事后核对日终归档/计息窗口根因");
|
||||
StringAssert.Contains(trace.ToString(), "无preEod兜底已并复利本金=0",
|
||||
"已并复利本金=0 且账龄超周期必须留告警,供事后核对日终归档/计息窗口根因");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void 无preEod兜底为正_不留退化告警()
|
||||
{
|
||||
var e = NormalEvent(settledAmount: 50_000m);
|
||||
e.InterestPrincipal = Notional + 100_000m; // 重放末次并本金后基数 → ①=100000 正常路径
|
||||
e.InterestPrincipal = Notional + 100_000m; // 重放末次并本金后基数 → 已并复利本金=100000 正常路径
|
||||
var trace = new AccrualTrace();
|
||||
RunMerge(Leg(InterestTypeEnum.复利), e, preEod: null, trace: trace);
|
||||
|
||||
Assert.IsFalse(trace.ToString().Contains("兜底①=0"), "①>0 是正常兜底路径,不得告警");
|
||||
Assert.IsFalse(trace.ToString().Contains("兜底已并复利本金=0"), "已并复利本金>0 是正常兜底路径,不得告警");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void 无preEod真首日兜底为零_不留退化告警()
|
||||
{
|
||||
var p = Leg(InterestTypeEnum.复利);
|
||||
p.PosiStartDate = UnwindDate; // 起息日当天平仓:账龄 0 < 重置周期,①=0 是设计内约定(类头注)
|
||||
p.PosiStartDate = UnwindDate; // 起息日当天平仓:账龄 0 < 重置周期,已并复利本金=0 是设计内约定(类头注)
|
||||
var e = NormalEvent(settledAmount: 50_000m);
|
||||
e.InterestPrincipal = Notional;
|
||||
var trace = new AccrualTrace();
|
||||
RunMerge(p, e, preEod: null, trace: trace);
|
||||
|
||||
Assert.IsFalse(trace.ToString().Contains("兜底①=0"), "真首日 ①=0 合法,不得告警");
|
||||
Assert.IsFalse(trace.ToString().Contains("兜底已并复利本金=0"), "真首日 已并复利本金=0 合法,不得告警");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace YLErp.Modules.SwapModule.Penalty;
|
||||
/// getSpread(加点利差)/ getPreEod(上一日终快照行)/ tryGetFixing(定盘取价),本类零 DB 耦合、可 headless 单测。
|
||||
///
|
||||
/// 复利承接量(精确续接口径的关键)**必须取实际计息状态**,严禁冻结利率重放推导:
|
||||
/// 承接① capitalized = max(0, preEod.TdInterestPrincipal×份额 − closePrincipal) —— 实际滚动复利基数中已并入部分;
|
||||
/// 承接② carryIn = 正常平仓流实结 InterestAmount − ① —— 最近重置日后实际已计利息;
|
||||
/// 无 preEod(首日平仓):①=0、②=实结金额。
|
||||
/// 已并复利本金 capitalized = max(0, preEod.TdInterestPrincipal×份额 − closePrincipal) —— 实际滚动复利基数中已并入部分;
|
||||
/// 段内已计利息 carryIn = 正常平仓流实结 InterestAmount − 已并复利本金 —— 最近重置日后实际已计利息;
|
||||
/// 无 preEod(首日平仓):已并复利本金=0、段内已计利息=实结金额。
|
||||
/// 逐腿全程 trace 落盘(SwapCalcTrace),供计算过程分析与错误定位。
|
||||
/// </summary>
|
||||
public static class PenaltyInterestFeeMerger
|
||||
@@ -48,7 +48,7 @@ public static class PenaltyInterestFeeMerger
|
||||
|
||||
foreach (var position in fundingPositions)
|
||||
{
|
||||
// 正常平仓利息流(GetInterests 刚产出)——承接②的事实源与罚息并入目标
|
||||
// 正常平仓利息流(GetInterests 刚产出)——段内已计利息的事实源与罚息并入目标
|
||||
var normalEvent = interests.FirstOrDefault(x => x.PositionId == position.id);
|
||||
if (normalEvent == null)
|
||||
{
|
||||
@@ -92,7 +92,7 @@ public static class PenaltyInterestFeeMerger
|
||||
continue;
|
||||
}
|
||||
|
||||
// 复利承接:实际滚动基数中已并入部分(①)+ 段内实际已计利息(②)。单利无并本金语义恒 0。
|
||||
// 复利承接:实际滚动基数中已并入部分(已并复利本金)+ 段内实际已计利息(段内已计利息)。单利无并本金语义恒 0。
|
||||
var (capitalized, carryIn) = isCompound
|
||||
? ResolveCompoundCarry(position, normalEvent, preEod, closePrincipal, share, unwindDate, trace)
|
||||
: (0m, 0m);
|
||||
@@ -115,18 +115,18 @@ public static class PenaltyInterestFeeMerger
|
||||
$"窗口=[{unwindDate:yyyy-MM-dd}→{maturityDate:yyyy-MM-dd}] 平仓日已结={unwindDaySettled} 到期算尾={maturityCalcLast} | " +
|
||||
$"本金 close={closePrincipal:F2} posi={r.PosiPrincipal:F2} share={share:P4} | " +
|
||||
$"冻结利率={frozenRate.AllInRate:P6} 来源={rateSource} | " +
|
||||
$"承接①={capitalized:F4} ②={carryIn:F4} 实结={normalEvent.InterestAmount:F4} | " +
|
||||
$"承接[已并复利本金]={capitalized:F4} [段内已计利息]={carryIn:F4} 实结={normalEvent.InterestAmount:F4} | " +
|
||||
$"罚息={penalty:F2} → InterestFee {feeBefore:F2}→{normalEvent.InterestFee:F2} PnL含罚息={normalEvent.InterestClosePnL:F2}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复利承接量:① 实际滚动基数中已并入部分 + ② 最近重置日后实际已计利息(= 实结 − ①)。
|
||||
/// 复利承接量:已并复利本金(实际滚动基数中已并入部分)+ 段内已计利息(最近重置日后实际已计,= 实结 − 已并复利本金)。
|
||||
///
|
||||
/// ① 的取值依赖平仓日是否为重置日、有无日终快照(数据契约):
|
||||
/// 段中平仓 + 有快照:TdInterestPrincipal 即当前段滚动基数(=本金+①),直接作差;
|
||||
/// 已并复利本金的取值依赖平仓日是否为重置日、有无日终快照(数据契约):
|
||||
/// 段中平仓 + 有快照:TdInterestPrincipal 即当前段滚动基数(=本金+已并复利本金),直接作差;
|
||||
/// 段中平仓 + 无快照:兜底取 normalEvent.InterestPrincipal——复利重放(CalcDailyCompoundInterest)
|
||||
/// 会把它写为末次并本金后的基数(=被平份额本金+①),同样是实际值而非推导值;
|
||||
/// 会把它写为末次并本金后的基数(=被平份额本金+已并复利本金),同样是实际值而非推导值;
|
||||
/// 重置日当天平仓:快照基数仍是【上一段】的(今日并入尚未发生),须改取
|
||||
/// preEod.InterestIncomeSum(昨日全部待实现利息 = 今日并入新段基数的那部分)。
|
||||
/// </summary>
|
||||
@@ -143,41 +143,41 @@ public static class PenaltyInterestFeeMerger
|
||||
capitalized = (preEod?.InterestIncomeSum ?? 0m) * share;
|
||||
if (preEod != null)
|
||||
trace?.Note(
|
||||
$"PENALTY|融资腿{position.id} 承接①推导 重置日平仓+有快照:快照{preEod.ValueDate:yyyy-MM-dd} " +
|
||||
$"昨日待实现利息InterestIncomeSum={preEod.InterestIncomeSum:F4} ×share={share:P4} → ①={capitalized:F4}");
|
||||
$"PENALTY|融资腿{position.id} 承接量推导(已并复利本金) 重置日平仓+有快照:快照{preEod.ValueDate:yyyy-MM-dd} " +
|
||||
$"昨日待实现利息InterestIncomeSum={preEod.InterestIncomeSum:F4} ×share={share:P4} → 已并复利本金={capitalized:F4}");
|
||||
if (preEod == null && (unwindDate - position.PosiStartDate).Days >= periodDays)
|
||||
trace?.Note($"PENALTY|融资腿{position.id} 注意 无preEod且平仓日=重置日:①退化0(此前重置并入额缺失,请核对日终归档完整性)");
|
||||
trace?.Note($"PENALTY|融资腿{position.id} 注意 无preEod且平仓日=重置日:已并复利本金退化0(此前重置并入额缺失,请核对日终归档完整性)");
|
||||
}
|
||||
else if (preEod != null)
|
||||
{
|
||||
// 段中平仓+有快照(复利承接主路径):① = 快照滚动基数×份额 − 平仓本金。全程留推导——
|
||||
// ①异常时凭此行即可区分"快照基数错 / share错 / 平仓本金错"三因,不必反推。
|
||||
// 段中平仓+有快照(复利承接主路径):已并复利本金 = 快照滚动基数×份额 − 平仓本金。全程留推导——
|
||||
// 结果异常时凭此行即可区分"快照基数错 / share错 / 平仓本金错"三因,不必反推。
|
||||
var rawCarry = preEod.TdInterestPrincipal * share - closePrincipal;
|
||||
capitalized = Math.Max(0m, rawCarry);
|
||||
trace?.Note(
|
||||
$"PENALTY|融资腿{position.id} 承接①推导 段中平仓+有快照:快照{preEod.ValueDate:yyyy-MM-dd} " +
|
||||
$"滚动基数TdInterestPrincipal={preEod.TdInterestPrincipal:F4} ×share={share:P4} −平仓本金{closePrincipal:F4} = {rawCarry:F4} → ①={capitalized:F4}" +
|
||||
$"PENALTY|融资腿{position.id} 承接量推导(已并复利本金) 段中平仓+有快照:快照{preEod.ValueDate:yyyy-MM-dd} " +
|
||||
$"滚动基数TdInterestPrincipal={preEod.TdInterestPrincipal:F4} ×share={share:P4} −平仓本金{closePrincipal:F4} = {rawCarry:F4} → 已并复利本金={capitalized:F4}" +
|
||||
(rawCarry < 0m ? "(原始差为负已钳0:快照滚动基数×份额小于平仓本金,疑部分平仓比例与快照归档口径不一致,请核对eod_swap_position.TdInterestPrincipal)" : ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
capitalized = Math.Max(0m, normalEvent.InterestPrincipal - closePrincipal);
|
||||
trace?.Note(
|
||||
$"PENALTY|融资腿{position.id} 承接①推导 段中平仓+无快照兜底:事件基数InterestPrincipal={normalEvent.InterestPrincipal:F4} −平仓本金{closePrincipal:F4} → ①={capitalized:F4}");
|
||||
// 兜底①=0 但账龄已过重置周期:复利每周期并本,理应 ①>0——多为 interestWindowEmpty
|
||||
$"PENALTY|融资腿{position.id} 承接量推导(已并复利本金) 段中平仓+无快照兜底:事件基数InterestPrincipal={normalEvent.InterestPrincipal:F4} −平仓本金{closePrincipal:F4} → 已并复利本金={capitalized:F4}");
|
||||
// 兜底已并复利本金=0 但账龄已过重置周期:复利每周期并本,理应 >0——多为 interestWindowEmpty
|
||||
// (当日已结息)早退未重放覆盖种子值、或日终归档缺失。留痕含两侧基数与账龄,供直接定位根因。
|
||||
var ageDays = (unwindDate - position.PosiStartDate).Days;
|
||||
if (capitalized == 0m && ageDays >= periodDays)
|
||||
trace?.Note(
|
||||
$"PENALTY|融资腿{position.id} 注意 无preEod兜底①=0但账龄{ageDays}天≥重置周期{periodDays}天:" +
|
||||
$"PENALTY|融资腿{position.id} 注意 无preEod兜底已并复利本金=0但账龄{ageDays}天≥重置周期{periodDays}天:" +
|
||||
$"事件基数{normalEvent.InterestPrincipal:F2}=平仓本金{closePrincipal:F2}(疑似interestWindowEmpty种子未重放/日终归档缺失," +
|
||||
$"请核对swap_flow_event.InterestPrincipal重放回写与eod_swap_position归档)");
|
||||
}
|
||||
|
||||
// ① 不得超过实结金额(数据异常时钳制并留痕,避免负②进入计息)
|
||||
// 已并复利本金不得超过实结金额(数据异常时钳制并留痕,避免负的段内已计利息进入计息)
|
||||
if (capitalized > Math.Max(0m, normalEvent.InterestAmount))
|
||||
{
|
||||
trace?.Note($"PENALTY|融资腿{position.id} 注意 承接①钳制:推导 {capitalized:F4} > 实结 {normalEvent.InterestAmount:F4}(快照/事件数据异常,请核对 preEod.TdInterestPrincipal/InterestIncomeSum)");
|
||||
trace?.Note($"PENALTY|融资腿{position.id} 注意 承接已并复利本金钳制:推导 {capitalized:F4} > 实结 {normalEvent.InterestAmount:F4}(快照/事件数据异常,请核对 preEod.TdInterestPrincipal/InterestIncomeSum)");
|
||||
capitalized = Math.Max(0m, normalEvent.InterestAmount);
|
||||
}
|
||||
return (capitalized, normalEvent.InterestAmount - capitalized);
|
||||
|
||||
@@ -905,13 +905,13 @@ namespace YLErp.Modules.SwapModule
|
||||
isResetDay ? endDate : startDate, position.interest_rule);
|
||||
// 历史上有"取错重置日利率"的线上 bug,取价决策必须常驻落盘(SwapCalcTrace.Critical 无条件 Info)。
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX GetFloatRate p{position.id} [{startDate:yyyy-MM-dd}→{endDate:yyyy-MM-dd}] days={days} period={period} " +
|
||||
$"FIX GetFloatRate 融资腿{position.id} [{startDate:yyyy-MM-dd}→{endDate:yyyy-MM-dd}] days={days} period={period} " +
|
||||
$"重置日={isResetDay} rule={position.interest_rule} 取价日={rateDate:yyyy-MM-dd} calcLast={calcLast} " +
|
||||
$"preEod={(preEod.id != 0 ? $"{preEod.ValueDate:yyyy-MM-dd}:{preEod.FloatRate:P6}" : "无")}");
|
||||
|
||||
if (preEod.id != 0 && !isResetDay)
|
||||
{
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate p{position.id} 非重置日→沿用昨日终FloatRate={preEod.FloatRate:P6}");
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate 融资腿{position.id} 非重置日→沿用昨日终FloatRate={preEod.FloatRate:P6}");
|
||||
position.FloatRate = positionClone.FloatRate = preEod.FloatRate;
|
||||
return preEod.FloatRate;
|
||||
}
|
||||
@@ -923,13 +923,13 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
var keptNoFetch = preEod.id != 0 ? preEod.FloatRate : position.FloatRate;
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX GetFloatRate p{position.id} 不算尾重置日→不取尾日定盘,沿用已有利率={keptNoFetch:P6}(来源={(preEod.id != 0 ? "preEod.FloatRate" : "position.FloatRate")})");
|
||||
$"FIX GetFloatRate 融资腿{position.id} 不算尾重置日→不取尾日定盘,沿用已有利率={keptNoFetch:P6}(来源={(preEod.id != 0 ? "preEod.FloatRate" : "position.FloatRate")})");
|
||||
return keptNoFetch;
|
||||
}
|
||||
|
||||
if (IndexFixer.TryGetFixing(rateDate, position.FloatRateUnderlyingCode, out decimal rate))
|
||||
{
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate p{position.id} 重置日→取{rateDate:yyyy-MM-dd}定盘={rate:P6}");
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate 融资腿{position.id} 重置日→取{rateDate:yyyy-MM-dd}定盘={rate:P6}");
|
||||
position.FloatRate = positionClone.FloatRate = rate;
|
||||
return position.FloatRate;
|
||||
}
|
||||
@@ -937,17 +937,17 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
if (calcLast)
|
||||
{
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate p{position.id} {rateDate:yyyy-MM-dd}缺价且算尾→抛异常拦截");
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate 融资腿{position.id} {rateDate:yyyy-MM-dd}缺价且算尾→抛异常拦截");
|
||||
throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{rateDate:yyyy年MM月dd日}的价格");
|
||||
}
|
||||
// 算头不算尾(calcLast=false):endDate 当天不计息,其 FR007 利率不参与计息,
|
||||
// 缺价时直接沿用已有利率,不回退取其他日期利率,不告警。
|
||||
var kept = preEod.id != 0 ? preEod.FloatRate : position.FloatRate;
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX GetFloatRate p{position.id} {rateDate:yyyy-MM-dd}缺价且不算尾→沿用已有利率={kept:P6}(来源={(preEod.id != 0 ? "preEod.FloatRate" : "position.FloatRate")})");
|
||||
$"FIX GetFloatRate 融资腿{position.id} {rateDate:yyyy-MM-dd}缺价且不算尾→沿用已有利率={kept:P6}(来源={(preEod.id != 0 ? "preEod.FloatRate" : "position.FloatRate")})");
|
||||
return kept;
|
||||
}
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate p{position.id} 计息窗口为空→利率不参与,返回0");
|
||||
SwapCalcTrace.Critical($"FIX GetFloatRate 融资腿{position.id} 计息窗口为空→利率不参与,返回0");
|
||||
return 0m;
|
||||
}
|
||||
|
||||
@@ -1376,15 +1376,15 @@ namespace YLErp.Modules.SwapModule
|
||||
if (fixing != 0m)
|
||||
{
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX Resolve p{position.id} {date:yyyy-MM-dd}(取价日={fixingDate:yyyy-MM-dd} rule={position.interest_rule})→定盘={fixing:P6}");
|
||||
$"FIX Resolve 融资腿{position.id} {date:yyyy-MM-dd}(取价日={fixingDate:yyyy-MM-dd} rule={position.interest_rule})→定盘={fixing:P6}");
|
||||
return fixing;
|
||||
}
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX Resolve p{position.id} {date:yyyy-MM-dd}(取价日={fixingDate:yyyy-MM-dd})→定盘=0视为缺价,沿用fallback={fallback:P6}");
|
||||
$"FIX Resolve 融资腿{position.id} {date:yyyy-MM-dd}(取价日={fixingDate:yyyy-MM-dd})→定盘=0视为缺价,沿用fallback={fallback:P6}");
|
||||
return fallback;
|
||||
}
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX Resolve p{position.id} {date:yyyy-MM-dd}(取价日={fixingDate:yyyy-MM-dd} rule={position.interest_rule})→缺价,抛异常");
|
||||
$"FIX Resolve 融资腿{position.id} {date:yyyy-MM-dd}(取价日={fixingDate:yyyy-MM-dd} rule={position.interest_rule})→缺价,抛异常");
|
||||
throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fixingDate:yyyy年MM月dd日}的价格");
|
||||
}
|
||||
|
||||
@@ -1403,7 +1403,7 @@ namespace YLErp.Modules.SwapModule
|
||||
var calcDays = (endDate - startDate).Days;
|
||||
decimal currentFloat = initialFloat;
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX Segments p{position.id} [{startDate:yyyy-MM-dd}→{endDate:yyyy-MM-dd}] period={interestPeriod} " +
|
||||
$"FIX Segments 融资腿{position.id} [{startDate:yyyy-MM-dd}→{endDate:yyyy-MM-dd}] period={interestPeriod} " +
|
||||
$"fetchAfter={(fetchAfterDate?.ToString("yyyy-MM-dd") ?? "全程")} calcLast={calcLast} " +
|
||||
$"排除起点={(exclusionStart?.ToString("yyyy-MM-dd") ?? (calcLast ? "无" : endDate.ToString("yyyy-MM-dd")))} seed={initialFloat:P6} spread={spread:P6}");
|
||||
for (int i = 0; i <= calcDays; i += interestPeriod)
|
||||
@@ -1422,7 +1422,7 @@ namespace YLErp.Modules.SwapModule
|
||||
else if (needFetch && isExcludedEnd)
|
||||
{
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX Segment p{position.id} {resetDate:yyyy-MM-dd} 排除日(不计息)→不取价,沿用末段={currentFloat:P6}");
|
||||
$"FIX Segment 融资腿{position.id} {resetDate:yyyy-MM-dd} 排除日(不计息)→不取价,沿用末段={currentFloat:P6}");
|
||||
}
|
||||
rates.Add((resetDate, spread + currentFloat));
|
||||
}
|
||||
|
||||
@@ -1380,7 +1380,7 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
var ongoingFixing = ResolveOngoingResetFixing(position, valueDate);
|
||||
SwapCalcTrace.Critical(
|
||||
$"FIX EodCloseRefix p{position.id} {valueDate:yyyy-MM-dd} 平仓日=重置日→剩余持仓快照再定盘 {newEodPayPosition.FloatRate:P6}→{ongoingFixing:P6}");
|
||||
$"FIX EodCloseRefix 融资腿{position.id} {valueDate:yyyy-MM-dd} 平仓日=重置日→剩余持仓快照再定盘 {newEodPayPosition.FloatRate:P6}→{ongoingFixing:P6}");
|
||||
newEodPayPosition.FloatRate = ongoingFixing;
|
||||
}
|
||||
//利息端估值用信息
|
||||
|
||||
Reference in New Issue
Block a user