#EQD-5718 【缺陷转需求】-国联民生-利息端计息方式与结算规则扩充

This commit is contained in:
吴方海
2026-05-08 15:09:58 +08:00
parent 689616820a
commit 95686f4c4d
14 changed files with 2227 additions and 242 deletions
@@ -1,4 +1,4 @@
//otcformat禁止千分位分组
//otcformat禁止千分位分组
window.otcformat.options.disableGrouping = true;
const consClients = ylotc.clients;
@@ -126,6 +126,8 @@ const vue = new Vue({
ObservationUnit: 'D',
ObservationHolidayType: 'Following',
ObservationAlignEnd: true,
ObservationCalendar: 'Chn',
ObservationSettlementRules: 0,
DefaultTitle1Value: 0.1,
ObservationDataList: [],
CheckedAll: false,
@@ -344,7 +346,7 @@ const vue = new Vue({
}
x.SwapIntervalList.push(interval);
}
if (x.InterestType == 1 && x.interest_rest_days<=0) {
if (x.interest_rest_days != null && x.interest_rest_days <= 0) {
main.message("利息端第" + (index + 1) + "行重置频率必须大于0");
errorcount++;
return false;
@@ -461,9 +463,7 @@ const vue = new Vue({
}
},
changeInterestType(item) {
if (item.InterestType == 0) {
item.interest_rest_days = null;
} else {
if (!item.interest_rest_days) {
item.interest_rest_days = 1;
}
},
@@ -553,7 +553,7 @@ const vue = new Vue({
arr[index].Rate = swapRate;
});
var observationDates = JSON.stringify(item.SwapIntervalList);
item.SwapIntervals = observationDates;
item.InterestSwapInterval = observationDates;
});
} else {
@@ -582,6 +582,10 @@ const vue = new Vue({
thisObj.observation.ObservationUnit = observation ? observation.ObservationUnit : 'D';
thisObj.observation.ObservationHolidayType = observation ? observation.ObservationHolidayType : 'Following';
thisObj.observation.ObservationAlignEnd = observation ? observation.ObservationAlignEnd : true;
if (type == 1) {
thisObj.observation.ObservationCalendar = observation ? observation.ObservationCalendar : 'Chn';
thisObj.observation.ObservationSettlementRules = observation ? observation.ObservationSettlementRules : 0;
}
thisObj.observation.IsDeductPrincipal = observation ? observation.IsDeductPrincipal : true;
if (type == 0) {
thisObj.observation.IsDeductPrincipal = false;
@@ -603,6 +607,7 @@ const vue = new Vue({
thisObj.observation.ObservationStart = endTime;
}
thisObj.observation.ObservationDataList = [];
var floatRateCode = type == 1 ? (item.FloatRateUnderlyingCode || '--') : '';
thisObj.observation.IntervalList.forEach((value, num, arr) => {
var val = value.Rate;
var _date = "";
@@ -616,24 +621,47 @@ const vue = new Vue({
disabled = true;
itemChecked = false;
}
var obdate = {
date: _date,
val: _.toString(val) ? parseFloat(consNumberFormat.umpriceP(val)) : "",
itemChecked: itemChecked,
disabled: disabled
var obdate = {};
if (type == 1) {
var SettlementDate = value.Date;
if (value.SettlementDate!=null) {
SettlementDate = value.SettlementDate;
}
obdate = {
date: _date,
SettlementDate: _date,
floatRateCode: floatRateCode,
val: _.toString(val) ? parseFloat(consNumberFormat.umpriceP(val)) : "",
itemChecked: itemChecked,
disabled: disabled
};
} else {
obdate = {
date: _date,
val: _.toString(val) ? parseFloat(consNumberFormat.umpriceP(val)) : "",
itemChecked: itemChecked,
disabled: disabled
};
}
thisObj.observation.ObservationDataList.push(obdate);
});
// thisObj.initObservationCheckedAll();
var area = type == 1 ? ['800px', '600px'] : ['750px', '600px'];
layer.open({
type: 1,
area: ['580px', '560px'],
area: area,
title: "设置互换日期",
shadeClose: false,
shade: 0.4,
content: $("#observationInfosEdit")
});
},
//计算结算日期
calcSettleDate(observationDate, settlementRules) {
if (!observationDate) return "";
var m = new moment(observationDate);
var settleDate = m.add(settlementRules, 'days').format("YYYY-MM-DD");
return settleDate;
},
//生成观察日操作
GetObservationDates() {
var thisObj = this;
@@ -641,43 +669,97 @@ const vue = new Vue({
var observationUnit = thisObj.observation.ObservationUnit;
var observationHolidayType = thisObj.observation.ObservationHolidayType;
var alignEnd = thisObj.observation.ObservationAlignEnd;
var postData = {
startDate: thisObj.observation.ObservationStart, endDate: thisObj.trade.ExerciseDate, termStr: observationNum + observationUnit,
holidayAdjustment: observationHolidayType, alignEnd: alignEnd, calcMode: thisObj.trade.trade_swap.RateCalcMode
};
var settlementRules = thisObj.observation.ObservationSettlementRules;
var calendar = thisObj.observation.ObservationCalendar;
var floatRateCode = this.observationType == 1 ? (thisObj.getSwapList[thisObj.observation.index]?.FloatRateUnderlyingCode || '--') : '';
thisObj.observation.ObservationDataList = [];
main.post("/trade/GetObservationDateList", postData).done(
function (res) {
$.each(res.obj, function (i) {
var _date = "";
var m = new moment(this);
if (!isNaN(m.date())) {
_date = m.format("YYYY-MM-DD");
}
var val = parseFloat(consNumberFormat.umpriceP(thisObj.observation.DefaultTitle1Value));
var itemChecked = true;
var disabled = false;
if (_date == thisObj.trade.ExerciseDate) {
disabled = true;
itemChecked = false;
}
var obdate = {
date: _date,
val: val,
itemChecked: itemChecked,
disabled: disabled
}
thisObj.observation.ObservationDataList.push(obdate);
if (this.observationType == 1) {
var postData = {
startDate: thisObj.observation.ObservationStart,
endDate: thisObj.trade.ExerciseDate,
termStr: observationNum + observationUnit,
holidayAdjustment: observationHolidayType,
alignEnd: alignEnd,
calcMode: thisObj.trade.trade_swap.RateCalcMode,
calendar: calendar,
settlementRules: settlementRules
};
main.post("/trade/GetSwapObservationDateList", postData).done(
function (res) {
$.each(res.obj, function (i) {
var _date = "";
var m = new moment(this.ObservationDate);
if (!isNaN(m.date())) {
_date = m.format("YYYY-MM-DD");
}
var _settleDate = "";
var sm = new moment(this.SettleDate);
if (!isNaN(sm.date())) {
_settleDate = sm.format("YYYY-MM-DD");
}
var val = parseFloat(consNumberFormat.umpriceP(thisObj.observation.DefaultTitle1Value));
var itemChecked = true;
var disabled = false;
if (_date == thisObj.trade.ExerciseDate) {
disabled = true;
itemChecked = false;
}
var obdate = {
date: _date,
SettlementDate: _settleDate,
floatRateCode: floatRateCode,
val: val,
itemChecked: itemChecked,
disabled: disabled
};
thisObj.observation.ObservationDataList.push(obdate);
});
thisObj.initObservationCheckedAll();
});
thisObj.initObservationCheckedAll();
});
} else {
var postData = {
startDate: thisObj.observation.ObservationStart,
endDate: thisObj.trade.ExerciseDate,
termStr: observationNum + observationUnit,
holidayAdjustment: observationHolidayType,
alignEnd: alignEnd,
calcMode: thisObj.trade.trade_swap.RateCalcMode
};
main.post("/trade/GetObservationDateList", postData).done(
function (res) {
$.each(res.obj, function (i) {
var _date = "";
var m = new moment(this);
if (!isNaN(m.date())) {
_date = m.format("YYYY-MM-DD");
}
var val = parseFloat(consNumberFormat.umpriceP(thisObj.observation.DefaultTitle1Value));
var itemChecked = true;
var disabled = false;
if (_date == thisObj.trade.ExerciseDate) {
disabled = true;
itemChecked = false;
}
var obdate = {
date: _date,
val: val,
itemChecked: itemChecked,
disabled: disabled
};
thisObj.observation.ObservationDataList.push(obdate);
});
thisObj.initObservationCheckedAll();
});
}
},
//编辑观察日功能数据处理
SetObservationDates() {
var observationStr = "";
if (this.observation.ObservationDataList != null) {
this.observation.ObservationDataList.forEach(item => {
observationStr = observationStr + item.date + ", " + (item.val * 0.01).toFixed(6) + ", " + item.itemChecked + ";\n";
observationStr = observationStr + item.date + ", " + item.SettlementDate + ", " + (item.val * 0.01).toFixed(6) + ", " + item.itemChecked + ";\n";
});
}
this.observation.ObservationInterval = observationStr;
@@ -712,18 +794,21 @@ const vue = new Vue({
var observationDates = thisObj.observation.ObservationInterval;
var items = observationDates.split(";").filter(o => o);
thisObj.observation.ObservationDataList = [];
var floatRateCode = thisObj.getSwapList[thisObj.observation.index]?.FloatRateUnderlyingCode || '--';
items.forEach(function (item) {
if (item) {
var values = item.split(",");
var itemChecked = JSON.parse(values[2].trim());
var itemChecked = JSON.parse(values[3].trim());
var disabled = false;
if (values[0] == thisObj.trade.ExerciseDate) {
disabled = true;
itemChecked = false;
}
var val = values[1].trim();
var val = values[2].trim();
var obdate = {
date: values[0],
SettlementDate: values[1] || "",
floatRateCode: floatRateCode,
val: _.toString(val) ? parseFloat(consNumberFormat.umpriceP(val)) : "",
itemChecked: itemChecked,
disabled: disabled
@@ -758,11 +843,24 @@ const vue = new Vue({
//添加观察日
addnewitem() {
var thisObj = this;
var obdate = {
date: '',
val: 0,
itemChecked: true,
disabled: false
var obdate = {};
if (this.observationType == 1) {
var floatRateCode = thisObj.getSwapList[thisObj.observation.index]?.FloatRateUnderlyingCode || '--';
obdate = {
date: '',
SettlementDate: '',
floatRateCode: floatRateCode,
val: 0,
itemChecked: true,
disabled: false
};
} else {
obdate = {
date: '',
val: 0,
itemChecked: true,
disabled: false
};
}
thisObj.observation.ObservationDataList.push(obdate);
},
@@ -792,7 +890,8 @@ const vue = new Vue({
var observation = {
Date: item.date,
Rate: item.val * 0.01,
Settlement: item.itemChecked ? 1 : 0
Settlement: item.itemChecked ? 1 : 0,
SettlementDate: item.SettlementDate || null // 结算日期
}
observationArr.push(observation);
@@ -805,11 +904,11 @@ const vue = new Vue({
alert("请输入正确的数字格式");
return false;
}
if (this.observationType == 0) {
if (this.observationType == 1) {
thisObj.getSwapList.forEach((val, num, arr) => {
if (val.index == thisObj.observation.index) {
arr[num].SwapIntervals = JSON.stringify(observationArr);
thisObj.observation.ObservationInterval = arr[num].SwapIntervals;
arr[num].InterestSwapInterval = JSON.stringify(observationArr);
thisObj.observation.ObservationInterval = arr[num].InterestSwapInterval;
arr[num].SwapIntervalList = observationArr;
arr[num].Obervation = JSON.parse(JSON.stringify(thisObj.observation));
}
@@ -817,8 +916,8 @@ const vue = new Vue({
} else {
thisObj.marginSwapList.forEach((val, num, arr) => {
if (val.index == thisObj.observation.index) {
arr[num].SwapIntervals = JSON.stringify(observationArr);
thisObj.observation.ObservationInterval = arr[num].SwapIntervals;
arr[num].InterestSwapInterval = JSON.stringify(observationArr);
thisObj.observation.ObservationInterval = arr[num].InterestSwapInterval;
arr[num].SwapIntervalList = observationArr;
arr[num].Obervation = JSON.parse(JSON.stringify(thisObj.observation));
}
@@ -1081,11 +1180,23 @@ const vue = new Vue({
thisObj.getSwapList = thisObj.trade.swap_positions.filter(x => { if ((x.UnderlyingCode == null || x.UnderlyingCode.length == 0) && x.IsInitial && (x.InterestMode == 1 || x.InterestMode == 2 || x.InterestMode == 7 || x.InterestMode == 8 || x.InterestMode == 9)) return x; });
thisObj.getSwapList.forEach((val, num, arr) => {
arr[num].index = num;
// 解析 InterestSwapInterval 为 SwapIntervalList
if (arr[num].InterestSwapInterval && !arr[num].SwapIntervalList) {
try {
arr[num].SwapIntervalList = JSON.parse(arr[num].InterestSwapInterval);
} catch (e) { }
}
});
thisObj.marginSwapList = thisObj.trade.swap_positions.filter(x => { if ((x.UnderlyingCode == null || x.UnderlyingCode.length == 0) && x.IsInitial && (x.InterestMode == 5 || x.InterestMode == 6)) return x; });
thisObj.marginSwapList.forEach((val, num, arr) => {
arr[num].index = num;
arr[num].index = 1000 + num; // 保证金列表使用 1000+ 偏移,避免与利息腿冲突
arr[num].HappenDate = thisObj.formatDate(arr[num].HappenDate);
// 解析 InterestSwapInterval 为 SwapIntervalList
if (arr[num].InterestSwapInterval && !arr[num].SwapIntervalList) {
try {
arr[num].SwapIntervalList = JSON.parse(arr[num].InterestSwapInterval);
} catch (e) { }
}
});
if (thisObj.trade.StructureType == '多空组合') {
thisObj.paySwapList = [];
@@ -44,8 +44,8 @@ function downloadFiles(files) {
window.open(files);
}
}
function showSwapRate(timeRate) {
vueDetails.initSwapIntervalList(timeRate);
function showSwapRate(timeRate, isMarginLeg) {
vueDetails.initSwapIntervalList(timeRate, isMarginLeg);
$("#swapIntervalModal").modal("show");
}
var layerIndex = -1;
@@ -192,7 +192,7 @@ function unWindSwapTrade(id) {
function unWindSwap(id) {
var title = "收益结算";
var srcurl = "/swaptrade2/SwapIncome/?enid=" + id;
main.post("/swaptrade2/CheckEodTrade?enid=" + id).done(function (res) {
main.post("/swaptrade2/CheckEodTradeForIncome?enid=" + id).done(function (res) {
if (res.success) {
main.open(title,
srcurl,
@@ -375,7 +375,8 @@ function reload() {
var vueDetails = new Vue({
el: "#swapIntervalModal",
data: {
SwapIntervalList:[]
SwapIntervalList:[],
isMarginLeg: false // 是否是保证金腿
},
created: function () {
},
@@ -383,13 +384,18 @@ var vueDetails = new Vue({
closeModal: function () {
$("#swapIntervalModal").modal("hide");
},
initSwapIntervalList(swapIntervals) {
initSwapIntervalList(swapIntervals, isMarginLeg) {
var that = this;
that.isMarginLeg = isMarginLeg;
that.SwapIntervalList = [];
if (swapIntervals.length>0) {
if (swapIntervals && swapIntervals.length>0) {
that.SwapIntervalList = JSON.parse(swapIntervals);
that.SwapIntervalList.forEach((item, index) => {
that.SwapIntervalList[index].Rate = otcformat.trading.marginRateP(item.Rate);
// 如果结算日期为空,默认等于观察日期
if (!item.SettlementDate) {
that.SwapIntervalList[index].SettlementDate = item.Date;
}
});
}
},