using Dapper; using Org.BouncyCastle.Asn1.Mozilla; using Org.BouncyCastle.Ocsp; using Qdp.Foundation.Implementations; using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; using YLErp.Abstract.DataProviders; using YLErp.DBModels; using YLErp.Model; using YLErp.Modules.CalculationModule; using YLErp.Modules.DataProviderModule; using YLErp.Modules.MarketRiskMoudule.Dto; namespace YLErp.Modules.EodModule { /// /// 国联民生 希腊字母计算 /// public class GLMSGreeksHandleService { private readonly List calcInstrumentTypes = new List() { ConsGlobal.InstrumentType.TBonds, ConsGlobal.InstrumentType.CreditBonds, ConsGlobal.InstrumentType.OtherBonds, ConsGlobal.InstrumentType.RateYield,ConsGlobal.InstrumentType.BondIndex,ConsGlobal.InstrumentType.TBFutures }; private readonly List instrumentBondsTypes = new List() { ConsGlobal.InstrumentType.TBonds, ConsGlobal.InstrumentType.CreditBonds, ConsGlobal.InstrumentType.OtherBonds }; Dictionary _pDic = new Dictionary(); Dictionary _dDic = new Dictionary(); Dictionary _cDic = new Dictionary(); Dictionary _ytmDic = new Dictionary(); //期货对应的债券代码 Dictionary _TFeaturesBondCodeDic = new Dictionary(); public void InitData(DateTime valueDate,List underlyingCodes) { var umDatas = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().Where(p => underlyingCodes.Contains(p.UnderlyingCode) && calcInstrumentTypes.Contains(p.UnderlyingInstrumentType)).ToList(); if (umDatas == null || umDatas.Count == 0) { return; } var eodPriceProvier = new EodPriceProvider(valueDate); eodPriceProvier.Initialize(underlyingCodes); underlyingCodes.ForEach(e => { _pDic.Add(e, eodPriceProvier.GetPrice(e, SettlementTypeEnum.ClosePrice)); }); using var db = DbContextFactory.GetYLDbContext(); var conn = db.Database.GetDbConnection(); var bondsUmCodes = umDatas.Where(p => instrumentBondsTypes.Contains(p.UnderlyingInstrumentType)).Select(p => p.UnderlyingCode).Distinct().ToList(); if (bondsUmCodes != null && bondsUmCodes.Count > 0) { var datas = db.china_bond_valuation.AsNoTracking().Where(p => p.valuation_date == valueDate && bondsUmCodes.Contains(p.bond_id)).Select(p => new { p.bond_id, p.modi_dura, p.convexity, p.yield }).ToList(); if (datas != null && datas.Count > 0) { foreach (var item in datas) { _dDic.Add(item.bond_id, item.modi_dura != null ? (double)item.modi_dura : null); _cDic.Add(item.bond_id, item.convexity != null ? (double)item.convexity : null); _ytmDic.Add(item.bond_id, item.yield != null ? (double)item.yield : null); } } } var bondIndexUmInnerCodes = umDatas.Where(p => ConsGlobal.InstrumentType.BondIndex.Equals(p.UnderlyingInstrumentType)).Select(p => p.InnerCode??0).Distinct().ToList(); if (bondIndexUmInnerCodes != null && bondIndexUmInnerCodes.Count > 0) { var querySql = "SELECT InnerCode,Duration1,Convexity1,YTM FROM bond_chinabondindexquote WHERE TradingDay = @ValueDate AND InnerCode IN @InnerCodes"; var bondIndexQuoteDatas = conn.Query(querySql, new { ValueDate = valueDate, InnerCodes = bondIndexUmInnerCodes }, commandTimeout: 1800).ToList(); if (bondIndexQuoteDatas != null && bondIndexQuoteDatas.Count > 0) { foreach (var item in bondIndexQuoteDatas) { var umCode = umDatas.First(d => d.InnerCode == item.InnerCode).UnderlyingCode; _dDic.Add(umCode, item.Duration1 != null ? (double)item.Duration1 : null); _cDic.Add(umCode, item.Convexity1 != null ? (double)item.Convexity1 : null); _ytmDic.Add(umCode, item.YTM != null ? (double)item.YTM : null); } } } var bondFeatureUmCodes = umDatas.Where(p => ConsGlobal.InstrumentType.TBFutures.Equals(p.UnderlyingInstrumentType)).Select(p => p.UnderlyingCode).Distinct().ToList(); if (bondFeatureUmCodes != null && bondFeatureUmCodes.Count > 0) { var tFeatureBondInnerCodeDic = GetTFeatureBondInnerCode(bondFeatureUmCodes, valueDate, conn); if (tFeatureBondInnerCodeDic != null && tFeatureBondInnerCodeDic.Count > 0) { var contractInnerCodeBondInnerCodeDic = new Dictionary(); foreach (var item in tFeatureBondInnerCodeDic) { var bondUm = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().FirstOrDefault(p => p.InnerCode == item.Value); if (bondUm != null) { _TFeaturesBondCodeDic.Add(item.Key, bondUm.UnderlyingCode); } var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.Key); if (um.InnerCode != null) { contractInnerCodeBondInnerCodeDic.Add(um.InnerCode ?? 0, item.Value); } } if (tFeatureBondInnerCodeDic.Count > 0) { } } } } public void Handle(EodPositionRisksDTO dto,underlying_manager um) { var calcDto = new GreeksCalcDto { Delta = dto.Delta, Gamma = dto.Gamma, Vega = dto.Vega, }; handle(calcDto, um); dto.Delta_r = calcDto.Delta_r; dto.Gamma_r = calcDto.Gamma_r; dto.Vega_r = calcDto.Vega_r; dto.Delta_r_1bp = calcDto.Delta_r_1bp; dto.Dv01 = calcDto.Dv01; dto.Gamma_r_1bp = calcDto.Gamma_r_1bp; dto.Vega_r_1bp = calcDto.Vega_r_1bp; } public void Handle(trade td,TradeValueResult calRes, underlying_manager um) { var calcDto = new GreeksCalcDto { Delta = calRes.Delta, Gamma = calRes.Gamma, Vega = calRes.Vega, }; handle(calcDto, um); calRes.Delta_r = calcDto.Delta_r; calRes.Gamma_r = calcDto.Gamma_r; calRes.Vega_r = calcDto.Vega_r; calRes.Delta_r_1bp = calcDto.Delta_r_1bp; calRes.Dv01 = calcDto.Dv01; calRes.Gamma_r_1bp = calcDto.Gamma_r_1bp; calRes.Vega_r_1bp = calcDto.Vega_r_1bp; } private Dictionary GetTFeatureBondInnerCode(List underlyingCodes,DateTime valueDate,DbConnection conn) { var sql = "SELECT contractcode,deliverableinnercode,spread FROM fut_cgbderiv WHERE TradingDay = @ValueDate AND pricetype = 3 AND (contractcode,irr) IN (SELECT contractcode,MAX(irr) FROM fut_cgbderiv WHERE TradingDay = @ValueDate AND contractcode IN (@UmCodes) AND pricetype = 3 GROUP BY contractcode);"; var datas = conn.Query(sql, new { ValueDate = valueDate, UmCodes = underlyingCodes }, commandTimeout: 1800).ToList(); var res = new Dictionary(); if (datas != null && datas.Count > 0) { res = datas.GroupBy(p => p.contractcode).ToDictionary(p => p.Key, p => p.OrderBy(d => d.spread).First().deliverableinnercode); } return res; } private GLMSGreeksCalcArgs GetCalcArgs(string underlyingCode,string underlyingInstrumentType) { if (ConsGlobal.InstrumentType.RateYield.Equals(underlyingInstrumentType)) { return null; } return new GLMSGreeksCalcArgs { }; } private Dictionary GetCFDatas(Dictionary contractInnerCodeBondInnerCodeDic, DbConnection conn) { var sql = "SELECT infopubldate,contractinnercode,ibmarketinnercode,conversionfactors FROM fut_conversionfactors WHERE (contractinnercode,ibmarketinnercode) IN ((2059453,477500));"; return null; } private void handle(GreeksCalcDto dto, underlying_manager um) { if (!calcInstrumentTypes.Contains(um.UnderlyingInstrumentType)) { return; } var calcArgs = GetCalcArgs(um.UnderlyingCode, um.UnderlyingInstrumentType); if (ConsGlobal.InstrumentType.RateYield.Equals(um.UnderlyingInstrumentType)) { //利率收益率 dto.Delta_r = dto.Delta * -1; dto.Gamma_r = dto.Gamma; dto.Vega_r = dto.Vega; } else if (instrumentBondsTypes.Contains(um.UnderlyingInstrumentType)) { //利率债、信用债、其它债券 dto.Delta_r = dto.Delta * calcArgs.P * calcArgs.D; dto.Gamma_r = dto.Delta * calcArgs.P * calcArgs.C + (calcArgs.P * calcArgs.D) * (calcArgs.P * calcArgs.D) * dto.Gamma; dto.Vega_r = dto.Vega * calcArgs.D * calcArgs.Ytm; } else if (ConsGlobal.InstrumentType.BondIndex.Equals(um.UnderlyingInstrumentType)) { //债券指数 dto.Delta_r = dto.Delta * calcArgs.P * calcArgs.D; dto.Gamma_r = dto.Delta * calcArgs.P * calcArgs.C + (calcArgs.P * calcArgs.D) * (calcArgs.P * calcArgs.D) * dto.Gamma; dto.Vega_r = dto.Vega * calcArgs.D * calcArgs.Ytm; } else if (ConsGlobal.InstrumentType.TBFutures.Equals(um.UnderlyingInstrumentType)) { //国债期货 dto.Delta_r = dto.Delta * calcArgs.P * calcArgs.D / calcArgs.CF; dto.Gamma_r = dto.Delta * calcArgs.P * calcArgs.C / calcArgs.CF + (calcArgs.P * calcArgs.D / calcArgs.CF) * (calcArgs.P * calcArgs.D / calcArgs.CF) * dto.Gamma; dto.Vega_r = dto.Vega * calcArgs.D * calcArgs.Ytm; } dto.Delta_r_1bp = dto.Delta_r * 0.0001; dto.Dv01 = dto.Delta_r_1bp; dto.Gamma_r_1bp = dto.Gamma_r * 0.0001 * 0.0001; dto.Vega_r_1bp = dto.Vega_r * 0.0001; } } public class GLMSGreeksCalcArgs { //计算日的全价 public double? P { get; set; } public double? D { get; set; } public double? CF { get; set; } public double? C { get; set; } public double? Ytm { get; set; } } public class GreeksCalcDto { public double? Delta { get; set; } public double? Gamma { get; set; } public double? Vega { get; set; } /// /// Delta_R /// public double? Delta_r { get; set; } public double? Delta_r_1bp { get; set; } public double? Dv01 { get; set; } public double? Gamma_r { get; set; } public double? Gamma_r_1bp { get; set; } public double? Vega_r { get; set; } public double? Vega_r_1bp { get; set; } } public class ChinaBondIndexQuoteQueryDto { public long InnerCode { get; set; } public decimal? Duration1 { get; set; } public decimal? Convexity1 { get; set; } public decimal? YTM { get; set; } } public class TFeatureBondInnerCodeQueryDto { public string contractcode { get; set; } public long deliverableinnercode { get; set; } public decimal? spread { get; set; } } }