using BaseOUDAL; using YLErp.Model; using YLErp.Modules.VolatilityModule; using YLErp.Modules.VolatilityModule.SkewMapVolModule; using YLErp.QdpModule; using YLErp.QdpModule.Constants; namespace YLErp.BLL { public class underlying_main_contract_historyBLL { public static readonly List ShowExpires; public static readonly List 有色金属ShowExpires; static underlying_main_contract_historyBLL() { if (!PS.Config.ErpElement.SkewMapVolConstruction) { ShowExpires = new List { "2W", "1M", "3M" }; 有色金属ShowExpires = new List { "2W", "1M", "2M" }; } else { ShowExpires = new List { "1M", "3M", "6M" }; 有色金属ShowExpires = new List { "1M", "3M", "6M" }; } } public static List GetVolatilityQuotation(int userId, IEnumerable quotationList, string userGroup = null) { var VQ = new List(); if (string.IsNullOrEmpty(userGroup)) { userGroup = UserBLL.GetUserGroup(userId); } var vollist = new VolatilityQueryService(OptUserInfo.SystemUser) .GetVolatilities(new BatchVolatilityRequest { QuotationDate = valuedateBLL.ValueDate, VolTypes = ConsVolInfos.subTradeVolType, UnderlyingCodes = quotationList.Select(O => O.UnderlyingCode).ToArray(), UserGroup = userGroup, TradeVolWithBidAsk = false }, true); var exDate = QdpCalendarHelper.GetNonHoliday(valuedateBLL.ValueDate.AddMonths(1).AddDays(-1)); var exerciseDate = exDate; var quotationUnderlyinglist = underlying_main_contractBLL.GetDefaultAtMoneyQuoteList(exDate); quotationList = quotationList.Where(q => quotationUnderlyinglist.Any(u => string.Equals(u.UnderlyingCode, q.UnderlyingCode, StringComparison.OrdinalIgnoreCase))).OrderBy(o => o.order).ToList(); var activeAsset = underlying_main_contractBLL.GetAllunderlying_main_contractModel().Where(x => x.NeedQuote == 1); foreach (var qu in quotationList) { var singleVQ = new VolatilityQuotation() { MarketName = qu.MarketName, UnderlyingMainCode = qu.UnderlyingCode, UnderlyingType = qu.UnderlyingType }; var underlying = quotationUnderlyinglist.FirstOrDefault(u => string.Equals(u.UnderlyingCode, qu.UnderlyingCode, StringComparison.OrdinalIgnoreCase)); singleVQ.CommodityCode = underlying.CommodityCode; var checkExpires = ShowExpires; if (underlying_managerBLL.IsYouSeJinShu(qu.UnderlyingCode)) { checkExpires = 有色金属ShowExpires; } var contractUnder = activeAsset.FirstOrDefault(q => q.UnderlyingType == qu.UnderlyingType); //var tt = activeAsset.Where(v => v.UnderlyingCode == qu.UnderlyingCode).ToList(); //var ttt = quotationUnderlyinglist.Where(q => q.UnderlyingType == "棕榈油").ToList(); var contractVol = new List(); if (contractUnder != null && vollist != null) { contractVol = vollist.Where(v => contractUnder.UnderlyingCodeList.Contains(v.ContractCode)).ToList(); } volatility askVolTable = null; volatility bidVolTable = null; if (PS.Config.ErpElement.SkewMapVolConstruction) { var req = new SkewVolRequest { VolType = null, valueDate = valuedateBLL.ValueDate, Strike = qu.SpotPrice ?? 0, UnderlyingCode = underlying.UnderlyingCode }; req.VolType = "报价Ask"; askVolTable = SkewVolQueryService.GetVol(userId, req); req.VolType = "报价Bid"; bidVolTable = SkewVolQueryService.GetVol(userId, req); } else { askVolTable = SetVolQuotationTable(contractVol, qu, "报价Ask", checkExpires); bidVolTable = SetVolQuotationTable(contractVol, qu, "报价Bid", checkExpires); } var volReq = new InterpolatedVolReq() { strike = qu.SpotPrice ?? 0, isMoneynessOption = false, exerciseDate = exerciseDate, valueDate = valuedateBLL.ValueDate, spot = qu.SpotPrice ?? 0, volSurfaceType = askVolTable.VolSurfaceMode }; var askeGroup = new List(); if (askVolTable.VolTable != null) { askeGroup = askVolTable.VolTable.GroupBy(v => v.Expire).Select(v => new ExpireGroup { Expire = v.Key, Sv = v.ToList() }).ToList(); } var bideGroup = new List(); if (bidVolTable.VolTable != null) { bideGroup = bidVolTable.VolTable.GroupBy(v => v.Expire).Select(v => new ExpireGroup { Expire = v.Key, Sv = v.ToList() }).ToList(); } var BidAskMatureData = new List(); foreach (var expire in checkExpires) { var askvol = double.NaN; var bidvol = double.NaN; var askGroup = askeGroup.FirstOrDefault(a => a.Expire == expire); var bidgroup = bideGroup.FirstOrDefault(b => b.Expire == expire); if (askGroup != null) { askvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(askGroup.Sv, volReq, askVolTable.InterpolationMethod); } else if (!PS.Config.ErpElement.SkewMapVolConstruction) { askvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(askVolTable.VolTable, volReq, askVolTable.InterpolationMethod); } if (bidgroup != null) { bidvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(bidgroup.Sv, volReq, bidVolTable.InterpolationMethod); } else if (!PS.Config.ErpElement.SkewMapVolConstruction) { bidvol = QdpVolHelper.GetInterpolatedVolFromNormalSurface(bidVolTable.VolTable, volReq, bidVolTable.InterpolationMethod); } var md = new BidAskMatureData() { Expire = expire, AskVol = askvol, BidVol = bidvol }; BidAskMatureData.Add(md); } singleVQ.BidAskMatureData = BidAskMatureData; VQ.Add(singleVQ); } return VQ; } public static volatility SetVolQuotationTable(List vollist, flat_price_quotation qu, string voltype, List ShowExpires) { var askVolTable = vollist.FirstOrDefault(v => v.ContractCode == qu.UnderlyingCode && v.VolType == voltype); if (askVolTable == null) { askVolTable = vollist.FirstOrDefault(v => v.ContractCode.Contains(underlying_managerBLL.GetCommodityCodeByUnCode(qu.UnderlyingCode)) && v.VolType == voltype); if (askVolTable == null) { askVolTable = new volatility { VolType = voltype, VolSurfaceMode = "MoneynessVol" }; return askVolTable; } } if (string.IsNullOrEmpty(askVolTable.VolSurfaceMode)) { askVolTable.VolSurfaceMode = "MoneynessVol"; } //需要检查 ShowExpires 里不存在的 foreach (var expire in ShowExpires) { if (!askVolTable.VolTable.Any(v => v.Expire == expire)) { //不存在则要查找 todo 这边应该找主力合约的波动率 var volTable = vollist.FirstOrDefault(v => v.VolTable.Any(vt => vt.Expire == expire) && v.VolType == voltype); if (volTable != null && volTable.VolTable != null) { var vtInner = volTable.VolTable.Where(vt => vt.Expire == expire).ToList(); if (vtInner != null) { var vt = askVolTable.VolTable; vt.AddRange(vtInner); askVolTable.Data = vt.ToJson(); } } } } return askVolTable; } } }