#EQD-6290 日终持仓风险-互换持仓价值和已实现盈亏不正确 ; 未实现的分红到期时未去掉
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
*.lscache
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using BaseOUDAL;
|
||||
using Newtonsoft.Json;
|
||||
using NPOI.POIFS.Properties;
|
||||
using System.Linq.Expressions;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.DBModels.Consts;
|
||||
@@ -471,12 +472,13 @@ namespace YLErp.Modules.SwapModule
|
||||
eodPosi.TdCloseDividend += eodPosi.PosiDividendSum;
|
||||
eodPosi.TdPosiDividend = 0;
|
||||
eodPosi.RealizedDividend += eodPosi.PosiDividendSum;
|
||||
eodPosi.PosiDividendSum = 0;
|
||||
eodPosi.PosiProfitSum -= eodPosi.TdCloseDividend;
|
||||
//互换持仓价值要去掉已实现的
|
||||
eodPosi.SwapPositionValue -= eodPosi.PosiDividendSum;
|
||||
//已实现盈亏要加上已实现的
|
||||
eodPosi.RealizedPnl += eodPosi.PosiDividendSum;
|
||||
eodPosi.PosiDividendSum = 0;
|
||||
eodPosi.PosiProfitSum -= eodPosi.TdCloseDividend;
|
||||
|
||||
}
|
||||
|
||||
UnwindData unwindData = new UnwindData();
|
||||
@@ -1460,6 +1462,12 @@ namespace YLErp.Modules.SwapModule
|
||||
int shortRatio = eod.PositionType == (int)PositionTypeFlag.Long ? 1 : -1;
|
||||
int directionRatio = eod.PosiDirection == (int)SwapDirectionEnum.收取 ? 1 : -1;
|
||||
var price = UnderlyingCodePrice(eod.UnderlyingCode, dealDate, out decimal vobp);
|
||||
var todayConsumedDividend = CalcConsumedDividend(curretEod, unwindEvents);
|
||||
var originNotional = (decimal)td.OriginalStockEqvNotional / swapPosition.PosiNetPrice;
|
||||
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
|
||||
decimal totalPayment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, td.StartDate.Value, valueDate, (decimal)originNotional, shortRatio, directionRatio);
|
||||
decimal tax = um.ValueAddedTax ?? 0;
|
||||
decimal totalInterest = totalPayment / (1 + tax) * (1 - tax);
|
||||
SetPriceInfoByFlowEvent(eod, curretEod, unwindEvents, swapPosition);
|
||||
curretEod.dv01 = Dv01Helper.CalcDv01(eod.UnderlyingCode, curretEod.PosiQuantity, eod.PosiDirection, eod.PositionType, vobp);
|
||||
curretEod.UnderlyingPrice = price;
|
||||
@@ -1467,21 +1475,20 @@ namespace YLErp.Modules.SwapModule
|
||||
curretEod.PosiMtmPnL = (curretEod.UnderlyingPrice - curretEod.PosiGrossPrice) * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio * directionRatio;
|
||||
curretEod.TdPosiDividend = 0;
|
||||
// 分红与互换无关,只要持仓>0且起始日早于当前日,正常计算当日分红
|
||||
// 修改,互换事件会影响待实现的分红的,现在要算上
|
||||
if (valueDate > td.StartDate.Value && (curretEod.PosiQuantity > 0))
|
||||
{
|
||||
decimal tax = um.ValueAddedTax ?? 0;
|
||||
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
|
||||
decimal payment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, eod.ValueDate, valueDate, curretEod.PosiQuantity, shortRatio, directionRatio);
|
||||
curretEod.TdPosiDividend = Math.Round(payment / (1 + tax) * (1 - tax), 2);
|
||||
}
|
||||
curretEod.RealizedMtmPnL = eod.RealizedMtmPnL + curretEod.TdCloseMtmPnl;
|
||||
|
||||
// 当日浮动端平仓盈亏·分红(仅来自平仓事件 和 互换 中已实现的分红)
|
||||
curretEod.TdCloseDividend = unwindEvents.Sum(e => e.DividendIn);
|
||||
curretEod.RealizedFee = eod.RealizedFee + curretEod.TdCloseFee;
|
||||
curretEod.RealizedPnl = eod.RealizedPnl + curretEod.TdCloseMtmPnl;
|
||||
curretEod.PosiStatus = curretEod.PosiQuantity == 0 ? 1 : 0;
|
||||
var closeQty = unwindEvents.Where(x => x.EventType == (int)SwapFlowEventTypeEnum.平仓).ToList().Sum(s => s.Quantity);
|
||||
// 当日浮动端平仓盈亏·分红(仅来自平仓事件中已实现的分红)
|
||||
curretEod.TdCloseDividend = unwindEvents.Sum(e => e.DividendIn);
|
||||
|
||||
curretEod.RealizedDividend = curretEod.RealizedDividend + curretEod.TdCloseDividend;
|
||||
|
||||
// 分红与互换解耦:持仓>0时从起始日重算待实现分红,不再受互换事件影响
|
||||
@@ -1490,11 +1497,9 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
//decimal tax = um.ValueAddedTax ?? 0;
|
||||
//BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
|
||||
//decimal totalPayment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, td.StartDate.Value, valueDate, td.., shortRatio, directionRatio);
|
||||
//decimal totalPayment = bondPaymentService.CalcPayment(curretEod.UnderlyingCode, td.StartDate.Value, valueDate, (decimal)originNotional, shortRatio, directionRatio);
|
||||
//var totalInterest = totalPayment / (1 + tax) * (1 - tax);
|
||||
var consumedDividend = - 1 * CalcConsumedDividend(curretEod, unwindEvents);
|
||||
|
||||
curretEod.PosiDividendSum = eod.PosiDividendSum - consumedDividend - curretEod.TdCloseDividend;
|
||||
curretEod.PosiDividendSum = Math.Round(totalInterest,2) - curretEod.RealizedDividend;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,2 +1,125 @@
|
||||
var main = main || {};
|
||||
main.formatOptions = { "trading": { "umprice": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "umpriceP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "umpricePR": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "tradeSinglePrice": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "premiumRateP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "premiumRate": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "tradePrice": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "StockEqvNotional": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "notional": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "notionalP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "volatility": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "volatilityP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "greek": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "marginRateP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "marginRate": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 } } };
|
||||
main.formatOptions={
|
||||
"trading": {
|
||||
"umprice": {
|
||||
"precision": 9,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 9,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"umpriceP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"umpricePR": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
},
|
||||
"tradeSinglePrice": {
|
||||
"precision": 2,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"premiumRateP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"premiumRate": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
},
|
||||
"tradePrice": {
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"StockEqvNotional": {
|
||||
"precision": 2,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"notional": {
|
||||
"precision": 2,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"notionalP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"volatility": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
},
|
||||
"volatilityP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"greek": {
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"marginRateP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"marginRate": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user