Merge branch 'glms/feature/1.4.2-etf' into glms/feature/1.4.2

# Conflicts:
#	YLErpWeb/wwwroot/Scripts/app/swaptrade/incomeSwapTrade.js
This commit is contained in:
吴方海
2026-06-22 13:45:25 +08:00
10 changed files with 169 additions and 93 deletions
@@ -51,6 +51,7 @@ namespace YLErp.Web.Controllers
OpenFeeType = 0,
InterestCalcMode = "10",
SettlementRules=0,
DividendPayDate=0
};
r = new trade()
{
@@ -307,6 +307,7 @@ namespace YLErp.Web.Controllers
if (EodPriceQueryService.TryGetEodPrice(valuedate.Value, code, out var eodPrice))
{
price = eodPrice.GetPrice((SettlementTypeEnum)settlementType);
return JsonSuccessData(price);
}
}
+9 -7
View File
@@ -1,4 +1,4 @@
@model UnwindData
@model UnwindData
@{
ViewBag.Title = "交易 | 收益结算";
Layout = "~/Views/Shared/_InfoLayout.cshtml";
@@ -133,10 +133,12 @@
<td width="116px">收支方向</td>
<td>多空方向</td>
<td>标的代码</td>
<td>期初标的交割全价%</td>
<td>期初标的交割净价%</td>
<td>标的价格%</td>
<td>持仓数量</td>
<td v-if="deal.StructureType!='普通收益互换'">期初标的交割全价%</td>
<td v-if="deal.StructureType!='普通收益互换'">期初标的交割净价%</td>
<td v-else>期初标的价格</td>
<td v-if="deal.StructureType!='普通收益互换'">期末标的交割全价%</td>
<td v-else>期末标的价格</td>
<td>数量</td>
<td>交易费用(平仓)</td>
<td>分红收益</td>
<td>浮动端平仓盈亏</td>
@@ -150,9 +152,9 @@
{{floatPosition.UnderlyingCode}}
</td>
<td>{{priceFormat(floatPosition.PosiGrossPrice)}}</td>
<td>{{priceFormat(floatPosition.TradingAmountNetAvg)}}</td>
<td v-if="deal.StructureType!='普通收益互换'">{{priceFormat(floatPosition.TradingAmountNetAvg)}}</td>
<td>
{{floatPosition.TradingAmountAvg}}
{{priceFormat(floatPosition.TradingAmountAvg)}}
</td>
<td>{{floatPosition.Quantity}}</td>
<td>
+6 -4
View File
@@ -1,4 +1,4 @@
@model UnwindData
@model UnwindData
@{
ViewBag.Title = "交易 | 交易平仓";
Layout = "~/Views/Shared/_InfoLayout.cshtml";
@@ -179,9 +179,11 @@
<td width="116px">收支方向</td>
<td>多空方向</td>
<td>标的代码</td>
<td>期初标的交割全价%</td>
<td>期标的交割全价%</td>
<td>持仓数量</td>
<td v-if="deal.StructureType!='普通收益互换'">期初标的交割全价%</td>
<td v-else>期标的价格</td>
<td v-if="deal.StructureType!='普通收益互换'">期末标的交割全价%</td>
<td v-else>期末标的价格</td>
<td>数量</td>
<td>交易费用(平仓)</td>
<td>交易费用(待结算)</td>
<td>分红收益</td>
+15 -10
View File
@@ -423,9 +423,10 @@
<th>收支方向</th>
<th>多空方向</th>
<th>标的代码</th>
<th>期初标的交割全价%</th>
<th>期初标的交割净价%</th>
<th>期初标的成交收益率%</th>
<th v-if="trade.StructureType!='普通收益互换'">期初标的交割全价%</th>
<th v-if="trade.StructureType!='普通收益互换'">期初标的交割净价%</th>
<th v-if="trade.StructureType!='普通收益互换'">期初标的成交收益率%</th>
<th v-if="trade.StructureType=='普通收益互换'">期初标的价格</th>
<th>数量</th>
<th>交易费用后付</th>
</tr>
@@ -443,19 +444,23 @@
</select>
</td>
<td>
<vue-underlying v-model="item.UnderlyingCode" v-on:change="setUnderlyingCode($event,item)" ></vue-underlying>
<vue-underlying-nonbond :key="getPosiPriceFormatKey(item,'UnderlyingCode')" v-if="trade.StructureType=='普通收益互换'" v-model="item.UnderlyingCode" v-on:change="setUnderlyingCode($event,item)"></vue-underlying-nonbond>
<vue-underlying-bond :key="getPosiPriceFormatKey(item,'normalUnderlyingCode')" v-else v-model="item.UnderlyingCode" v-on:change="setUnderlyingCode($event,item)"></vue-underlying-bond>
<a href="javascript:void(0);" title="发行信息" v-on:click="showUnderlyingInfo(item)" :id="'popover'+item.index" class="un" v-show="trade.StructureType!='普通收益互换'">
<span class="glyphicon glyphicon glyphicon-edit" aria-hidden="true" style="color:#ff0000"></span>
</a>
</td>
<td>
<vue-number-input :key="getPosiPriceFormatKey(item,'PosiGrossPrice')" v-model="item.PosiGrossPrice" v-bind:format="getPosiPriceFormat(item)" v-on:input="changeSpotPrice(item)"></vue-number-input>
<td v-if="trade.StructureType!='普通收益互换'">
<vue-number-input :key="getPosiPriceFormatKey(item,'PosiGrossPrice')" v-model="item.PosiGrossPrice" v-bind:format="inputFormatMarginRateNoPercent" v-on:input="changeSpotPrice(item)"></vue-number-input>
</td>
<td>
<vue-number-input :key="getPosiPriceFormatKey(item,'PosiNetNoFeePrice')" v-model="item.PosiNetNoFeePrice" v-bind:format="getPosiPriceFormat(item)"></vue-number-input>
<td v-if="trade.StructureType!='普通收益互换'">
<vue-number-input :key="getPosiPriceFormatKey(item,'PosiNetNoFeePrice')" v-model="item.PosiNetNoFeePrice" v-bind:format="inputFormatMarginRateNoPercent"></vue-number-input>
</td>
<td>
<vue-number-input :key="getPosiPriceFormatKey(item,'InitYtm')" v-model="item.InitYtm" v-bind:format="getPosiPriceFormat(item)"></vue-number-input>
<td v-if="trade.StructureType!='普通收益互换'">
<vue-number-input :key="getPosiPriceFormatKey(item,'InitYtm')" v-model="item.InitYtm" v-bind:format="inputFormatMarginRateNoPercent"></vue-number-input>
</td>
<td v-if="trade.StructureType=='普通收益互换'">
<vue-number-input :key="getPosiPriceFormatKey(item,'normalPosiGrossPrice')" v-model="item.PosiGrossPrice" v-bind:format="inputFormatTradeSinglePrice" v-on:input="changeSpotPrice(item)"></vue-number-input>
</td>
<td>
<vue-number-input v-model="item.PosiQuantity" v-on:input="changeQuantity(item)" v-bind:format="inputFormatTradeAmount"></vue-number-input>{{item.underlying!=null?item.underlying.QuoteUnitString:''}}
+73 -29
View File
@@ -22,9 +22,10 @@
var swap_deals = trade.swap_Events.Where(x => x.EventType == (int)SwapEventTypeEnum.互换 || x.EventType == (int)SwapEventTypeEnum.自动互换).ToList();//单标的/多空组合互换 互换记录
var closeSwapDeals = trade.swap_Events.Where(x => x.EventType == (int)SwapEventTypeEnum.平仓).ToList();//单标的互换 平仓记录
bool isBond = trade.StructureType == "普通债券类收益互换";
string spotPriceTitle = "期初标的交割全价%";
string netSportPriceTitle = "期初标的交割净价%";
string initYtmTitle = "期初标的成交收益率%";
string spotPriceTitle = isBond ? "期初标的交割全价%" : "期初标的价格";
string netSportPriceTitle = isBond ? "期初标的交割净价%" : string.Empty;
string initYtmTitle = isBond ? "期初标的成交收益率%" : string.Empty;
string endSpotPriceTitle = isBond ? "期末标的交割全价%" : "期末标的价格";
var positions = trade.swap_positions.Where(x=>x.PosiDirection>0&&x.IsInitial).ToList();
var realPositions = trade.swap_positions.Where(x => x.PosiDirection > 0 && !x.IsInitial).ToList();
var sr = trade.trade_extend.ExtendObj.SettlementRules;
@@ -368,8 +369,11 @@
<td>多空方向</td>
<td>标的代码</td>
<td>@spotPriceTitle</td>
<td>@netSportPriceTitle</td>
<td>@initYtmTitle</td>
@if (isBond)
{
<td>@netSportPriceTitle</td>
<td>@initYtmTitle</td>
}
<td>数量</td>
<td>交易费用后付</td>
</tr>
@@ -384,12 +388,15 @@
<td>
@((item.PosiGrossPrice * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
<td>
@(((item.PosiNetNoFeePrice ?? 0) * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
<td>
@((item.InitYtm * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
@if (isBond)
{
<td>
@(((item.PosiNetNoFeePrice ?? 0) * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
<td>
@((item.InitYtm * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
}
<td>
@item.PosiQuantity.OtcFormat(OtcFormatFlag.StockEqvNotional)
</td>
@@ -561,8 +568,11 @@
<td>多空方向</td>
<td>标的代码</td>
<td>@spotPriceTitle</td>
<td>@netSportPriceTitle</td>
<td>持仓数量</td>
@if (isBond)
{
<td>@netSportPriceTitle</td>
}
<td>数量</td>
<td>持仓名义本金</td>
<td>交易费用后付</td>
<td>起始日期</td>
@@ -583,9 +593,12 @@
<td>
@((item.PosiGrossPrice * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
<td>
@(((item.PosiNetNoFeePrice ?? 0) * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
@if (isBond)
{
<td>
@(((item.PosiNetNoFeePrice ?? 0) * multiplier).OtcFormat(OtcFormatFlag.umprice))
</td>
}
<td>
@item.PosiQuantity.OtcFormat(OtcFormatFlag.StockEqvNotional)
</td>
@@ -761,9 +774,17 @@
<td>收支方向</td>
<td>多空方向</td>
<td>标的代码</td>
<td>期初标的交割全价%</td>
<td>期末标的交割全价%</td>
<td>平仓数量</td>
@if (isBond)
{
<td>期初标的交割全价%</td>
<td>期末标的交割全价%</td>
}
else
{
<td>期初标的价格</td>
<td>期末标的价格</td>
}
<td>数量</td>
<td>交易费用</td>
<td>交易费用(待结算)</td>
<td>分红收益</td>
@@ -773,8 +794,16 @@
<td class="@fbgclass" style="width:116px !important;">@((SwapDirectionEnum)closeFloat.PayDirection)</td>
<td>@(closeFloat.PositionType == (int)PositionTypeFlag.Long ? "多头" : "空头")</td>
<td>@closeFloat.UnderlyingCode</td>
<td>@((closeFloat.PosiGrossPrice * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
<td>@((closeFloat.TradingAmountAvg * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
@if (isBond)
{
<td>@((closeFloat.PosiGrossPrice * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
<td>@((closeFloat.TradingAmountAvg * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
}
else
{
<td>@(closeFloat.PosiGrossPrice.OtcFormat(OtcFormatFlag.umprice))</td>
<td>@(closeFloat.TradingAmountAvg.OtcFormat(OtcFormatFlag.umprice))</td>
}
<td>@(closeFloat.Quantity.OtcFormat(OtcFormatFlag.StockEqvNotional))</td>
<td>@(closeFloat.TradingFee.OtcFormat(OtcFormatFlag.StockEqvNotional))</td>
<td>@(closeFloat.TradingFeePending.OtcFormat(OtcFormatFlag.StockEqvNotional))</td>
@@ -938,10 +967,18 @@
<td>收支方向</td>
<td>多空方向</td>
<td>标的代码</td>
<td>@spotPriceTitle</td>
<td>@netSportPriceTitle</td>
<td>标的价格%</td>
<td>持仓数量</td>
@if (isBond)
{
<td>@spotPriceTitle</td>
<td>@netSportPriceTitle</td>
}
else
{
<td>标的价格</td>
}
<td>@endSpotPriceTitle</td>
<td>数量</td>
<td>交易费用</td>
<td>分红收益</td>
<td>浮动端平仓盈亏</td>
@@ -950,9 +987,16 @@
<td class="@fbgclass" style="width:116px !important;">@((SwapDirectionEnum)closeFloat.PayDirection)</td>
<td>@(closeFloat.PositionType == (int)PositionTypeFlag.Long ? "多头" : "空头")</td>
<td>@closeFloat.UnderlyingCode</td>
<td>@((closeFloat.PosiGrossPrice * multiplier).OtcFormat(OtcFormatFlag.umpriceP))</td>
<td>@(((closeFloat.TradingAmountNetAvg ?? 0) * multiplier).OtcFormat(OtcFormatFlag.umpriceP))</td>
<td>@((closeFloat.TradingAmountAvg * multiplier).OtcFormat(OtcFormatFlag.umpriceP))</td>
@if (isBond)
{
<td>@((closeFloat.PosiGrossPrice * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
<td>@(((closeFloat.TradingAmountNetAvg ?? 0) * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
}
else
{
<td>@((closeFloat.TradingAmountAvg * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
}
<td>@((closeFloat.TradingAmountAvg * multiplier).OtcFormat(OtcFormatFlag.umprice))</td>
<td>@((closeFloat.PositionQty??0).OtcFormat(OtcFormatFlag.StockEqvNotional))</td>
<td>@(closeFloat.TradingFee.OtcFormat(OtcFormatFlag.StockEqvNotional))</td>
<td>@(closeFloat.DividendIn.OtcFormat(OtcFormatFlag.StockEqvNotional))</td>
@@ -1057,4 +1101,4 @@
@if (!string.IsNullOrWhiteSpace(Context.Request.Query["abstract"]))
{
@await Html.PartialAsync("/Views/trade/_part/TradeAbstractInfo.cshtml", Model.Trade)
}
}
@@ -1,4 +1,4 @@
//otcformat禁止千分位分组
//otcformat禁止千分位分组
window.otcformat.options.disableGrouping = true;
const inputFormatSwapRate = Object.freeze({ precision: otcformat.trading.premiumRateP.precision, append: '%' });
@@ -27,13 +27,14 @@ const vue = new Vue({
}
},
created() {
this.multiplier = this.deal.StructureType == '普通债券类收益互换' ? 100 : 1;
this.initDeal();
this.setValueDate();
if (this.deal.StructureType != '普通收益互换') {
this.multiplier = 100;
}
},
methods: {
getPriceScale() {
return this.multiplier == 100 ? 0.01 : 1;
},
initDeal() {
var positions = model.FlowEvents.filter((item) => {
return item.UnderlyingCode;
@@ -41,7 +42,7 @@ const vue = new Vue({
this.floatPosition = positions[0];
this.initPosiNetPrice = this.floatPosition.PosiNetPrice;
// 互换标的价格固定为期初净价,与平仓不同不需要用户填写
this.floatPosition.TradingAmountAvg = this.initPosiNetPrice * 100;
this.floatPosition.TradingAmountAvg = this.initPosiNetPrice;
this.interestList = model.FlowEvents.filter((item) => {
return item.InterestMode == 1 || item.InterestMode == 2 || item.InterestMode == 7 || item.InterestMode == 8 || item.InterestMode == 9;
});
@@ -114,7 +115,8 @@ 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);
thisObj.floatPosition.MarkClosePnl = thisObj.deal.CloseNotionalValue * (thisObj.floatPosition.TradingAmountAvg*0.01 - thisObj.initPosiNetPrice) * floatRatio;
let scale = thisObj.getPriceScale();
thisObj.floatPosition.MarkClosePnl = thisObj.deal.CloseNotionalValue * (thisObj.floatPosition.TradingAmountAvg * scale - thisObj.initPosiNetPrice) * floatRatio;
thisObj.floatPosition.MarkClosePnl = thisObj.floatPosition.MarkClosePnl + TradingFee + TradingFeePending + DividendIn;
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);
thisObj.calcCloseAmount();
@@ -133,12 +135,13 @@ const vue = new Vue({
thisObj.deal.SwapRealizedPnL = pnl;
thisObj.deal.SwapMarginRebatePnl = 0;
thisObj.deal.SwapMarginAmount = 0;
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue) * 0.01;
let scale = thisObj.getPriceScale();
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue) * scale;
thisObj.floatPosition.CloseFee = TradingFee;
if (thisObj.deal.CloseQty > 0) {
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * 0.01 + (TradingFee / thisObj.deal.CloseQty) * floatRatio;
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale + (TradingFee / thisObj.deal.CloseQty) * floatRatio;
} else {
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * 0.01;
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale;
}
this.interestList.forEach(x => {
//let interestRatio = x.InterestDirection == 1 ? 1 : -1;
@@ -201,7 +204,7 @@ const vue = new Vue({
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
let floatPosition = _.cloneDeep(thisObj.floatPosition);
floatPosition.Quantity = 0;
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * 0.01;
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * thisObj.getPriceScale();
reqObj.FlowEvents.push(floatPosition);
var postData = { unwindData: reqObj };
var msg = "确认提交收益结算?";
@@ -11,14 +11,22 @@ const inputFormatEqvNotional = Object.freeze({ precision: otcformat.trading.Stoc
const inputFormatTradeAmount = Object.freeze({ precision: otcformat.trading.notional.precision, append: '' });
const inputFormatSwapRate = Object.freeze({ precision: otcformat.trading.premiumRateP.precision, negative: true, append: '%' });
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradePrice.precision, negative: true, append: '' });
const inputFormatTradeSinglePrice = Object.freeze({ precision: otcformat.trading.tradeSinglePrice.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 consUnderlyingFlag = (function () {
const consUnderlyingFlagBase = (function () {
let unSelFlag = tradeHelper.UnderlyingSelectFlag;
return unSelFlag.UseForTrading | unSelFlag.IncludeMatured | unSelFlag.UsePinYinFilter | unSelFlag.IncludeBasket | unSelFlag.IncludeSynthetic | unSelFlag.CheckLaunch;
}());
const consUnderlyingFlagNonBond = (function () {
let unSelFlag = tradeHelper.UnderlyingSelectFlag;
return consUnderlyingFlagBase | unSelFlag.Stock | unSelFlag.StockIndex | unSelFlag.StockIF | unSelFlag.CommodityFutures | unSelFlag.CommoditySpot;
}());
const consUnderlyingFlagBond = (function () {
let unSelFlag = tradeHelper.UnderlyingSelectFlag;
return consUnderlyingFlagBase | unSelFlag.CreditBonds | unSelFlag.Bonds | unSelFlag.TBonds | unSelFlag.OtherBonds;
}());
const inputFormatDouble2 = Object.freeze({ precision: 2, append: '' });
var autoMarginTemplateName;
@@ -42,16 +50,14 @@ const consNumberFormat = Object.freeze(new function () {
return this;
}());
//标的选择组件
const vueUnderlying = function () {
const createVueUnderlying = function (selectFlag) {
return {
props: ['value', 'index'],
data() {
return { autoUnderlying: null };
},
mounted() {
var selFlag = tradeHelper.UnderlyingSelectFlag;
this.autoUnderlying = tradeHelper.UnderlyingAutoComplete(this.$el, { SelectFlag: selFlag.UsePinYinFilter | selFlag.UseForTrading | selFlag.IncludeSynthetic | selFlag.IncludeMatured | selFlag.IncludeBasket | selFlag.CheckLaunch, BlackLimit: 2, });
this.autoUnderlying = tradeHelper.UnderlyingAutoComplete(this.$el, { SelectFlag: selectFlag, BlackLimit: 2, });
this.autoUnderlying.onSelect(this.onchange);
this.value && this.autoUnderlying.selectByCode(this.value);
},
@@ -67,6 +73,12 @@ const vueUnderlying = function () {
template: '<input type="text" v-model="value" />'
};
};
const vueUnderlyingNonBond = function () {
return createVueUnderlying(consUnderlyingFlagNonBond);
};
const vueUnderlyingBond = function () {
return createVueUnderlying(consUnderlyingFlagBond);
};
//标的选择组件 银行间回购定盘&其他利率
const vueUnderlyingRate = function () {
@@ -177,11 +189,6 @@ const vue = new Vue({
this.initSwapRateList();
},
methods: {
getPosiPriceFormat(item) {
return tradeHelper.IsBond(item && item.UnderlyingInstrumentType)
? inputFormatMarginRateNoPercent
: inputFormatTradeSinglePrice;
},
getPosiPriceFormatKey(item, field) {
const index = item && item.index != null ? item.index : '';
const isBond = tradeHelper.IsBond(item && item.UnderlyingInstrumentType);
@@ -189,6 +196,13 @@ const vue = new Vue({
},
changeStructureType() {
this.trade.StockEqvNotional = 0;
let direction = this.trade.trade_extend.ExtendObj.Direction;
if (direction !== 1 && direction !== 2) {
direction = 2;
this.trade.trade_extend.ExtendObj.Direction = direction;
}
this.paySwapList = [];
this.addSwapFloat(direction);
//this.trade.trade_extend.ExtendObj.FlowBookMode = 0;
},
//变更初始预付金收取方向
@@ -1432,7 +1446,8 @@ const vue = new Vue({
components: {
'vue-datepicker': FastVue.vueDatePicker(),
'vue-number-input': FastVue.vueNumberInput(),
'vue-underlying': vueUnderlying(),
'vue-underlying-nonbond': vueUnderlyingNonBond(),
'vue-underlying-bond': vueUnderlyingBond(),
'vue-underlying-rate': vueUnderlyingRate()
},
destroyed() {
@@ -1,4 +1,4 @@
//otcformat禁止千分位分组
//otcformat禁止千分位分组
window.otcformat.options.disableGrouping = true;
const inputFormatSwapRate = Object.freeze({ precision: otcformat.trading.premiumRateP.precision, append: '%' });
@@ -30,13 +30,14 @@ const vue = new Vue({
}
},
created() {
if (this.deal.StructureType != '普通收益互换') {
this.multiplier = 100;
}
this.multiplier = this.deal.StructureType == '普通债券类收益互换' ? 100 : 1;
this.initDeal();
this.setUnwindDate();
},
methods: {
getPriceScale() {
return this.multiplier == 100 ? 0.01 : 1;
},
initDeal() {
var positions = model.FlowEvents.filter((item) => {
return item.UnderlyingCode;
@@ -187,7 +188,7 @@ const vue = new Vue({
main.post("/underlying_manager/GetUnderlyingPriceByCode",
{ code: thisObj.floatPosition.UnderlyingCode, valuedate: thisObj.deal.ValueDate })
.done(function (res) {
res.obj = res.obj * 100;
res.obj = res.obj * thisObj.multiplier;
thisObj.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(res.obj);
thisObj.calcFloatClosePnl();
});
@@ -198,7 +199,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);
thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (thisObj.floatPosition.TradingAmountAvg*0.01 - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
let scale = thisObj.getPriceScale();
thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (thisObj.floatPosition.TradingAmountAvg * scale - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
thisObj.floatPosition.MarkClosePnl = Number(thisObj.floatPosition.MarkClosePnl.toFixed(2));
thisObj.floatPosition.MarkClosePnl = thisObj.floatPosition.MarkClosePnl + (TradingFee + TradingFeePending) * floatRatio * -1 + parseFloat(thisObj.floatPosition.DividendIn);
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);
@@ -228,12 +230,13 @@ const vue = new Vue({
thisObj.deal.SwapRealizedPnL = pnl;
thisObj.deal.SwapMarginRebatePnl = 0;
thisObj.deal.SwapMarginAmount = 0;
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseQty) * 0.01;
let scale = thisObj.getPriceScale();
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseQty) * scale;
thisObj.floatPosition.CloseFee = TradingFee;
if (thisObj.deal.CloseQty == 0) {
thisObj.floatPosition.TradingAmountFeeAvg = 0;
} else {
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * 0.01 + (TradingFee / thisObj.deal.CloseQty) * ratio;
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale + (TradingFee / thisObj.deal.CloseQty) * ratio;
}
this.interestList.forEach(x => {
/*let interestRatio = x.InterestDirection == 1 ? 1 : -1;*/
@@ -325,7 +328,7 @@ const vue = new Vue({
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
let floatPosition = _.cloneDeep(thisObj.floatPosition);
floatPosition.Quantity = reqObj.CloseQty;
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * 0.01;
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * thisObj.getPriceScale();
reqObj.FlowEvents.push(floatPosition);
var postData = { unwindData: reqObj };
var msg = "确认提交平仓?";
+12 -12
View File
@@ -1,4 +1,4 @@
//tradeHelper
//tradeHelper
(function () {
function tradeHelper() { }
@@ -362,22 +362,22 @@
function __getPostData() {
let options = this.options;
let sf = options.SelectFlag;
let InstrumentTypes = options.InstrumentTypes;
(sf & SelectFlag.Stock) > 0 && (InstrumentTypes.push('Stock'));
(sf & SelectFlag.StockIndex) > 0 && (InstrumentTypes.push('StockIndex'));
(sf & SelectFlag.CommodityFutures) > 0 && (InstrumentTypes.push('CommodityFutures'));
(sf & SelectFlag.CommoditySpot) > 0 && (InstrumentTypes.push('CommoditySpot'));
(sf & SelectFlag.CreditBonds) > 0 && (InstrumentTypes.push('CreditBonds'));
(sf & SelectFlag.Bonds) > 0 && (InstrumentTypes.push('Bonds'));
(sf & SelectFlag.TBonds) > 0 && (InstrumentTypes.push('TBonds'));
(sf & SelectFlag.OtherBonds) > 0 && (InstrumentTypes.push('OtherBonds'));
let instrumentTypes = Array.isArray(options.InstrumentTypes) ? options.InstrumentTypes.slice() : [];
(sf & SelectFlag.Stock) > 0 && (instrumentTypes.push('Stock'));
(sf & SelectFlag.StockIndex) > 0 && (instrumentTypes.push('StockIndex'));
(sf & SelectFlag.CommodityFutures) > 0 && (instrumentTypes.push('CommodityFutures'));
(sf & SelectFlag.CommoditySpot) > 0 && (instrumentTypes.push('CommoditySpot'));
(sf & SelectFlag.CreditBonds) > 0 && (instrumentTypes.push('CreditBonds'));
(sf & SelectFlag.Bonds) > 0 && (instrumentTypes.push('Bonds'));
(sf & SelectFlag.TBonds) > 0 && (instrumentTypes.push('TBonds'));
(sf & SelectFlag.OtherBonds) > 0 && (instrumentTypes.push('OtherBonds'));
return {
FilterCode: '{{{q}}}',
ClientId: options.ClientId,
VarietyId: options.VarietyId,
BlackLimit: options.BlackLimit,
MaxShowLength: options.MaxShowLength,
InstrumentTypes: InstrumentTypes,
InstrumentTypes: instrumentTypes,
UsePinYinFilter: (sf & (SelectFlag.UsePinYinFilter | SelectFlag.Stock | SelectFlag.StockIndex)) > 0,
IncludeMatured: (sf & SelectFlag.IncludeMatured) > 0,
OnlySynthetic: (sf & SelectFlag.OnlySynthetic) > 0,
@@ -728,4 +728,4 @@
}(window.tradeHelper));
Object.freeze(window.tradeHelper);
Object.freeze(window.tradeHelper);