using System.Text; using YLErp.Modules.CalculationModule; using YLErp.Modules.DataProviderModule; using YLErp.QdpModule; namespace YLErp.Modules.SystemModule.SysToolModule.HeiXiang { /// /// 黑箱dailypnl验证 /// public class HeixiangDailyPnlService : YLBaseService { public HeixiangDailyPnlService(OptUserInfo userInfo) : base(userInfo) { } /// /// 获取黑箱dailypnl验证数据 /// /// public IEnumerable GetList(HeixiangDailyPnlRequest request) { if (string.IsNullOrWhiteSpace(request.HxMainTradeNumber)) { throw new ServiceException("黑箱主交易编号不能为空"); } var db = DbContextFactory.GetYLDbContext(); var preDate = QdpCalendarHelper.GetNonHolidayDefore(request.SettleDate.AddDays(-1)); var mainTrade = db.trade.Where(n => n.TradeNumber == request.HxMainTradeNumber) .Select(n => new { n.id }).FirstOrDefault(); if (mainTrade == null) { throw new ServiceException("黑箱主交易 数据不存在"); } IQueryable posQry = db.eod_trade_position; if (string.IsNullOrEmpty(request.VolType) || request.VolType == "对冲") { posQry = db.eod_trade_position_hedgevol; } var query = from t in posQry join td in db.trade on t.TradeId equals td.id join pt in db.eod_trade_position.Where(n => n.ValueDate == preDate) on t.TradeId equals pt.TradeId into pt_s from pt in pt_s.DefaultIfEmpty() where t.ValueDate == request.SettleDate && t.ParentTradeId == mainTrade.id select new { td.TradeNumber, td.OriginalNotional, td.TradePrice, td.BuySell, td.OriginalPrincipalSum, t.TradeId, t.Amount, t.Pv, t.LastPv, t.ClosedPnL, t.DailyPnL, pre = pt == null ? null : new { pt.Pv, pt.Amount } }; var datas = query.ToArray(); var subTradeIds = datas.Select(n => n.TradeId).ToArray(); var tcProvider = new TradeCashDataProvider(); tcProvider.Initialize(subTradeIds); var list = new List(datas.Length + 1); var sb = new StringBuilder(); double sumDailyPnl = 0d, sumDailyPnlCalc = 0d; foreach (var item in datas) { var result = new HeixiangDailyPnlResult { TradeNumber = item.TradeNumber }; if (item.Amount < 1e-4) { result.TradeStatus = "完全了结"; } else { var diff = Math.Abs((item.OriginalNotional ?? 0) - item.Amount); if (diff < 1e-4) { result.TradeStatus = "全部成交"; } else { result.TradeStatus = "部分了结"; } } double lastPv; if (item.pre != null) { result.PrePositionPv = item.pre.Pv.OtcFormatFlex(2, 4); result.PrePositionNotional = item.pre.Amount.OtcFormatFlex(2, 4); lastPv = item.LastPv; } else { if (PS.Config.ErpElement.IsPVIncludePrincipal) { lastPv = item.TradePrice ?? 0; } else { lastPv = (item.TradePrice ?? 0) - (item.OriginalPrincipalSum ?? 0); } if (item.BuySell == "卖出") { lastPv = -lastPv; } } result.PositionPv = item.Pv.OtcFormatFlex(2, 4); result.PositionNotional = item.Amount.OtcFormatFlex(2, 4); result.PositionDailyPnl = item.DailyPnL.OtcFormatFlex(2, 4); sb.Clear(); sb.AppendFormat("pv({0}) - lastpv({1}) + 了结盈亏(", item.Pv.OtcFormatFlex(2, 4), lastPv.OtcFormatFlex(2, 4)); var dailyCalc = item.Pv - lastPv; foreach (var c in tcProvider.GetTradeCashes(item.TradeId)) { if (c.Action == ClientCashInCashOut.系统操作_期权费) { continue; } var unWindProfit = c.Amount; if (!PS.Config.ErpElement.IsPVIncludePrincipal) { if (c.Action == ClientCashInCashOut.系统操作_行权费 || c.Action == ClientCashInCashOut.系统操作_平仓费 || c.IsLastAction) { unWindProfit -= (c.UnwindPercentRate ?? 0) * item.OriginalPrincipalSum.Value * TradeCalcHelper.GetSign(item.BuySell); } } sb.Append(unWindProfit.OtcFormatFlex(2, 4)).Append(" + "); dailyCalc += unWindProfit; } if (sb[sb.Length - 2] == '+') { sb[sb.Length - 2] = ')'; } else { sb.Append(") "); } sb.Append(" = ").Append(dailyCalc.OtcFormatFlex(2, 4)); result.DailyPnlCalc = sb.ToString(); sumDailyPnl += item.DailyPnL; sumDailyPnlCalc += dailyCalc; list.Add(result); } var sumData = new HeixiangDailyPnlResult { TradeNumber = "合计:", PositionDailyPnl = sumDailyPnl.OtcFormatFlex(2, 4), DailyPnlCalc = sumDailyPnlCalc.OtcFormatFlex(2, 4) }; list.Add(sumData); return list; } } }