diff --git a/Framework/YLErp.Core/DBModels/BondPayment.cs b/Framework/YLErp.Core/DBModels/BondPayment.cs index bcf23d60..94056c19 100644 --- a/Framework/YLErp.Core/DBModels/BondPayment.cs +++ b/Framework/YLErp.Core/DBModels/BondPayment.cs @@ -102,6 +102,7 @@ namespace YLErp.DBModels /// /// 更新时间 /// + [DisplayName("更新时间")] [Column("update_time")] public DateTime update_time { get; set; } } diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs index 19775965..3d3d0e9b 100644 --- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs @@ -9,6 +9,7 @@ using OfficeOpenXml.Drawing.Controls; using Org.BouncyCastle.Asn1.Ocsp; using Qdp.Pricing.Base.Implementations; using Qdp.Pricing.Core.Modules; +using Qdp.Pricing.Library.Base.Utilities; using System.Linq.Expressions; using YLErp.BLL; using YLErp.BLL.Eod; @@ -320,7 +321,7 @@ namespace YLErp.Modules.SwapModule var posiNotionalValue = stockEqvNotional * closePercent;//剩余名义本金 var grossPrice = realPostitions.Where(x => x.PosiDirection > 0).FirstOrDefault()?.PosiGrossPrice; bool tdClose = DbContext.swap_flow_event.Any(x => x.SwapTradeId == tradeId && x.UnwindDate == unwindDate && eventTypes.Contains(x.EventType) && x.DataState == (int)SwapFlowDateStateEnum.完成); - interests = GetInterests(td, tradeExtend, valueDate, unwindDate, lastEodPositions, positions, stockEqvNotional, posiLongNotionalValue, posiShortNotionalValue, posiNotionalValue, closePercent, eventType, tdClose, false, grossPrice ?? 0, orginPv, true, false, false); + interests = GetInterests(td, tradeExtend, valueDate, unwindDate, lastEodPositions, positions, stockEqvNotional, posiLongNotionalValue, posiShortNotionalValue, posiNotionalValue, closePercent, eventType, tdClose, false, grossPrice ?? 0, orginPv, true, false, false); return interests; } /// @@ -401,7 +402,7 @@ namespace YLErp.Modules.SwapModule } else if (position.InterestMode == (int)InterestModeEnum.标的期初全价) { - _closePosiNotionalValue = _posiNotionalValue * closePrecent; + _closePosiNotionalValue = _posiNotionalValue * closePrecent; _posiNotionalValue = _posiNotionalValue; } else if (position.InterestMode == (int)InterestModeEnum.追加预付金 || position.InterestMode == (int)InterestModeEnum.初始预付金) @@ -434,7 +435,7 @@ namespace YLErp.Modules.SwapModule position.FloatRate = Convert.ToDecimal(floatRate); positionClone.FloatRate = position.FloatRate; } - else if(!swap) + else if (!swap) { throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{rateDate:yyyy年MM月dd日}的价格"); } @@ -770,7 +771,7 @@ namespace YLErp.Modules.SwapModule DealFloatPosition(unwindData); var flowList = new List(unwindData.FlowEvents); var eventId = SaveSwapDeal(unwindData, (int)SwapEventTypeEnum.平仓, clientCashId, "系统操作_平仓"); - if (unwindData.CloseMethod == (int)CloseMethodEnum.全部平仓|| unwindData.ClosePercent==1) + if (unwindData.CloseMethod == (int)CloseMethodEnum.全部平仓 || unwindData.ClosePercent == 1) { td.TradeStatus = "已平仓"; td.trade_extend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == td.id); @@ -813,7 +814,7 @@ namespace YLErp.Modules.SwapModule /// /// /// - public void AuotoSwapUnwind(int tradeid, decimal unwindPrice, decimal unwindPriceFee, decimal unwindNetFee, decimal unwindNet, DateTime valueDate, decimal unwindQty,decimal closeFee) + public void AuotoSwapUnwind(int tradeid, decimal unwindPrice, decimal unwindPriceFee, decimal unwindNetFee, decimal unwindNet, DateTime valueDate, decimal unwindQty, decimal closeFee) { unwindPriceFee = decimal.Parse(unwindPriceFee.ToString("F10")); var td = DbContext.trade.Find(tradeid); @@ -851,7 +852,7 @@ namespace YLErp.Modules.SwapModule unwindData.CloseMethod = unwindQty == unwindData.PositionQty ? (int)CloseMethodEnum.全部平仓 : (int)CloseMethodEnum.部分平仓; unwindData.ClosePercent = unwindData.PositionQty == 0 ? 0 : unwindPercent; unwindData.CloseNotionalValue = position == null ? 0 : unwindQty * position.PosiGrossPrice * position.ContractSize; - unwindData.CloseNotionalValue = unwindPercent >= 1? unwindData.PosiNotionalValue: Math.Round(unwindData.CloseNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); + unwindData.CloseNotionalValue = unwindPercent >= 1 ? unwindData.PosiNotionalValue : Math.Round(unwindData.CloseNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); unwindData.CloseQty = unwindQty; if (position != null) { @@ -881,23 +882,14 @@ namespace YLErp.Modules.SwapModule floatEvent.TradingFeePending = position.PosiTradingFeePending * unwindData.ClosePercent; floatEvent.TradingFeePending = Math.Round(floatEvent.TradingFeePending, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); floatEvent.TradingFee = closeFee; - - BondPaymentService bondPaymentService = new BondPaymentService(UserInfo); - var tax = GetUnderlyingTax(floatEvent.UnderlyingCode); - // 只计算事件日期当天的分红收益 - var payments = bondPaymentService.GetTargetDatePayments(floatEvent.UnderlyingCode, floatEvent.EventDate); - floatEvent.DividendIn = bondPaymentService.CalcPayment(payments, unwindQty, longRatio, floatRatio) / (1 + tax) * (1 - tax); - floatEvent.DividendIn = Math.Round(floatEvent.DividendIn, 2, MidpointRounding.AwayFromZero); - floatEvent.DividendPending = bondPaymentService.CalcPayment(payments, floatEvent.PositionQty ?? 0, longRatio, floatRatio) / (1 + tax) * (1 - tax); - - floatEvent.MarkClosePnl = (unwindPrice - position.PosiGrossPrice) * unwindQty * floatRatio * longRatio; - floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + ((floatEvent.TradingFeePending+ closeFee) * floatRatio * -1) + floatEvent.DividendIn, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); + floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + ((floatEvent.TradingFeePending + closeFee) * floatRatio * -1) + floatEvent.DividendIn, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); floatEvent.TradingAmount = unwindPrice * floatEvent.Quantity * floatEvent.ContractSize; floatEvent.TradingAmount = Math.Round(floatEvent.TradingAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); floatEvent.OptLog = "流水自动"; floatEvent.ClientId = td.ClientId; floatEvent.SetOpt(UserInfo); + EnrichDividendIn(floatEvent, unwindQty); } unwindData.FlowEvents.Add(floatEvent); var interestPositions = GetUnwindInterests(unwindData.ValueDate, unwindData.UnwindDate.Value, td.id, unwindPercent, (int)SwapEventTypeEnum.平仓); @@ -907,8 +899,8 @@ namespace YLErp.Modules.SwapModule }); foreach (var item in interestPositions) { - item.TdInterestAmount=Math.Round(item.TdInterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); - item.InterestAmount=Math.Round(item.InterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); + item.TdInterestAmount = Math.Round(item.TdInterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); + item.InterestAmount = Math.Round(item.InterestAmount, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); item.InterestClosePnL = Math.Round(item.InterestClosePnL, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); } unwindData.FlowEvents.AddRange(interestPositions); @@ -916,6 +908,15 @@ namespace YLErp.Modules.SwapModule DealUnwind(unwindData, td); } + private void EnrichDividendIn(swap_flow_event flowEvent, decimal unwindQty) + { + // 平仓数量/平仓前的数量*平仓对象的待实现分红收益,保留2位小数 + var yest = QdpCalendarHelper.GetNonHolidayDefore(flowEvent.EventDate.AddDays(-1)); + var eod = DbContext.eod_swap_position.Where(e => e.SwapTradeId == flowEvent.SwapTradeId && !e.Invalid && e.PosiQuantity > 0 && e.ValueDate == yest).FirstOrDefault(); + var dividendIn = eod.PosiProfitSum * unwindQty / eod.PosiQuantity; + flowEvent.DividendIn = Math.Round(dividendIn, 2, MidpointRounding.AwayFromZero); + } + public decimal GetUnderlyingTax(string code) { var data = DataCacheProvider.GetUnderlyingDataSource().GetData(code); @@ -1073,7 +1074,7 @@ namespace YLErp.Modules.SwapModule return interests; } - private void DealUnwind(UnwindData unwindData, trade td, string actionMsg = "系统操作_自动平仓") + private void DealUnwind(UnwindData unwindData, trade td, string actionMsg = "系统操作_自动平仓") { int clientCashId = AddClientCashInCashOut(td, Convert.ToDouble(-unwindData.SwapRealizedPnL), ClientCashInCashOut.系统操作_平仓费, unwindData.ValueDate); if (unwindData.SwapMarginAmount != 0) @@ -1104,7 +1105,7 @@ namespace YLErp.Modules.SwapModule td.TradeAmount -= Convert.ToDouble(unwindData.CloseQty); td.Notional = td.TradeAmount; td.OptDate = DateTime.Now; - td.OptId= UserId; + td.OptId = UserId; td.OptName = UserName; DbContext.SaveChanges(); } @@ -1384,7 +1385,7 @@ namespace YLErp.Modules.SwapModule decimal shortRatio = item.PositionType == (int)PositionTypeFlag.Long ? -1m : 1m; item.TradingAmountFeeAvg = item.TradingAmountAvg + item.TradingFeePending / unwindData.CloseQty * shortRatio; item.TradingAmountNetFeeAvg = item.TradingAmountNetAvg + item.TradingFeePending / unwindData.CloseQty * shortRatio; - item.TradingAmount= item.TradingAmountAvg * unwindData.CloseQty; + item.TradingAmount = item.TradingAmountAvg * unwindData.CloseQty; } } } @@ -1400,7 +1401,7 @@ namespace YLErp.Modules.SwapModule if (!string.IsNullOrEmpty(position.UnderlyingCode)) { position.PosiQuantity -= unwindData.CloseQty; - position.PosiNotionalValue = unwindData.PosiNotionalValue- unwindData.CloseNotionalValue; + position.PosiNotionalValue = unwindData.PosiNotionalValue - unwindData.CloseNotionalValue; position.PosiTradingFee -= position.PosiTradingFee * unwindData.ClosePercent; position.PosiTradingFeePending -= position.PosiTradingFeePending * unwindData.ClosePercent; }