using Qdp.ComputeService.Data.CommonModels.MarketInfos; using Qdp.ComputeService.Data.CommonModels.MarketInfos.CurveDefinitions; using Qdp.Foundation.Implementations; using Qdp.Pricing.Base.Enums; using Qdp.Pricing.Base.Implementations; using Qdp.Pricing.Base.Interfaces; using Qdp.Pricing.Base.Utilities; using Qdp.Pricing.Ecosystem.Market; using Qdp.Pricing.Ecosystem.Utilities; using Qdp.Pricing.Library.Common.Market; using YLErp.Abstract; using YLErp.Commons; namespace YLErp.QdpModule { /// /// 非线程安全类 /// public class MarketProxy : IDisposable { public const string ConstantZeroCurve = "ConstantZeroCurve"; public const string RiskFreeDiscountCurve = "RiskFreeDiscountCurve"; public MarketProxy(DateTime valueDate, double sysRiskFreeRate, string curveDayCount = null) { ValueDate = valueDate; RiskFreeRate = sysRiskFreeRate; QdpMarket = new PrebuiltQdpMarket(valueDate.ToString("yyyy-MM-dd"), valueDate); SetYieldCurve(ConstantZeroCurve, QdpHelper.CreateRiskFreeCurve(ConstantZeroCurve, 0)); CurveDayCount = curveDayCount; if (string.IsNullOrEmpty(CurveDayCount)) { CurveDayCount = BLL.valuedateBLL.SystemDate.CurveDayCount; } SetYieldCurve(RiskFreeDiscountCurve, QdpHelper.CreateRiskFreeCurve(DiscountCurveName, RiskFreeRate, CurveDayCount)); } #region----属性定义---- /// /// 计算日期 /// public DateTime ValueDate { get; private set; } /// /// QDP Market对象 /// public PrebuiltQdpMarket QdpMarket { get; } /// /// 无风险利率 /// public double RiskFreeRate { get; } /// /// 无风险利率曲线名称 /// public string DiscountCurveName => RiskFreeDiscountCurve; /// /// 用于计算跟踪输出 /// public TraceWrap Trace { get; set; } /// /// 曲面日历 /// public string CurveDayCount { get; } #endregion #region----利率曲线/标的物价格/波动率/相关性---- /// /// 添加利率曲线 /// public void SetYieldCurve(string curveName, InstrumentCurveDefinition curveDefinition) { YieldCurve instrumentCurve = null; if (curveDefinition.RateDefinitions.All(x => x.InstrumentType.ToInstrumentType() == InstrumentType.Dummy || x.InstrumentType.ToInstrumentType() == InstrumentType.None)) { if (curveDefinition.RateDefinitions.All(x => x.IsTerm())) { instrumentCurve = new YieldCurve( curveDefinition.Name, ValueDate, curveDefinition.RateDefinitions.Select(x => Tuple.Create((ITerm)new Term(x.Tenor), x.Rate)).ToArray(), curveDefinition.CurveConvention.BusinessDayConvention.ToBda(), curveDefinition.CurveConvention.DayCount.ToDayCountImpl(), curveDefinition.CurveConvention.Calendar.ToCalendarImpl(), curveDefinition.CurveConvention.Currency.ToCurrencyCode(), curveDefinition.CurveConvention.Compound.ToCompound(), curveDefinition.CurveConvention.Interpolation.ToInterpolation(), curveDefinition.Trait.ToYieldCurveTrait() ); } else { instrumentCurve = new YieldCurve( curveDefinition.Name, ValueDate, curveDefinition.RateDefinitions.Select(x => Tuple.Create(new Date(DateTime.Parse(x.Tenor)), x.Rate)).ToArray(), curveDefinition.CurveConvention.BusinessDayConvention.ToBda(), curveDefinition.CurveConvention.DayCount.ToDayCountImpl(), curveDefinition.CurveConvention.Calendar.ToCalendarImpl(), curveDefinition.CurveConvention.Currency.ToCurrencyCode(), curveDefinition.CurveConvention.Compound.ToCompound(), curveDefinition.CurveConvention.Interpolation.ToInterpolation(), curveDefinition.Trait.ToYieldCurveTrait() ); } } QdpMarket.YieldCurves[curveName] = instrumentCurve; } /// /// 添加股票价格 /// public void SetStockPrice(string ticker, double price) { QdpMarket.StockPrices[ticker] = price; } /// /// 移除波动率曲面 /// public bool RemoveYieldCurve(string curveName) { if (string.IsNullOrEmpty(curveName)) { return false; } return QdpMarket.YieldCurves.Remove(curveName); } /// /// 设置波动率 /// public void SetVolSurface(string volSurfaceName, double consVol) { var volatility = QdpModule.QdpVolHelper.GenerateFlatSurface(consVol); SetVolSurface(volSurfaceName, volatility); } /// /// 设置波动率 /// public void SetVolSurface(string volSurfaceName, IVolatility volatility, double addVolRate = 0, bool isAddVolPercent = true) { if (string.IsNullOrWhiteSpace(volSurfaceName)) { throw new ArgumentNullException(nameof(volSurfaceName)); } if (volatility is null) { throw new ArgumentNullException(nameof(volatility)); } if (volatility.VolTable is null) { throw new ArgumentException("VolTable不能为null", nameof(volatility)); } Trace?.WriteData(volatility, "波动率名称:" + volSurfaceName); var wrap = new VolSurfaceBuilder { volSurfaceName = volSurfaceName, volSurfaceType = volatility.VolSurfaceMode, interpolation = volatility.InterpolationMethod }.SetVectors(volatility.VolTable, addVolRate, isAddVolPercent).Build(ValueDate); QdpMarket.VolSurfaces[wrap.VolSurfaceName] = wrap.VolSurface; } /// /// 设置相关性 /// public void SetCorrelation(string[] underlyingTickers, double correlation) { var corrName = underlyingTickers.Length > 1 ? (underlyingTickers[0] + "_" + underlyingTickers[1]) : underlyingTickers[0]; var corrSurface = new CorrSurfMktData(corrName, correlation); QdpMarket.CorrSurfaces[corrName] = corrSurface.ToImpliedVolSurface(ValueDate); } #endregion #region----请求自增ID---- int _requestId = 1; /// /// 获取下一个请求ID /// public int NextRequestId() { return _requestId++; } #endregion #region----释放资源--- bool isDisposed; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (isDisposed) { return; } if (disposing) { QdpMarket.Dispose(); } isDisposed = true; } #endregion public override string ToString() { return QdpMarket.MarketName; } } }