diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index 70a5e50e..05d0a372 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -712,7 +712,7 @@ namespace YLErp.Modules.SwapModule } // 获取利率 - decimal rate = GetFixedRate(position, unwindDate); + decimal rate = Math.Round(GetFixedRate(position, unwindDate), InterestCalculationPrecision, MidpointRounding.AwayFromZero); // 做精度调整 原数据有精度误差 decimal floatRate = GetFloatRate(position, preEodPosition, td.StartDate.Value, endDate, interestPeriod, swap, positionClone); // 根据场景计算利息 diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js index 6ff80ccc..fa37a9da 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js @@ -42,7 +42,7 @@ var swapPricePrecision = (function (global) { FixingRepoRate: { integerDigits: 2, precision: 4 }, RateYield: {integerDigits: 6, precision: 8}, BondIndex: {integerDigits: 6, precision: 4}, - // TODO: Add InterestYield, BondIndex and GoldFutures after their enum values are confirmed. + }); function normalizeDecimal(value) { @@ -265,6 +265,7 @@ var swapPricePrecision = (function (global) { return rule ? Object.assign({}, options, rule) : Object.assign({}, options); }, format: format, + roundDecimal: roundDecimal, roundForSubmit: function (value, instrumentType, field, storagePrecisionOffset) { const rule = getRule(instrumentType, field); if (value === null || value === undefined || value === '' || !rule) return value; diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js index 7f0e627c..7500c3fd 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js @@ -20,6 +20,18 @@ const inputFormatPosiFeeUnit = Object.freeze({ precision: 6, negative: true, app const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' }); const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, negative: true, append: '', percent: false }); const consPosiFeeType = Object.freeze({ Percent: 0, Unit: 1 }); +const observationRatePrecision = 12; +const roundObservationRate = function (value) { + const rounded = swapPricePrecision.roundDecimal(value, observationRatePrecision); + return rounded === null || rounded === '' ? value : rounded; +}; +const observationRateFromPercent = function (value) { + const rate = roundObservationRate(swapPricePrecision.shiftDecimal(value, -2)); + return rate === null || rate === '' ? value : Number(rate); +}; +const observationRateTextFromPercent = function (value) { + return roundObservationRate(swapPricePrecision.shiftDecimal(value, -2)); +}; const swapPosiFeeCalc = Object.freeze({ normalizeFeeType(feeType) { return Number(feeType) === consPosiFeeType.Unit ? consPosiFeeType.Unit : consPosiFeeType.Percent; @@ -712,6 +724,15 @@ const vue = new Vue({ if (this.trade.trade_extend.ExtendObj.InterestCalcMode == "00" || this.trade.trade_extend.ExtendObj.InterestCalcMode == "10") { date = moment(date).add(-1, 'days').format('YYYY-MM-DD'); } + const serializeSwapIntervals = function (position) { + position.SwapIntervalList.forEach(interval => { + const rate = roundObservationRate(interval.Rate); + if (rate !== null && rate !== '') { + interval.Rate = Number(rate); + } + }); + position.InterestSwapInterval = JSON.stringify(position.SwapIntervalList); + }; this.getSwapList.forEach((x,index) => { if ((x.UnderlyingCode == null || x.UnderlyingCode.length == 0) && x.SwapIntervalList.length == 0) { var interval = { @@ -727,7 +748,7 @@ const vue = new Vue({ return false; } x.FloatRateUnderlyingCode = x.FloatRateUnderlyingCode == "--" ? null : x.FloatRateUnderlyingCode; - x.InterestSwapInterval = JSON.stringify(x.SwapIntervalList); + serializeSwapIntervals(x); thisObj.trade.swap_positions.push(x); }); if (errorcount > 0) { @@ -750,7 +771,7 @@ const vue = new Vue({ } x.FloatRateUnderlyingCode = x.FloatRateUnderlyingCode == "--" ? null : x.FloatRateUnderlyingCode; margin = margin + x.InterestPrincipalFix * (x.InterestDirection == 1 ? 1 : -1); - x.InterestSwapInterval = JSON.stringify(x.SwapIntervalList); + serializeSwapIntervals(x); thisObj.trade.swap_positions.push(x); }); if (errorcount > 0) { @@ -1031,14 +1052,14 @@ const vue = new Vue({ date: _date, SettlementDate: m.format("YYYY-MM-DD"), floatRateCode: floatRateCode, - val: _.toString(val) ? parseFloat(consNumberFormat.umpriceP(val)) : "", + val: _.toString(val) ? swapPricePrecision.shiftDecimal(val, 2) : "", itemChecked: itemChecked, disabled: disabled }; } else { obdate = { date: _date, - val: _.toString(val) ? parseFloat(consNumberFormat.umpriceP(val)) : "", + val: _.toString(val) ? swapPricePrecision.shiftDecimal(val, 2) : "", itemChecked: itemChecked, disabled: disabled }; @@ -1099,7 +1120,7 @@ const vue = new Vue({ if (!isNaN(sm.date())) { _settleDate = sm.format("YYYY-MM-DD"); } - var val = parseFloat(consNumberFormat.umpriceP(thisObj.observation.DefaultTitle1Value)); + var val = swapPricePrecision.shiftDecimal(thisObj.observation.DefaultTitle1Value, 2); var itemChecked = true; var disabled = false; if (_date == thisObj.trade.ExerciseDate) { @@ -1135,7 +1156,7 @@ const vue = new Vue({ if (!isNaN(m.date())) { _date = m.format("YYYY-MM-DD"); } - var val = parseFloat(consNumberFormat.umpriceP(thisObj.observation.DefaultTitle1Value)); + var val = swapPricePrecision.shiftDecimal(thisObj.observation.DefaultTitle1Value, 2); var itemChecked = true; var disabled = false; if (_date == thisObj.trade.ExerciseDate) { @@ -1159,7 +1180,7 @@ const vue = new Vue({ var observationStr = ""; if (this.observation.ObservationDataList != null) { this.observation.ObservationDataList.forEach(item => { - observationStr = observationStr + item.date + ", " + item.SettlementDate + ", " + (item.val * 0.01).toFixed(6) + ", " + item.itemChecked + ";\n"; + observationStr = observationStr + item.date + ", " + item.SettlementDate + ", " + observationRateTextFromPercent(item.val) + ", " + item.itemChecked + ";\n"; }); } this.observation.ObservationInterval = observationStr; @@ -1209,7 +1230,7 @@ const vue = new Vue({ date: values[0], SettlementDate: values[1] || "", floatRateCode: floatRateCode, - val: _.toString(val) ? parseFloat(consNumberFormat.umpriceP(val)) : "", + val: _.toString(val) ? swapPricePrecision.shiftDecimal(val, 2) : "", itemChecked: itemChecked, disabled: disabled } @@ -1289,7 +1310,7 @@ const vue = new Vue({ } var observation = { Date: item.date, - Rate: item.val * 0.01, + Rate: observationRateFromPercent(item.val), Settlement: item.itemChecked ? 1 : 0, SettlementDate: item.SettlementDate || null // 结算日期 }