@@ -372,11 +390,14 @@ namespace YLErp.Modules.SwapModule
CountRatio = underlying.CountRatio,
ContractSize = Convert.ToDecimal(underlying.ContractSize),
PosiNetPrice = flowMerge.TradingAmountFeeAvgAbs,
- PosiGrossPrice = flowMerge.TradingAmountAvg,
+ PosiGrossPrice = Math.Round(
+ flowMerge.TradingAmountAvg,
+ underlying.IsBond() ? ConsGlobal.PriceRound : ConsGlobal.SwapDeliveryPriceRound,
+ MidpointRounding.AwayFromZero),
PosiNetFeePrice = flowMerge.TradingAmountNetFeeAvg ?? 0,
PosiNetNoFeePrice = flowMerge.TradingAmountNetAvg ?? 0,
PosiQuantity = flowMerge.TradingQtyAbs,
- PosiNotionalValue = flowMerge.TradingAmount,
+ PosiNotionalValue = Math.Round(flowMerge.TradingAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero),
PosiTradingFeePending = flowMerge.TradingFeePending,
PosiTradingFee = 0,
PosiTradingFeeUnit = 0,
@@ -388,7 +409,7 @@ namespace YLErp.Modules.SwapModule
OptId = UserInfo.UserId,
OptName = UserInfo.UserName,
UnderlyingInstrumentType = underlying.UnderlyingInstrumentType,
- InitYtm = flowMerge.InitYtm
+ InitYtm = RoundSwapBondNetPriceAndYtm(flowMerge.InitYtm)
};
td.swap_positions.Add(floatPosition);
swap_position interestPosition = new swap_position()
@@ -581,7 +602,7 @@ namespace YLErp.Modules.SwapModule
dbTrade.trade_extend = req.trade_extend;
dbTrade.swap_positions = req.swap_positions;
dbTrade.MetaDic = req.MetaDic;
- dbTrade.InitYtm = req.swap_positions.FirstOrDefault(p => p.InitYtm != null)?.InitYtm;
+ dbTrade.InitYtm = RoundSwapBondNetPriceAndYtm(req.swap_positions.FirstOrDefault(p => p.InitYtm != null)?.InitYtm);
InnerSaveTrade(false, dbTrade, changsStr, changeConfirmStatus);
return dbTrade;
@@ -675,11 +696,7 @@ namespace YLErp.Modules.SwapModule
private bool PrepareTrade(trade req, TradeSourceEnum dataSource, underlying_manager um)
{
bool tradeNumberGenerated = false;
- req.InitialMargin = Convert.ToDouble(req.trade_Initial_Margin.MarginValue);
- if (req.trade_Initial_Margin.MarginType == 0)
- {
- req.InitialMargin = req.StockEqvNotional == 0 ? 0 : Convert.ToDouble(req.trade_Initial_Margin.MarginValue) * req.StockEqvNotional;
- };
+ PrepareInitialMargin(req);
var isAddNew = req.id == 0;
if (isAddNew)
{
@@ -722,6 +739,17 @@ namespace YLErp.Modules.SwapModule
return tradeNumberGenerated;
}
+
+ private static void PrepareInitialMargin(trade req)
+ {
+ // 初始预付金依赖最终入库的名义本金,须先统一金额精度,避免两者无法勾稽。
+ req.StockEqvNotional = Math.Round(req.StockEqvNotional, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
+ req.InitialMargin = Convert.ToDouble(req.trade_Initial_Margin.MarginValue);
+ if (req.trade_Initial_Margin.MarginType == 0)
+ {
+ req.InitialMargin = req.StockEqvNotional == 0 ? 0 : Convert.ToDouble(req.trade_Initial_Margin.MarginValue) * req.StockEqvNotional;
+ }
+ }
//准备单个交易
private trade PrepareSingleTrade(trade req, TradeSourceEnum dataSource, bool isAddNew, underlying_manager um)
{
@@ -764,6 +792,7 @@ namespace YLErp.Modules.SwapModule
req.SpotPrice = Convert.ToDouble(swapPosition.PosiNetPrice);
}
req.Strike = null;
+ req.StockEqvNotional = Math.Round(req.StockEqvNotional, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
req.OriginalStockEqvNotional = req.StockEqvNotional;
req.StockEqvNotionalReal = req.StockEqvNotional;
@@ -1351,13 +1380,19 @@ namespace YLErp.Modules.SwapModule
position.UnderlyingCode = swap.UnderlyingCode;
position.UnderlyingInstrumentType = swap.UnderlyingInstrumentType;
position.PosiDirection = swap.PosiDirection;
- position.PosiGrossPrice = swap.PosiGrossPrice;
- position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiGrossPrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
+ // position.PosiGrossPrice = string.IsNullOrEmpty(swap.UnderlyingCode)
+ // ? Math.Round(swap.PosiGrossPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero)
+ // : ValidateDeliveryPrice(swap.PosiGrossPrice, "期初交割价");
+ var storagePriceRound = ConsGlobal.InstrumentType.IsBond(swap.UnderlyingInstrumentType)
+ ? ConsGlobal.PriceRound
+ : ConsGlobal.SwapDeliveryPriceRound;
+ position.PosiGrossPrice = Math.Round(swap.PosiGrossPrice, storagePriceRound, MidpointRounding.AwayFromZero);
+ position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (position.PosiGrossPrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
position.PosiNetPrice = Math.Round(position.PosiNetPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
- position.PosiNetNoFeePrice = swap.PosiNetNoFeePrice;
+ position.PosiNetNoFeePrice = RoundSwapBondNetPriceAndYtm(swap.PosiNetNoFeePrice);
position.PosiNetFeePrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiNetNoFeePrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
position.PosiNetFeePrice = Math.Round(position.PosiNetFeePrice??0, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
- position.PosiNotionalValue = swap.PosiNotionalValue;
+ position.PosiNotionalValue = Math.Round(swap.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
position.PosiQuantity = swap.PosiQuantity;
position.InterestDirection = swap.InterestDirection;
position.InterestMode = swap.InterestMode;
@@ -1379,10 +1414,10 @@ namespace YLErp.Modules.SwapModule
position.FloatRateUnderlyingCode = swap.FloatRateUnderlyingCode;
position.interest_rest_days = swap.interest_rest_days;
position.interest_rule = swap.interest_rule;
- position.InitYtm = swap.InitYtm;
- if (swap.InitYtm != null && swap.InitYtm > 0)
+ position.InitYtm = RoundSwapBondNetPriceAndYtm(swap.InitYtm);
+ if (position.InitYtm != null && position.InitYtm > 0)
{
- td.InitYtm = swap.InitYtm;
+ td.InitYtm = position.InitYtm;
}
if (position.id == 0)
@@ -1481,7 +1516,7 @@ namespace YLErp.Modules.SwapModule
td.ProcessStatus = null;
if (backToBegin)
{
- td.StockEqvNotional = td.OriginalStockEqvNotional ?? 0;
+ td.StockEqvNotional = Math.Round(td.OriginalStockEqvNotional ?? 0, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
td.UnWindDate = null;
td.HasPartialUnWind = null;
SingleTradeBackToBegin(td, swapPositions);
@@ -1643,10 +1678,10 @@ namespace YLErp.Modules.SwapModule
posi.PosiGrossPrice = eodPosi.PosiGrossPrice;
posi.PosiNetFeePrice = eodPosi.PosiNetFeePrice;
posi.PosiNetNoFeePrice = eodPosi.PosiNetNoFeePrice;
- posi.PosiNotionalValue = eodPosi.PosiNotionalValue;
+ posi.PosiNotionalValue = Math.Round(eodPosi.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
if (posi.PosiDirection > 0)
{
- td.StockEqvNotional = Convert.ToDouble(posi.PosiNotionalValue);
+ td.StockEqvNotional = Math.Round(Convert.ToDouble(posi.PosiNotionalValue), ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
td.TradeAmount = Convert.ToDouble(posi.PosiQuantity);
}
}
diff --git a/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml b/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml
index b02667f9..c86b8774 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapIncome.cshtml
@@ -163,7 +163,7 @@
| {{priceFormat(floatPosition.TradingAmountNetAvg > 0 ? floatPosition.TradingAmountNetAvg : floatPosition.PosiNetPrice)}} |
-
+
diff --git a/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml b/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml
index 1011c3c8..e1ecadcb 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapUnwind.cshtml
@@ -200,7 +200,7 @@
|
{{priceFormat(floatPosition.PosiGrossPrice)}} |
-
+
diff --git a/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml b/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml
index 6bc78ac4..eb805b1c 100644
--- a/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/SwapflowList.cshtml
@@ -243,7 +243,7 @@
-
+
@*
diff --git a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml
index cc26b463..661828bd 100644
--- a/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml
+++ b/YLErpWeb/Views/SwapTrade2/TradeEdit.cshtml
@@ -452,16 +452,16 @@
|
- 源
+
|
- 源
+
|
- 源重算
+
|
-
+
|
{{item.underlying!=null?item.underlying.QuoteUnitString:''}}
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js
index b92a89e3..3af1b627 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/SwapflowList.js
@@ -1,5 +1,6 @@
//window.otcformat.options.disableGrouping = true;
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradeSinglePrice.precision, negative: true, append: '' });
+const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, negative: true, append: '' });
const inputFormatTradeAmount = Object.freeze({ precision: otcformat.trading.notional.precision, append: '' });
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
var clients = ylotc.clients;
@@ -669,7 +670,7 @@ function getColModelGridStep4() {
label: '名义本金',
width: 160,
align: 'center',
- formatter: otcformat.trading.umprice
+ formatter: otcformat.trading.StockEqvNotional
}
, {
name: 'position.PosiTradingFee',
@@ -1198,6 +1199,7 @@ var vue = new Vue({
},
postSwapflow() {
var thisObj = this;
+ thisObj.swapflow.TradingAmountAvg = _.round(Number(thisObj.swapflow.TradingAmountAvg), 9);
main.post("/swaptrade2/SaveSwapflow", { req: thisObj.swapflow, step: thisObj.step }).done(function (resp) {
if (resp.success) {
getList();
@@ -1221,4 +1223,4 @@ var vue = new Vue({
'vue-underlying': vueUnderlying()
}
});
-window.reloadData = getList();
\ No newline at end of file
+window.reloadData = getList();
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js
index 7acad7c4..a0057f28 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js
@@ -8,6 +8,7 @@ const inputFormatEqvNotional = Object.freeze({ precision: otcformat.trading.Stoc
const inputFormatDividend = Object.freeze({ precision: 2, append: '', negative: true });
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 });
let ValueDate = model.ValueDate;
let MaxIncomeValueDate = model.MaxIncomeValueDate ? model.MaxIncomeValueDate.substr(0, 10) : ValueDate;
@@ -77,6 +78,10 @@ const vue = new Vue({
getPriceScale() {
return SwapCalc.getPriceScale(this.multiplier);
},
+ getStorageDeliveryPrice() {
+ const precision = inputFormatSwapDeliveryPrice.precision + (this.multiplier === 100 ? 2 : 0);
+ return SwapCalc.roundHalfAwayFromZero(Number(this.floatPosition.TradingAmountAvg) * this.getPriceScale(), precision);
+ },
initDeal() {
var positions = model.FlowEvents.filter((item) => {
return item.UnderlyingCode;
@@ -161,7 +166,7 @@ const vue = new Vue({
{ code: thisObj.floatPosition.UnderlyingCode, valuedate: thisObj.deal.ValueDate })
.done(function (res) {
res.obj = res.obj * thisObj.multiplier;
- thisObj.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(res.obj);
+ thisObj.floatPosition.TradingAmountAvg = _.round(Number(res.obj), 9);
thisObj.calcFloatClosePnl();
});
},
@@ -180,11 +185,11 @@ const vue = new Vue({
let TradingFee = thisObj.floatPosition.TradingFee == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFee);
let TradingFeePending = thisObj.floatPosition.TradingFeePending == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFeePending);
let DividendIn = thisObj.floatPosition.DividendIn == "" ? 0 : parseFloat(thisObj.floatPosition.DividendIn ?? 0);
- let scale = thisObj.getPriceScale();
+ let deliveryPrice = thisObj.getStorageDeliveryPrice();
// 债券全价是单位价格,价差盈亏应按持仓数量×合约乘数计算;
// CloseNotionalValue 是期初全价折算后的名义本金,直接乘价差会重复包含期初价格。
let positionAmount = parseFloat(thisObj.floatPosition.Quantity) * parseFloat(thisObj.floatPosition.ContractSize || 1);
- thisObj.floatPosition.MarkClosePnl = positionAmount * (thisObj.floatPosition.TradingAmountAvg * scale - thisObj.initPosiGrossPrice) * floatRatio;
+ thisObj.floatPosition.MarkClosePnl = positionAmount * (deliveryPrice - thisObj.initPosiGrossPrice) * floatRatio;
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);//MarkClosePnl 纯盯市不要计算交易费用和分红
// 守卫: 浮动盈亏合计必须保留 2 位小数 → 对应历史 bug 3c5f25a5(原代码缺精度保留)
// 数值由 swapCalc.calcFloatPnlSum 计算, 此处 .toFixed(2) 仅保留字符串类型以兼容下游
@@ -205,13 +210,13 @@ const vue = new Vue({
thisObj.deal.SwapRealizedPnL = pnl;
thisObj.deal.SwapMarginRebatePnl = 0;
thisObj.deal.SwapMarginAmount = 0;
- let scale = thisObj.getPriceScale();
- thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue) * scale;
+ let deliveryPrice = thisObj.getStorageDeliveryPrice();
+ thisObj.floatPosition.TradingAmount = deliveryPrice * parseFloat(thisObj.deal.CloseNotionalValue);
thisObj.floatPosition.CloseFee = TradingFee;
if (thisObj.deal.CloseQty > 0) {
- thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale + (TradingFee / thisObj.deal.CloseQty) * floatRatio;
+ thisObj.floatPosition.TradingAmountFeeAvg = deliveryPrice + (TradingFee / thisObj.deal.CloseQty) * floatRatio;
} else {
- thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale;
+ thisObj.floatPosition.TradingAmountFeeAvg = deliveryPrice;
}
this.interestList.forEach(x => {
//let interestRatio = x.InterestDirection == 1 ? 1 : -1;
@@ -277,7 +282,7 @@ const vue = new Vue({
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
let floatPosition = _.cloneDeep(thisObj.floatPosition);
floatPosition.Quantity = 0;
- floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * thisObj.getPriceScale();
+ floatPosition.TradingAmountAvg = thisObj.getStorageDeliveryPrice();
reqObj.FlowEvents.push(floatPosition);
var postData = { unwindData: reqObj };
var msg = "确认提交收益结算?";
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js
index 5524ff19..91b2e26a 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapTradeEdit.js
@@ -13,7 +13,10 @@ const inputFormatSwapRate = Object.freeze({ precision: otcformat.trading.premium
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradePrice.precision, negative: true, append: '' });
const inputFormatTradeSinglePrice = Object.freeze({ precision: otcformat.trading.tradeSinglePrice.precision, negative: true, append: '', percent: false });
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, negative: true, append: '', percent: false });
+const inputFormatSwapBondDeliveryPrice = Object.freeze({ precision: 9, negative: true, append: '', percent: true });
+const inputFormatSwapBondNetPriceAndYtm = Object.freeze({ precision: 9, negative: true, append: '', percent: true });
+const swapBondStoragePricePrecision = inputFormatSwapBondDeliveryPrice.precision + 2;
const consUnderlyingFlagBase = (function () {
let unSelFlag = tradeHelper.UnderlyingSelectFlag;
@@ -219,6 +222,15 @@ const vue = new Vue({
});
},
methods: {
+ roundStorageDeliveryPrice(item, price) {
+ const precision = tradeHelper.IsBond(item && item.UnderlyingInstrumentType)
+ ? swapBondStoragePricePrecision
+ : inputFormatSwapDeliveryPrice.precision;
+ return _.round(Number(price), precision);
+ },
+ roundStorageBondNetPriceAndYtm(value) {
+ return value == null ? value : _.round(Number(value), swapBondStoragePricePrecision);
+ },
getPosiPriceFormatKey(item, field) {
const index = item && item.index != null ? item.index : '';
const isBond = tradeHelper.IsBond(item && item.UnderlyingInstrumentType);
@@ -376,7 +388,8 @@ const vue = new Vue({
//计算数量
if (this.paySwapList.length > 0) {
var item = this.paySwapList[0];
- var notional = item.PosiGrossPrice * item.ContractSize;
+ var deliveryPrice = this.roundStorageDeliveryPrice(item, item.PosiGrossPrice);
+ var notional = deliveryPrice * item.ContractSize;
item.PosiQuantity = notional == 0 ? 0 : _.round(this.trade.StockEqvNotional / notional, page.otcFormatConfig.StockEqvNotional.precision);
this.calcNotional();
}
@@ -457,7 +470,8 @@ const vue = new Vue({
}
var national = payItem.PosiQuantity * payItem.ContractSize;
// 守卫: 名义本金必须 round 到 2 位 → 对应历史 bug f873239a(缺 _.round); 外置到 swapCalc.calcStockEqvNotional
- var stockEqvNotional = SwapCalc.calcStockEqvNotional(payItem.PosiGrossPrice, national);//名义本金=期初价格*数量*乘数
+ var deliveryPrice = this.roundStorageDeliveryPrice(payItem, payItem.PosiGrossPrice);
+ var stockEqvNotional = SwapCalc.calcStockEqvNotional(deliveryPrice, national);//名义本金=期初价格*数量*乘数
this.trade.StockEqvNotional = otcformat.trading.stockEqvNotional(stockEqvNotional);
payItem.PosiNotionalValue = this.trade.StockEqvNotional;
}
@@ -601,6 +615,9 @@ const vue = new Vue({
errorcount++;
return false;
}
+ x.PosiGrossPrice = thisObj.roundStorageDeliveryPrice(x, x.PosiGrossPrice);
+ x.PosiNetNoFeePrice = thisObj.roundStorageBondNetPriceAndYtm(x.PosiNetNoFeePrice);
+ x.InitYtm = x.InitYtm == null ? null : thisObj.roundStorageBondNetPriceAndYtm(x.InitYtm);
thisObj.trade.swap_positions.push(x);
});
} else {
@@ -735,8 +752,8 @@ const vue = new Vue({
// 非 EodPrice 分支 ×bondPriceMultiple=0.01)。故此处仅做精度格式化,**不可**再 bondCalcPriceToStorage(÷100),
// 否则默认价 1.0 被除成 0.01,界面 percent:true 再 ×100 显示为 1("被自动除以100"bug)。
// 计算器(/Bond/CalcBond)返回的才是展示态,其 ÷100 落库逻辑在 calcBondForItem 内处理。
- item.PosiNetNoFeePrice = otcformat.trading.umprice(resp.obj.netPrice);
- item.PosiGrossPrice = otcformat.trading.umprice(resp.obj.price);
+ item.PosiNetNoFeePrice = thisObj.roundStorageBondNetPriceAndYtm(resp.obj.netPrice);
+ item.PosiGrossPrice = thisObj.roundStorageDeliveryPrice(item, resp.obj.price);
thisObj.calcNotional();
});
},
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
index c7fd23ff..3838b7ea 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
@@ -7,6 +7,7 @@ const inputFormatTradeAmount = Object.freeze({ precision: otcformat.trading.noti
const inputFormatEqvNotional = Object.freeze({ precision: otcformat.trading.StockEqvNotional.precision, append: '', negative: true });
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 });
let ValueDate = model.ValueDate;
const vue = new Vue({
el: '#vueDiv',
@@ -40,6 +41,10 @@ const vue = new Vue({
getPriceScale() {
return this.multiplier == 100 ? 0.01 : 1;
},
+ getStorageDeliveryPrice() {
+ const precision = inputFormatSwapDeliveryPrice.precision + (this.multiplier === 100 ? 2 : 0);
+ return SwapCalc.roundHalfAwayFromZero(Number(this.floatPosition.TradingAmountAvg) * this.getPriceScale(), precision);
+ },
initDeal() {
var positions = model.FlowEvents.filter((item) => {
return item.UnderlyingCode;
@@ -84,7 +89,7 @@ const vue = new Vue({
this.deal.SwapCloseAmount = otcformat.trading.StockEqvNotional(this.deal.SwapCloseAmount);
//this.floatPosition.PosiNetPrice = otcformat.trading.tradeSinglePrice(this.floatPosition.PosiNetPrice);
//this.floatPosition.PosiGrossPrice = otcformat.trading.tradeSinglePrice(this.floatPosition.PosiGrossPrice);
- this.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(this.floatPosition.TradingAmountAvg);
+ this.floatPosition.TradingAmountAvg = _.round(Number(this.floatPosition.TradingAmountAvg), 9);
this.floatPosition.TradingFee = otcformat.trading.StockEqvNotional(this.floatPosition.TradingFee);
this.floatPosition.TradingFeePending = otcformat.trading.StockEqvNotional(this.floatPosition.TradingFeePending);
this.floatPosition.DividendIn = parseFloat(this.floatPosition.DividendIn).toFixed(2);
@@ -212,7 +217,7 @@ const vue = new Vue({
{ code: thisObj.floatPosition.UnderlyingCode, valuedate: thisObj.deal.ValueDate })
.done(function (res) {
res.obj = res.obj * thisObj.multiplier;
- thisObj.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(res.obj);
+ thisObj.floatPosition.TradingAmountAvg = _.round(Number(res.obj), 9);
thisObj.calcFloatClosePnl();
});
},
@@ -222,8 +227,8 @@ const vue = new Vue({
let longRatio = thisObj.floatPosition.PositionType == 1 ? 1 : -1;
let TradingFee = thisObj.floatPosition.TradingFee == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFee);
let TradingFeePending = thisObj.floatPosition.TradingFeePending == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFeePending);
- let scale = thisObj.getPriceScale();
- thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (thisObj.floatPosition.TradingAmountAvg * scale - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
+ let deliveryPrice = thisObj.getStorageDeliveryPrice();
+ thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (deliveryPrice - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
thisObj.floatPosition.MarkClosePnl = Number(thisObj.floatPosition.MarkClosePnl.toFixed(2));//MarkClosePnl 纯盯市不要计算交易费用和分红
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);
thisObj.floatPosition.FloatPnlSum = (parseFloat(thisObj.floatPosition.MarkClosePnl) + TradingFee + TradingFeePending + parseFloat(thisObj.floatPosition.DividendIn)).toFixed(2);
@@ -253,13 +258,13 @@ const vue = new Vue({
thisObj.deal.SwapRealizedPnL = pnl;
thisObj.deal.SwapMarginRebatePnl = 0;
thisObj.deal.SwapMarginAmount = 0;
- let scale = thisObj.getPriceScale();
- thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseQty) * scale;
+ let deliveryPrice = thisObj.getStorageDeliveryPrice();
+ thisObj.floatPosition.TradingAmount = deliveryPrice * parseFloat(thisObj.deal.CloseQty);
thisObj.floatPosition.CloseFee = TradingFee;
if (thisObj.deal.CloseQty == 0) {
thisObj.floatPosition.TradingAmountFeeAvg = 0;
} else {
- thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale + (TradingFee / thisObj.deal.CloseQty) * ratio;
+ thisObj.floatPosition.TradingAmountFeeAvg = deliveryPrice + (TradingFee / thisObj.deal.CloseQty) * ratio;
}
this.interestList.forEach(x => {
/*let interestRatio = x.InterestDirection == 1 ? 1 : -1;*/
@@ -360,7 +365,7 @@ const vue = new Vue({
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
let floatPosition = _.cloneDeep(thisObj.floatPosition);
floatPosition.Quantity = reqObj.CloseQty;
- floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * thisObj.getPriceScale();
+ floatPosition.TradingAmountAvg = thisObj.getStorageDeliveryPrice();
reqObj.FlowEvents.push(floatPosition);
var postData = { unwindData: reqObj };
var msg = "确认提交平仓?";
diff --git a/YLErpWeb/wwwroot/Scripts/app/tradeHelper.js b/YLErpWeb/wwwroot/Scripts/app/tradeHelper.js
index 75701fcb..fa58d6ff 100644
--- a/YLErpWeb/wwwroot/Scripts/app/tradeHelper.js
+++ b/YLErpWeb/wwwroot/Scripts/app/tradeHelper.js
@@ -276,6 +276,7 @@
tradeHelper.IsBond = function (instType) {
switch (instType) {
case "Bonds":
+ case "Bond":
case "TBonds":
case "CreditBonds":
case "OtherBonds":
diff --git a/YLErpWeb/wwwroot/Statics/views/TradeDetailsListMailV2.cshtml b/YLErpWeb/wwwroot/Statics/views/TradeDetailsListMailV2.cshtml
index 36b18756..44cc8c9f 100644
--- a/YLErpWeb/wwwroot/Statics/views/TradeDetailsListMailV2.cshtml
+++ b/YLErpWeb/wwwroot/Statics/views/TradeDetailsListMailV2.cshtml
@@ -897,7 +897,7 @@
| @tr.MetaDic["互换_收取方初始预付金"] |
@tr.MetaDic["互换_收取方交易费用"] |
@tr.MetaDic["互换_收取方多空方向"] |
- @tr.OriginalStockEqvNotional |
+ @tr.TdDetail.OriginalStockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional) |
@tr.MetaDic["年化天数"] |
@tr.MetaDic["互换_互换日期"] |