using BaseOUDAL; using System.Linq.Expressions; using YLErp.QdpModule; namespace YLErp.Modules.TradeModule.QueryModule { public class TradeCreditRiskQueryService : YLBaseService { public TradeCreditRiskQueryService(OptUserInfo userInfo) : base(userInfo) { } public TradeCreditRiskQueryService(YLBaseService baseService) : base(baseService) { } /// /// 查询客户交易明细 /// public SearchListResult SearchTradeCreditRisk(TradeCreditRiskReq req) { BuildTradePredicate(req, out var tradPredicate); DateTime tradingday = QdpCalendarHelper.GetNonHolidayDefore(req.EndDate.Value); DateTime lastdate = req.EndDate.Value.AddDays(1 - req.EndDate.Value.Day).AddMonths(1).AddDays(-1); DateTime lastdatetrading = QdpCalendarHelper.GetNonHolidayDefore(lastdate); if (tradingday != lastdatetrading) { lastdatetrading = QdpCalendarHelper.GetNonHolidayDefore(lastdate.AddDays(1 - lastdate.Day).AddDays(-1)); } var query = from td in DbContext.trade.Where(tradPredicate) join et in DbContext.eod_trade.Where(O => O.ValueDate == req.EndDate.Value) on td.id equals et.TradeId into tempEt from et in tempEt.DefaultIfEmpty() join etp in DbContext.eod_trade_position.Where(O => O.ValueDate == lastdate) on td.id equals etp.TradeId into tempEtp from etp in tempEtp.DefaultIfEmpty() where et != null select new TradeCreditRisk { id = td.id, TradeNumber = td.TradeNumber, tradecode = "", ClientId = td.ClientId, BuySell = td.BuySell, OptionType = td.OptionType, StructureType = td.StructureType, TradeType = td.TradeType, TradeDate = td.TradeDate, ExerciseDate = td.ExerciseDate, SettlementDate = td.SettlementDate, PremiumPayDate = td.PremiumPayDate, Strike = td.Strike, UnderlyingCode = td.UnderlyingCode, BasisUnderlyingCode = td.BasisUnderlyingCode, StockEqvNotional = td.StockEqvNotional, StockEqvNotionalMax = td.StockEqvNotionalMax, OriginalStockEqvNotional = td.OriginalStockEqvNotional, TradePrice = td.TradePrice, InitialMargin = td.TradePrice, Notional = td.Notional, tradevalue = etp == null ? 0 : etp.Pv, et = et, }; if (string.IsNullOrWhiteSpace(req.sidx)) { req.sidx = "id"; req.sord = "desc"; } var list = query.ToSearchList(req); var clients = DataCacheProvider.GetClientDataSource().AsQueryable(); var underly = DataCacheProvider.GetUnderlyingDataSource().AsQueryable(); var varietys = DataCacheProvider.GetVarietyDataSource().AsQueryable(); var markets = DataCacheProvider.GetMarketDataSource().AsQueryable(); foreach (var item in list.rows) { if (item.et != null) { item.Strike = item.et.trade.Strike; item.UnderlyingCode = item.et.trade.UnderlyingCode; item.BasisUnderlyingCode = item.et.trade.BasisUnderlyingCode; item.StockEqvNotional = item.et.trade.StockEqvNotional; item.StockEqvNotionalMax = item.et.trade.StockEqvNotionalMax; item.OriginalStockEqvNotional = item.et.trade.OriginalStockEqvNotional; item.TradePrice = item.et.trade.TradePrice; item.InitialMargin = item.et.trade.InitialMargin; item.Notional = item.et.trade.Notional; } var client = clients.FirstOrDefault(x => x.id == item.ClientId); item.ClientName = client.Name; item.ClientNumber = client.Number; item.MainProtocolCode = client.MainProtocolCode; item.LicenseType = client.LicenseType; item.LicenseCode = client.LicenseCode; item.buysell_show = item.BuySell == "买入" ? "B" : "S"; item.CallorPut = item.OptionType == "看涨" ? "Call" : "Put"; item.multishort = item.OptionType == "看涨" ? "多头" : "空头"; item.tradetype_show = item.StructureType ?? item.TradeType; var un = underly.FirstOrDefault(x => x.UnderlyingCode == item.UnderlyingCode); var va = un == null ? null : varietys.FirstOrDefault(x => x.id == un.UnderlyingTypeId); var ma = un == null ? null : markets.FirstOrDefault(x => x.ExchangeNo == un.MarketCode); item.UnderlyingAssetName = un?.UnderlyingName; item.QuoteCurrency = va?.QuoteCurrency ?? "CNY"; item.UnderlyingAssetName = un?.UnderlyingName; item.MarketName = ma?.MarketName; if (item.et != null) { var eodpostion = DbContext.eod_trade_position.FirstOrDefault(O => O.ValueDate == req.EndDate && O.TradeId == item.et.TradeId); item.pv = eodpostion?.Pv; item.valuedate = eodpostion?.ValueDate; } if (item.TradeType == "远期") { var lasteodpostion = DbContext.eod_trade_position.FirstOrDefault(O => O.ValueDate == lastdatetrading && O.TradeId == item.et.TradeId); item.tradevalue = lasteodpostion?.Pv; item.producttype = string.IsNullOrWhiteSpace(item.BasisUnderlyingCode) ? "商品远期" : "商品互换"; } else if (item.TradeType == "收益互换") { var swap = DbContext.trade_swap.FirstOrDefault(O => O.TradeId == item.id && O.TradeId == item.et.TradeId); item.payfloattype = swap.IsPayFloatingProfit == true ? "2:支付浮动" : "1:支付固定"; item.producttype = "收益互换"; if (swap.IsPayFloatingProfit) { var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(swap.GetSwapTimeAndRate); if (customizedResults.Item1 == null) { item.SwapTime = null; } else { item.SwapTime = customizedResults.Item1[0]; } item.Strike = swap.PaySpotPrice + (swap.PayLongShort == "多头" ? 1 : -1) * ((swap.GetSingleFee ?? 0) / un.ContractSize + (swap.PaySpotPrice * swap.GetUnAnnualRate ?? 0)); } else { var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(swap.PaySwapTimeAndRate); if (customizedResults.Item1 == null) { item.SwapTime = null; } else { item.SwapTime = customizedResults.Item1[0]; } item.Strike = swap.GetSpotPrice + (swap.GetLongShort == "多头" ? 1 : -1) * ((swap.PaySingleFee ?? 0) / un.ContractSize + (swap.GetSpotPrice * swap.PayUnAnnualRate ?? 0)); } } else { item.producttype = un == null ? "商品期货" : un.IsCommoditySpot() ? "商品现货" : "商品期货"; if(item.et != null && item.et.trade.IsGroup ==1) { if (double.TryParse(item.et.trade.Propertys?.Where(x => x.name == "行权价格").FirstOrDefault()?.value ?? "", out double strike)) { item.Strike = strike; } if (DateTime.TryParse(item.et.trade.Propertys?.Where(x => x.name == "期权费支付日").FirstOrDefault()?.value ?? "", out DateTime premiumPayDate)) { item.PremiumPayDate = premiumPayDate; } else { item.PremiumPayDate = item.TradeDate; } var callorPut = item.et.trade.Propertys?.Where(x => x.name == "期权方向").FirstOrDefault()?.value ?? ""; item.CallorPut = callorPut == "看涨" ? "Call" : "Put"; item.multishort = callorPut == "看涨" ? "多头" : "空头"; var subid = DbContext.trade.Where(x => x.ParentTradeId == item.et.TradeId && x.ValidState != "InValid" && x.IsGroup == 2).Select(x => x.id).ToArray(); var subpv = DbContext.eod_trade_position.Where(O => O.ValueDate == req.EndDate && subid.Contains(O.TradeId)).Sum(x => x.Pv); item.pv = subpv; item.valuedate = req.EndDate; } } } return list; } private void BuildTradePredicate(TradeCreditRiskReq req, out Expression> tradPredicate) { //交易明细页面:组合互换 提前终止和到期都按照子交易展示 if (req.CreditRiskType == "期权") { tradPredicate = PredicateBuilder.True().And(x => x.TradeType != "远期" && x.TradeType != "收益互换"); } //交易明细页面:组合互换 成交按照主交易可展开形式展示 else if (req.CreditRiskType == "远期") { tradPredicate = PredicateBuilder.True().And(x => x.TradeType == "远期"); } //交易明细导出:组合互换都按照子交易展示 else if (req.CreditRiskType == "互换") { tradPredicate = PredicateBuilder.True().And(x => x.TradeType == "收益互换"); } else { tradPredicate = PredicateBuilder.True(); } var endDate = req.EndDate.Value; tradPredicate = tradPredicate.And(t => t.TradeDate <= endDate && t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2); if (req.StartDate != null) { tradPredicate = tradPredicate.And(t => t.TradeDate >= req.StartDate); } if (!string.IsNullOrWhiteSpace(req.ClientIds)) { if (req.ClientIds.Substring(0, 1) != ",") { tradPredicate = tradPredicate.And(t => req.ClientIdsInt.Contains(t.ClientId)); } } } } /// /// 交易查熏 /// public class TradeCreditRiskReq : BaseSearchReq { /// /// 客户ID列表 /// public string ClientIds { get; set; } public List ClientIdsInt { get { if (string.IsNullOrEmpty(ClientIds)) { return new List(); } return (ClientIds + "").Split(',').Select(c => Convert.ToInt32(c)).ToList(); } } /// /// 开始日期 /// public DateTime? StartDate { get; set; } /// /// 结束日期 /// public DateTime? EndDate { get; set; } /// /// 类型 /// public string CreditRiskType { get; set; } } public class TradeCreditRisk : OtcTradeDto { /// /// client /// public string MainProtocolCode { get; set; } public string ClientNumber { get; set; } public string LicenseType { get; set; } public string LicenseCode { get; set; } /// /// trade /// public string buysell_show { get; set; } public string CallorPut { get; set; } public string multishort { get; set; } public string tradetype_show { get; set; } public string accountCode { get { return "HAZB0001"; } } public string accountName { get { return "华安资本账户0001"; } } //public string financeCode = "自定义"; //public string financeName = "标的合约代码"; public string producttype { get; set; } /// /// SPT_CMDT(商品现货)、FUT_CMDT(商品期货)、SWP_S(收益互换)、SWP_CMDT(商品互换)、FWD_FUT_CMDT(商品远期)、OPT_FUT_CMDT(场内期权) /// public string assetstype { get { if (producttype == "商品现货") { return "SPT_CMDT"; } else if (producttype == "商品期货") { return "FUT_CMDT"; } else if (producttype == "收益互换") { return "SWP_S"; } else if (producttype == "商品互换") { return "SWP_CMDT"; } else if (producttype == "商品远期") { return "FWD_FUT_CMDT"; } else if (producttype == "商品远期") { return "OPT_FUT_CMDT"; } else { return ""; } } } public string MarketName { get; set; } /// /// 商品现货:大连商品交易所(XDCE),上海期货交易所(XSGE),郑州商品交易所(XZCE) 金交所(SGEX) /// 商品远期:NONE、收益互换:NONE、场外期权:NONE /// 商品期货:深交所(XSHE),上交所(XSHG) /// public string markettype { get { if (producttype == "商品现货") { if (MarketName == "大连商品交易所") { return "XDCE"; } else if (MarketName == "上海期货交易所") { return "XSGE"; } else if (MarketName == "郑州商品交易所") { return "XZCE"; } else if (MarketName == "金融资产交易所") { return "SGEX"; } } else if (producttype == "商品期货") { if (MarketName == "上海证券交易所") { return "XSHE"; } else if (MarketName == "深圳证券交易所") { return "XSHG"; } } return "NONE"; } } /// /// 远期 /// public double? pv { get; set; } public double? pnl { get; set; } public DateTime? valuedate { get; set; } /// /// 互换 /// public string payfloattype { get; set; } public DateTime? SwapTime { get; set; } public string tradecode { get; set; } public double? tradevalue { get; set; } public eod_trade et { get; set; } /// /// 抵押品 /// public string productCode { get; set; } public string productName { get; set; } public string productMaketName { get; set; } public string productMaketType { get; set; } } }