From 5b7f17727d9a37271f02cb62166775663f83cc48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BC=A0=E5=90=8D=E9=94=90?= <1565842059@qq.com>
Date: Thu, 6 Aug 2026 12:41:30 +0800
Subject: [PATCH] =?UTF-8?q?refactor(swaptrade):=20=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E4=BA=92=E6=8D=A2=E4=BA=A4=E6=98=93=E4=B8=AD=E7=9A=84=E6=95=B0?=
=?UTF-8?q?=E9=87=8F=E5=92=8C=E9=87=91=E9=A2=9D=E6=A0=BC=E5=BC=8F=E5=8C=96?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 引入UnderlyingInstrumentType字段用于精确控制格式化规则
- 添加quantityPrecision配置支持不同产品类型的数量精度设置
- 实现formatAmount和formatQuantity方法提供统一格式化接口
- 更新视图模板使用新的格式化方法替代直接数据绑定
- 重构swapPricePrecisionHelper.js支持按产品类型定制格式化规则
- 移除废弃的inputFormatTradeAmount等旧格式化配置
- 添加千分位分组显示功能提升数字可读性
---
.../App_Data/Config/swappriceprecision.js | 54 ++++----
YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml | 18 +--
.../Views/SwapTrade2/SwapLongShortSwap.cshtml | 10 +-
.../SwapTrade2/SwapLongShortUnwind.cshtml | 14 +-
YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml | 22 ++--
YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml | 2 +-
YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml | 2 +-
YLErpWeb/Views/SwapTrade2/TradeView.cshtml | 10 +-
.../Scripts/app/swaptrade/SwapflowList.js | 20 ++-
.../Scripts/app/swaptrade/incomeSwapTrade.js | 12 +-
.../Scripts/app/swaptrade/swapLongShort.js | 11 +-
.../app/swaptrade/swapPricePrecisionHelper.js | 123 ++++++++++++------
.../Scripts/app/swaptrade/swapTradeEdit.js | 12 +-
.../Scripts/app/swaptrade/swapTradeView.js | 5 +-
.../Scripts/app/swaptrade/unwindLongShort.js | 11 +-
.../Scripts/app/swaptrade/unwindSwapTrade.js | 15 ++-
16 files changed, 218 insertions(+), 123 deletions(-)
diff --git a/YLErpWeb/App_Data/Config/swappriceprecision.js b/YLErpWeb/App_Data/Config/swappriceprecision.js
index 2cb43923..a0d631eb 100644
--- a/YLErpWeb/App_Data/Config/swappriceprecision.js
+++ b/YLErpWeb/App_Data/Config/swappriceprecision.js
@@ -2,52 +2,54 @@
window.main = window.main || {};
window.main.swapPricePrecision = {
common: {
- amount: { precision: 2 },
- quantity: { precision: 2 },
+ amount: { precision: 2, grouping: true },
+ quantity: { precision: 2, grouping: true },
rate: { precision: 4 }
},
- Stock: { integerDigits: 7, precision: 2 },
- StockIndex: { integerDigits: 7, precision: 2 },
- StockIF: { integerDigits: 7, precision: 4 },
- CommodityFutures: { integerDigits: 7, precision: 4 },
- CommoditySpot: { integerDigits: 7, precision: 4 },
- NewOtcStock: { integerDigits: 7, precision: 4 },
- HKStock: { integerDigits: 7, precision: 4 },
- HKStockIndex: { integerDigits: 7, precision: 4 },
- Fund: { integerDigits: 7, precision: 4 },
+ Stock: { integerDigits: 7, precision: 2, quantityPrecision: 2 },
+ StockIndex: { integerDigits: 7, precision: 2, quantityPrecision: 2 },
+ StockIF: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ CommodityFutures: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ CommoditySpot: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ NewOtcStock: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ HKStock: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ HKStockIndex: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ Fund: { integerDigits: 7, precision: 4, quantityPrecision: 4 },
Bond: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
TBonds: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
CreditBonds: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
OtherBonds: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
- TBFutures: { integerDigits: 8, precision: 4 },
- OtherFutures: { integerDigits: 8, precision: 4 },
- GoldSpot: { integerDigits: 8, precision: 4 },
- OtherSpot: { integerDigits: 8, precision: 4 },
- AbroadFutures: { integerDigits: 8, precision: 4 },
- AbroadSpot: { integerDigits: 8, precision: 4 },
- AbroadStock: { integerDigits: 8, precision: 2 },
- AbroadStockIndex: { integerDigits: 8, precision: 4 },
- ExRate: { integerDigits: 2, precision: 8 },
- Shibor: { integerDigits: 2, precision: 4 },
- FixingRepoRate: { integerDigits: 2, precision: 4 },
- RateYield: {integerDigits: 6, precision: 8},
- BondIndex: {integerDigits: 6, precision: 4},
-
- // TODO: 利率收益率(6+8)、债券指数(6+4)、黄金期货(6+4)待对应的 UnderlyingInstrumentType 枚举确认后启用。
+ TBFutures: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ OtherFutures: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ GoldSpot: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ OtherSpot: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ AbroadFutures: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ AbroadSpot: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ AbroadStock: { integerDigits: 8, precision: 2, quantityPrecision: 2 },
+ AbroadStockIndex: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ ExRate: { integerDigits: 2, precision: 8, quantityPrecision: 8 },
+ Shibor: { integerDigits: 2, precision: 4, quantityPrecision: 2 },
+ FixingRepoRate: { integerDigits: 2, precision: 4, quantityPrecision: 2 },
+ RateYield: {integerDigits: 6, precision: 8, quantityPrecision: 2},
+ BondIndex: {integerDigits: 6, precision: 4, quantityPrecision: 2},
};
diff --git a/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml b/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml
index ea00430b..91d9d26f 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml
@@ -42,15 +42,15 @@
| 成交名义本金 |
- {{deal.NotionalValue}} |
+ {{formatAmount(deal.NotionalValue)}} |
持仓名义本金 |
- {{deal.PosiNotionalValue}} |
+ {{formatAmount(deal.PosiNotionalValue)}} |
| 成交数量 |
- {{deal.NotionalQty}} |
+ {{formatQuantity(deal.NotionalQty)}} |
持仓数量 |
- {{deal.PositionQty2}} |
+ {{formatQuantity(deal.PositionQty2)}} |
| 起始日期 |
@@ -66,7 +66,7 @@
| 平仓总额 |
- {{deal.SwapCloseAmount}} |
+ {{formatAmount(deal.SwapCloseAmount)}} |
|
|
@@ -98,7 +98,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
@@ -126,7 +126,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
@@ -177,13 +177,13 @@
- {{floatPosition.Quantity}} |
+ {{formatQuantity(floatPosition.Quantity)}} |
我方{{floatPosition.PayDirection==1?"支付":"收取"}}交易费用
|
|
- {{floatPosition.FloatPnlSum}} |
+ {{formatAmount(floatPosition.FloatPnlSum)}} |
diff --git a/YLErpWeb/Views/SwapTrade2/SwapLongShortSwap.cshtml b/YLErpWeb/Views/SwapTrade2/SwapLongShortSwap.cshtml
index 1ef9f150..4df23cf7 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapLongShortSwap.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapLongShortSwap.cshtml
@@ -28,11 +28,11 @@
@@ -75,7 +75,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
@@ -103,7 +103,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
diff --git a/YLErpWeb/Views/SwapTrade2/SwapLongShortUnwind.cshtml b/YLErpWeb/Views/SwapTrade2/SwapLongShortUnwind.cshtml
index c773ae03..bdbc1601 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapLongShortUnwind.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapLongShortUnwind.cshtml
@@ -29,20 +29,20 @@
@@ -91,7 +91,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
@@ -115,7 +115,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
diff --git a/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml b/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml
index 7f9e2ea1..4d7c979a 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml
@@ -33,20 +33,20 @@
@@ -125,7 +125,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
@@ -165,7 +165,7 @@
|
- {{item.InterestClosePnL}} |
+ {{formatAmount(item.InterestClosePnL)}} |
@@ -214,7 +214,7 @@
- {{deal.CloseQty}} |
+ {{formatQuantity(deal.CloseQty)}} |
我方{{floatPosition.PayDirection==1?"支付":"收取"}}交易费用
@@ -222,8 +222,8 @@
|
|
- {{floatPosition.DividendIn}} |
- {{floatPosition.FloatPnlSum}} |
+ {{formatAmount(floatPosition.DividendIn)}} |
+ {{formatAmount(floatPosition.FloatPnlSum)}} |
diff --git a/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml b/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml
index 9ec357e9..863283eb 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml
@@ -233,7 +233,7 @@
-
+
diff --git a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml
index eead5b88..6561cbfe 100644
--- a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml
@@ -493,7 +493,7 @@
- {{item.underlying!=null?item.underlying.QuoteUnitString:''}}
+ {{item.underlying!=null?item.underlying.QuoteUnitString:''}}
|
diff --git a/YLErpWeb/Views/SwapTrade2/TradeView.cshtml b/YLErpWeb/Views/SwapTrade2/TradeView.cshtml
index 93efbf9f..24f94de3 100644
--- a/YLErpWeb/Views/SwapTrade2/TradeView.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/TradeView.cshtml
@@ -423,7 +423,7 @@
|
}
-
+
|
@if (item.PosiFeeType == 0)
@@ -646,7 +646,7 @@
|
}
-
+
|
|
|
@@ -710,7 +710,7 @@
@if (tc.CloseType == 1)
{
平仓数量 |
- |
+ |
}
else
{
@@ -856,7 +856,7 @@
|
|
}
- |
+ |
|
|
|
@@ -1058,7 +1058,7 @@
|
}
|
- |
+ |
|
|
|
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js
index 6bba7673..bfab8ce6 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js
@@ -2,9 +2,15 @@
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradeSinglePrice.precision, negative: true, append: '' });
const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, negative: true, append: '' });
const inputFormatSwapAmount = swapPricePrecision.getCommonInputFormat('amount', { negative: true, append: '' });
-const inputFormatTradeAmount = swapPricePrecision.getCommonInputFormat('quantity', { append: '' });
const formatSwapAmount = value => swapPricePrecision.formatCommon('amount', value);
-const formatSwapQuantity = value => swapPricePrecision.formatCommon('quantity', value);
+const formatSwapQuantity = function (value, options, rowObject) {
+ const row = rowObject || {};
+ const instrumentType = row.UnderlyingInstrumentType
+ || row.InstrumentType
+ || (row.position && row.position.UnderlyingInstrumentType)
+ || '';
+ return swapPricePrecision.formatCommon('quantity', value, instrumentType);
+};
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
var clients = ylotc.clients;
const consUnderlyingFlag = (function () {
@@ -864,6 +870,7 @@ var vue = new Vue({
SwapTradeNo: "",
BsType: 1,
UnderlyingCode: "",
+ UnderlyingInstrumentType: "",
TradingQty: 0,
TradingAmount: 0,
TradingFee: 0,
@@ -1017,6 +1024,12 @@ var vue = new Vue({
this.tradeDate = page.valueDate; //将1970/08/08转化成1970-08-08
return this.tradeDate;
},
+ getQuantityInputFormat() {
+ return swapPricePrecision.getCommonInputFormat(
+ 'quantity',
+ { append: '' },
+ this.swapflow.UnderlyingInstrumentType);
+ },
addNew() {
this.tradeDate = page.valueDate;
this.initSwapFlow();
@@ -1032,6 +1045,7 @@ var vue = new Vue({
SwapTradeNo: "",
BsType: 1,
UnderlyingCode: "",
+ UnderlyingInstrumentType: "",
TradingQty: 0,
TradingAmount: 0,
TradingFee: 0,
@@ -1129,6 +1143,7 @@ var vue = new Vue({
thisObj.swapflow.SwapTradeNo = item.SwapTradeNo;
thisObj.swapflow.BsType = item.BsType;
thisObj.swapflow.UnderlyingCode = item.UnderlyingCode;
+ thisObj.swapflow.UnderlyingInstrumentType = item.UnderlyingInstrumentType || item.InstrumentType || "";
thisObj.swapflow.TradingQty = item.TradingQty;
thisObj.swapflow.TradingAmount = item.TradingAmount;
thisObj.swapflow.TradingFee = item.TradingFee;
@@ -1158,6 +1173,7 @@ var vue = new Vue({
setUnderlyingCode(data) {
this.swapflow.ContractSize = data.ContractSize;
this.swapflow.UnderlyingName = data.Name;
+ this.swapflow.UnderlyingInstrumentType = data.InstrumentType || data.UnderlyingInstrumentType || "";
},
changeClient: function (client) {
this.swapflow.ClientId = client.id;
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js
index ba2fea6a..b52065cf 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js
@@ -3,12 +3,12 @@ window.otcformat.options.disableGrouping = true;
const inputFormatSwapRate = swapPricePrecision.getCommonInputFormat('rate', { append: '%' });
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradePrice.precision, append: '' });
-const inputFormatTradeAmount = swapPricePrecision.getCommonInputFormat('quantity', { append: '' });
const inputFormatEqvNotional = swapPricePrecision.getCommonInputFormat('amount', { append: '', negative: true });
const inputFormatInterestAmount = swapPricePrecision.getCommonInputFormat('amount', { append: '', negative: true });
const inputFormatDividend = swapPricePrecision.getCommonInputFormat('amount', { append: '', negative: true });
-const formatSwapAmount = value => swapPricePrecision.formatCommon('amount', value);
-const formatSwapQuantity = value => swapPricePrecision.formatCommon('quantity', value);
+const swapInstrumentType = (model.FlowEvents || []).find(item => item && item.UnderlyingInstrumentType)?.UnderlyingInstrumentType || model.UnderlyingInstrumentType || '';
+const formatSwapAmount = value => swapPricePrecision.normalizeCommon('amount', value);
+const formatSwapQuantity = value => swapPricePrecision.normalizeCommon('quantity', value, swapInstrumentType);
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
const inputFormatMarginRateNoPercent = Object.freeze({ precision: otcformat.trading.umpriceP.precision, append: '', percent: true });
const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, append: '', negative: true });
@@ -62,6 +62,12 @@ const vue = new Vue({
});
},
methods: {
+ formatAmount(value) {
+ return swapPricePrecision.formatCommon('amount', value);
+ },
+ formatQuantity(value) {
+ return swapPricePrecision.formatCommon('quantity', value, swapInstrumentType);
+ },
isAfterMaxIncomeValueDate(valueDate) {
return valueDate && MaxIncomeValueDate && valueDate > MaxIncomeValueDate;
},
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapLongShort.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapLongShort.js
index 02a97d3f..60bcb46b 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapLongShort.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapLongShort.js
@@ -1,8 +1,9 @@
//otcformat禁止千分位分组
window.otcformat.options.disableGrouping = true;
const inputFormatEqvNotional = swapPricePrecision.getCommonInputFormat('amount', { append: '' });
-const formatSwapAmount = value => swapPricePrecision.formatCommon('amount', value);
-const formatSwapQuantity = value => swapPricePrecision.formatCommon('quantity', value);
+const swapInstrumentType = (model.FlowEvents || []).find(item => item && item.UnderlyingInstrumentType)?.UnderlyingInstrumentType || model.UnderlyingInstrumentType || '';
+const formatSwapAmount = value => swapPricePrecision.normalizeCommon('amount', value);
+const formatSwapQuantity = value => swapPricePrecision.normalizeCommon('quantity', value, swapInstrumentType);
let ValueDate = model.ValueDate;
const vue = new Vue({
el: '#vueDiv',
@@ -24,6 +25,12 @@ const vue = new Vue({
this.setValueDate();
},
methods: {
+ formatAmount(value) {
+ return swapPricePrecision.formatCommon('amount', value);
+ },
+ formatQuantity(value) {
+ return swapPricePrecision.formatCommon('quantity', value, swapInstrumentType);
+ },
initDeal() {
this.interestList = model.FlowEvents.filter((item) => {
return item.InterestMode == 1 || item.InterestMode == 2 || item.InterestMode == 7 || item.InterestMode == 8 || item.InterestMode == 9;
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
index 5dd5cf0d..ebd08215 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
@@ -1,52 +1,56 @@
var swapPricePrecision = (function (global) {
const defaults = Object.freeze({
common: {
- amount: { precision: 2 },
- quantity: { precision: 2 },
+ amount: { precision: 2, grouping: true },
+ quantity: { precision: 2, grouping: true },
rate: { precision: 4 }
},
- Stock: { integerDigits: 7, precision: 2 },
- StockIndex: { integerDigits: 7, precision: 2 },
- StockIF: { integerDigits: 7, precision: 4 },
- CommodityFutures: { integerDigits: 7, precision: 4 },
- CommoditySpot: { integerDigits: 7, precision: 4 },
- NewOtcStock: { integerDigits: 7, precision: 4 },
- HKStock: { integerDigits: 7, precision: 4 },
- HKStockIndex: { integerDigits: 7, precision: 4 },
- Fund: { integerDigits: 7, precision: 4 },
+ Stock: { integerDigits: 7, precision: 2, quantityPrecision: 2 },
+ StockIndex: { integerDigits: 7, precision: 2, quantityPrecision: 2 },
+ StockIF: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ CommodityFutures: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ CommoditySpot: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ NewOtcStock: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ HKStock: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ HKStockIndex: { integerDigits: 7, precision: 4, quantityPrecision: 2 },
+ Fund: { integerDigits: 7, precision: 4, quantityPrecision: 4 },
Bond: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
TBonds: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
CreditBonds: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
OtherBonds: {
+ quantityPrecision: 0,
grossPrice: { integerDigits: 6, precision: 9 },
netPrice: { integerDigits: 6, precision: 9 },
yield: { integerDigits: 2, precision: 4 }
},
- TBFutures: { integerDigits: 8, precision: 4 },
- OtherFutures: { integerDigits: 8, precision: 4 },
- GoldSpot: { integerDigits: 8, precision: 4 },
- OtherSpot: { integerDigits: 8, precision: 4 },
- AbroadFutures: { integerDigits: 8, precision: 4 },
- AbroadSpot: { integerDigits: 8, precision: 4 },
- AbroadStock: { integerDigits: 8, precision: 2 },
- AbroadStockIndex: { integerDigits: 8, precision: 4 },
- ExRate: { integerDigits: 2, precision: 8 },
- Shibor: { integerDigits: 2, precision: 4 },
- FixingRepoRate: { integerDigits: 2, precision: 4 },
- RateYield: {integerDigits: 6, precision: 8},
- BondIndex: {integerDigits: 6, precision: 4},
+ TBFutures: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ OtherFutures: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ GoldSpot: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ OtherSpot: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ AbroadFutures: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ AbroadSpot: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ AbroadStock: { integerDigits: 8, precision: 2, quantityPrecision: 2 },
+ AbroadStockIndex: { integerDigits: 8, precision: 4, quantityPrecision: 2 },
+ ExRate: { integerDigits: 2, precision: 8, quantityPrecision: 8 },
+ Shibor: { integerDigits: 2, precision: 4, quantityPrecision: 2 },
+ FixingRepoRate: { integerDigits: 2, precision: 4, quantityPrecision: 2 },
+ RateYield: {integerDigits: 6, precision: 8, quantityPrecision: 2},
+ BondIndex: {integerDigits: 6, precision: 4, quantityPrecision: 2},
});
@@ -130,7 +134,7 @@ var swapPricePrecision = (function (global) {
if (!rule || typeof rule !== 'object') return null;
const precision = Number(rule.precision);
if (!Number.isInteger(precision) || precision < 0 || precision > 13) return null;
- return { precision: precision };
+ return { precision: precision, grouping: typeof rule.grouping === 'boolean' ? rule.grouping : undefined };
}
function findRule(source, instrumentType, field) {
@@ -144,13 +148,6 @@ var swapPricePrecision = (function (global) {
return findRule(global.main && global.main.swapPricePrecision, instrumentType, field) || fallback;
}
- function getCommonRule(kind) {
- const fallback = normalizeCommonRule(defaults.common[kind]);
- const configured = global.main && global.main.swapPricePrecision
- && global.main.swapPricePrecision.common;
- return normalizeCommonRule(configured && configured[kind]) || fallback || { precision: 2 };
- }
-
function formatFixed(value, precision) {
const normalized = normalizeDecimal(roundDecimal(value, precision));
if (!normalized) return '';
@@ -161,12 +158,48 @@ var swapPricePrecision = (function (global) {
return (negative ? '-' : '') + integerPart + '.' + (parts[1] || '').padEnd(precision, '0');
}
- function formatCommon(kind, value) {
+ function groupDecimal(value) {
+ if (!value) return value;
+ const negative = value.charAt(0) === '-';
+ const source = negative ? value.substring(1) : value;
+ const parts = source.split('.');
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+ return (negative ? '-' : '') + parts.join('.');
+ }
+
+ function getQuantityPrecision(instrumentType, fallback) {
+ if (!instrumentType) return fallback;
+ const configured = global.main && global.main.swapPricePrecision;
+ const typeRule = (configured || defaults)[instrumentType];
+ if (!typeRule || !Object.prototype.hasOwnProperty.call(typeRule, 'quantityPrecision')) return fallback;
+ const precision = Number(typeRule.quantityPrecision);
+ return Number.isInteger(precision) && precision >= 0 && precision <= 13 ? precision : fallback;
+ }
+
+ function getCommonRule(kind, instrumentType) {
+ const fallback = normalizeCommonRule(defaults.common[kind]) || { precision: 2, grouping: false };
+ const configured = global.main && global.main.swapPricePrecision
+ && global.main.swapPricePrecision.common;
+ const configuredRule = normalizeCommonRule(configured && configured[kind]);
+ const rule = configuredRule || fallback;
+ if (rule.grouping === undefined) rule.grouping = fallback.grouping;
+ if (kind === 'quantity') rule.precision = getQuantityPrecision(instrumentType, rule.precision);
+ return rule;
+ }
+
+ function formatCommon(kind, value, instrumentType, options) {
if (value === null || value === undefined || value === '') return '';
- const precision = getCommonRule(kind).precision;
+ if (instrumentType && typeof instrumentType === 'object') {
+ options = instrumentType;
+ instrumentType = options.instrumentType;
+ }
+ const rule = getCommonRule(kind, instrumentType);
const displayValue = kind === 'rate' ? shiftDecimal(value, 2) : value;
- const formatted = formatFixed(displayValue, precision);
- return kind === 'rate' && formatted ? formatted + '%' : formatted;
+ const formatted = formatFixed(displayValue, rule.precision);
+ if (!formatted) return '';
+ const grouping = options && options.grouping !== undefined ? !!options.grouping : rule.grouping;
+ const text = grouping ? groupDecimal(formatted) : formatted;
+ return kind === 'rate' ? text + '%' : text;
}
function format(value, instrumentType, field) {
@@ -297,16 +330,24 @@ var swapPricePrecision = (function (global) {
return Object.freeze({
getRule: getRule,
- getCommonPrecision: function (kind) {
- return getCommonRule(kind).precision;
+ getCommonPrecision: function (kind, instrumentType) {
+ return getCommonRule(kind, instrumentType).precision;
},
- getCommonInputFormat: function (kind, options) {
- return Object.assign({}, options, {
- precision: getCommonRule(kind).precision,
+ getCommonInputFormat: function (kind, options, instrumentType) {
+ const inputOptions = Object.assign({}, options || {});
+ const type = instrumentType || inputOptions.instrumentType;
+ delete inputOptions.instrumentType;
+ const rule = getCommonRule(kind, type);
+ return Object.assign(inputOptions, {
+ precision: rule.precision,
+ grouping: inputOptions.grouping === undefined ? !!rule.grouping : !!inputOptions.grouping,
trimTailZeros: false
});
},
formatCommon: formatCommon,
+ normalizeCommon: function (kind, value, instrumentType) {
+ return formatCommon(kind, value, instrumentType, { grouping: false });
+ },
getInputFormat: function (instrumentType, field, options) {
const rule = getRule(instrumentType, field);
return rule ? Object.assign({}, options, rule) : Object.assign({}, options);
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js
index 64152a49..d1fd613c 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js
@@ -11,8 +11,6 @@ const consAssetUnits = page.canAddNewTrader ? ylotc.assetunits
const inputFormatInteger = Object.freeze({ precision: 0, append: '' });
const inputFormatEqvNotional = swapPricePrecision.getCommonInputFormat('amount', { append: '' });
-const inputFormatTradeAmount = swapPricePrecision.getCommonInputFormat('quantity', { append: '' });
-const inputFormatPositionQuantityFixed2 = swapPricePrecision.getCommonInputFormat('quantity', { append: '' });
const inputFormatSwapRate = swapPricePrecision.getCommonInputFormat('rate', { negative: true, append: '%' });
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradePrice.precision, negative: true, append: '' });
const inputFormatTradeSinglePrice = swapPricePrecision.getCommonInputFormat('amount', { negative: true, append: '', percent: false });
@@ -270,6 +268,12 @@ const vue = new Vue({
});
},
methods: {
+ getQuantityInputFormat(item) {
+ return swapPricePrecision.getCommonInputFormat(
+ 'quantity',
+ { append: '' },
+ item && item.UnderlyingInstrumentType);
+ },
getPosiPriceInputFormat(item, field) {
return swapPricePrecision.getInputFormat(
item && item.UnderlyingInstrumentType,
@@ -563,7 +567,7 @@ const vue = new Vue({
},
//变更名义本金(仅格式化,不反算数量)
changeStockEqvNotional() {
- this.trade.StockEqvNotional = swapPricePrecision.formatCommon('amount', this.trade.StockEqvNotional);
+ this.trade.StockEqvNotional = swapPricePrecision.normalizeCommon('amount', this.trade.StockEqvNotional);
this.refreshPayTradingFeesByUnit();
//计算数量
// if (this.paySwapList.length > 0) {
@@ -651,7 +655,7 @@ const vue = new Vue({
// 守卫: 名义本金必须 round 到 2 位 → 对应历史 bug f873239a(缺 _.round); 外置到 swapCalc.calcStockEqvNotional
var deliveryPrice = this.roundStoragePrice(payItem, payItem.PosiGrossPrice, 'grossPrice');
var stockEqvNotional = SwapCalc.calcStockEqvNotional(deliveryPrice, national);//名义本金=期初价格*数量*乘数
- this.trade.StockEqvNotional = swapPricePrecision.formatCommon('amount', stockEqvNotional);
+ this.trade.StockEqvNotional = swapPricePrecision.normalizeCommon('amount', stockEqvNotional);
payItem.PosiNotionalValue = this.trade.StockEqvNotional;
this.refreshPayTradingFeesByUnit();
}
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeView.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeView.js
index 565ab713..c6ad4bac 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeView.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeView.js
@@ -11,7 +11,10 @@ function formatSwapPriceElements() {
function formatSwapCommonElements() {
$('.js-swap-common').each(function () {
- this.textContent = swapPricePrecision.formatCommon(this.dataset.kind, this.dataset.value);
+ this.textContent = swapPricePrecision.formatCommon(
+ this.dataset.kind,
+ this.dataset.value,
+ this.dataset.instrumentType);
});
}
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindLongShort.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindLongShort.js
index 48fd18f0..ed32fced 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindLongShort.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindLongShort.js
@@ -1,8 +1,9 @@
//otcformat禁止千分位分组
window.otcformat.options.disableGrouping = true;
const inputFormatEqvNotional = swapPricePrecision.getCommonInputFormat('amount', { append: '' });
-const formatSwapAmount = value => swapPricePrecision.formatCommon('amount', value);
-const formatSwapQuantity = value => swapPricePrecision.formatCommon('quantity', value);
+const swapInstrumentType = (model.FlowEvents || []).find(item => item && item.UnderlyingInstrumentType)?.UnderlyingInstrumentType || model.UnderlyingInstrumentType || '';
+const formatSwapAmount = value => swapPricePrecision.normalizeCommon('amount', value);
+const formatSwapQuantity = value => swapPricePrecision.normalizeCommon('quantity', value, swapInstrumentType);
let dealDate = model.DealDate;
const vue = new Vue({
el: '#vueDiv',
@@ -23,6 +24,12 @@ const vue = new Vue({
this.dataFormat();
},
methods: {
+ formatAmount(value) {
+ return swapPricePrecision.formatCommon('amount', value);
+ },
+ formatQuantity(value) {
+ return swapPricePrecision.formatCommon('quantity', value, swapInstrumentType);
+ },
initDeal() {
this.interestList = model.FlowEvents.filter((item) => {
return item.InterestMode == 1 || item.InterestMode == 2 || item.InterestMode == 7 || item.InterestMode == 8 || item.InterestMode == 9;
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
index 51441df1..5afb4707 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
@@ -3,11 +3,11 @@ window.otcformat.options.disableGrouping = true;
const inputFormatSwapRate = Object.freeze({ precision: 4, append: '%', trimTailZeros: false });
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradePrice.precision, append: '' });
-const inputFormatTradeAmount = swapPricePrecision.getCommonInputFormat('quantity', { append: '' });
const inputFormatEqvNotional = swapPricePrecision.getCommonInputFormat('amount', { append: '', negative: true });
const inputFormatCloseAmount = swapPricePrecision.getCommonInputFormat('amount', { append: '', negative: true });
-const formatSwapAmount = value => swapPricePrecision.formatCommon('amount', value);
-const formatSwapQuantity = value => swapPricePrecision.formatCommon('quantity', value);
+const swapInstrumentType = (model.FlowEvents || []).find(item => item && item.UnderlyingInstrumentType)?.UnderlyingInstrumentType || model.UnderlyingInstrumentType || '';
+const formatSwapAmount = value => swapPricePrecision.normalizeCommon('amount', value);
+const formatSwapQuantity = value => swapPricePrecision.normalizeCommon('quantity', value, swapInstrumentType);
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
const inputFormatMarginRateNoPercent = Object.freeze({ precision: otcformat.trading.umpriceP.precision, append: '', percent: true });
const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, append: '', negative: true });
@@ -81,6 +81,15 @@ const vue = new Vue({
this.setUnwindDate();
},
methods: {
+ formatAmount(value) {
+ return swapPricePrecision.formatCommon('amount', value);
+ },
+ formatQuantity(value) {
+ return swapPricePrecision.formatCommon('quantity', value, swapInstrumentType);
+ },
+ getQuantityInputFormat() {
+ return swapPricePrecision.getCommonInputFormat('quantity', { append: '' }, swapInstrumentType);
+ },
getDeliveryPriceInputFormat() {
return swapPricePrecision.getInputFormat(
this.floatPosition && this.floatPosition.UnderlyingInstrumentType,