public BondSpreadWcfService(BondSpreadService bondSpreadService, BondSpreadServiceModel serviceModel, BondSpreadCalculator serviceCalculator, InterestCurves curves) { Log.Info("BondSpreadWcfService initialized!"); this.bondSpreadService = bondSpreadService; this.serviceModel = serviceModel; this.serviceCalculator = serviceCalculator; this.curves = curves; }
public void ShouldGiveCorrectBondLivePricesWithoutRicSubscription() { AutoResetEvent reset = new AutoResetEvent(false); DIContainer.RegisterSingletonType<FutureBuilder>(); Mock<IRepoAssumptions> mockRepo = new Mock<IRepoAssumptions>(); mockRepo.Setup(t => t.LoadDefaultRepo()); //DIContainer.GetInstance().RegisterType<ForwardBuilder>(new InjectionConstructor(mockRepo.Object)); DIContainer.RegisterSingletonType<BondSpreadServiceModel>(); DIContainer.RegisterSingletonType<BondSpreadCalculator>(); DIContainer.RegisterSingletonType<CurveBuilder>(); DIContainer.RegisterSingletonType<FutureBuilder>(); DIContainer.RegisterSingletonType<FutureEnrichment>(); var bondSpreadServiceModel = DIContainer.Resolve<BondSpreadServiceModel>(); var curveBuilder = DIContainer.Resolve<CurveBuilder>(); var futureBuilder = DIContainer.Resolve<FutureBuilder>(); var futureEnrichment = DIContainer.Resolve<FutureEnrichment>(); var forwardBuilder = new ForwardBuilder(futureBuilder, mockRepo.Object); var curves = new InterestCurves(curveBuilder); var bondspreadcalc = new BondSpreadCalculator(bondSpreadServiceModel, curveBuilder, futureBuilder, futureEnrichment, forwardBuilder, curves); bondspreadcalc.GetMarketDataStreamFromCarbon("US912828P956", new[] { "Bid", "Ask" }); bondspreadcalc.BondPriceObservable() .Subscribe(ProcessMethod); reset.WaitOne(TimeSpan.FromMinutes(1)); }
public void EnrichFuture(Future futures, Dictionary<DateTime, double> oisCurveLive, Dictionary<DateTime, double> liborCurveLive, Dictionary<DateTime, double> oisCurve, Dictionary<DateTime, double> liborCurve, BondSpreadCalculator bondSpreadCalculator) { // can throw exceptions // default country to US var eCountry = BondAnalytics.Country.US; // obtain delivery date futures.Delivery = EnrichDeliveryDate(futures); RealTimeBondData bondData; // go to the calculator cache to obtain bond prices. bondSpreadCalculator.GetBondPrices().TryGetValue(futures.RTTicker, out bondData); futures.LivePrice = double.NaN; if (bondData != null) { futures.LivePrice = (bondData.Bid + bondData.Ask)/2; futures.LivePriceTimeUtc = bondData.UtcTime; } double closePrice; if (!histPriceCache.TryGetValue(futures.RTTicker, out closePrice)) { //**** only fetch closes from symmetry service for front and back month contract in order to reduce hammering the service too much // this logic could be removed when closes have migrated to carbon var futureDateCode = FutureContractCode(futures.Contract); if (futureDateCode == _futureBuilder.FrontTicker || futureDateCode == _futureBuilder.BackTicker) { //var histPriceObj = bondServiceModel.GetHistoryPrice(futures.Contract + " Comdty", _futureBuilder.AsOfDate, "Close"); //closePrice = histPriceObj != null ? histPriceObj.Price : double.NaN; closePrice = bondServiceModel.GetCarbonHistoryPrice(futures.Contract + " Comdty", _futureBuilder.AsOfDate); if (!double.IsNaN(closePrice)) histPriceCache[futures.RTTicker] = closePrice; } else { // not front and back contract, skip close Log.InfoFormat("close price skipped for future {0}", futures.Contract); closePrice = double.NaN; } } else closePrice = histPriceCache[futures.RTTicker]; futures.ClosePrice = closePrice; // get CTD static data RealTimeBondData ctdData=null; if (!string.IsNullOrEmpty(futures.CTDRic)) bondSpreadCalculator.GetBondPrices().TryGetValue(futures.CTDRic, out ctdData); else Log.ErrorFormat("no CTD ric found for future {0}, please ensure its setup in the BSServiceClient tool", futures.Contract); // either get from carbon or override var ctdRecord = FetchSavedCTDFromMongo(futures.Contract); // validation check // if no ctd override and carbon data, we cannot proceed further if ((ctdData == null || string.IsNullOrEmpty(ctdData.BKGD_REF)) && (ctdRecord == null || string.IsNullOrEmpty(ctdRecord.CTDCusip))) { Log.ErrorFormat("no ctd override and carbon data, we cannot proceed further for {0}", futures.Contract); return; } futures.CTDReuters =(ctdRecord == null || string.IsNullOrEmpty(ctdRecord.CTDCusip)) ? ctdData.BKGD_REF.TrimEnd('=') : ctdRecord.CTDCusip.TrimEnd('='); BondStatic ctdStatic; if (futureStaticCache.ContainsKey(futures.CTDReuters)) ctdStatic = futureStaticCache[futures.CTDReuters]; else { ctdStatic = bondServiceModel.GetSingleSecurityMetadata(futures.CTDReuters); futureStaticCache[futures.CTDReuters] = ctdStatic; } futures.CTD = ctdStatic.MLP; futures.IssueDate = DateTime.FromOADate(ctdStatic.IssueDate); futures.Maturity = DateTime.FromOADate(ctdStatic.Maturity); futures.Coupon = ctdStatic.Coupon; // beware that the delivery date used to compute conversion factor is from the long dated future, therefore we need to roll back 3 days for short dated futures var deliveryDateUsedForConvFactor = (futures.IsShortLong == ShortLongFuture.ShortDated) ? bondServiceModel.RollDate(futures.Delivery, -3, DateUnit.Bd , BusinessDayConvention.Following, "USNY").ContinueWith(a => a.Result.ToDateTime()).Result : futures.Delivery; futures.ConvFator = BondAnalytics.CalcBondCF(futures.Coupon, futures.IssueDate, DateTime.MinValue, futures.Maturity, deliveryDateUsedForConvFactor, futures.Header, 0.0); // ctd bond if (double.IsNaN(futures.LivePrice)) { futures.BondPriceLive = double.NaN; futures.FwdYieldLive = double.NaN; } else { futures.BondPriceLive = futures.LivePrice * futures.ConvFator; futures.FwdYieldLive = BondAnalytics.SolveYield(eCountry, futures.Delivery, futures.BondPriceLive, DateTime.MinValue, DateTime.MinValue, futures.Maturity, futures.Coupon, 6).First(); } futures.BondPriceClose = futures.ClosePrice*futures.ConvFator; futures.FwdYieldClose = BondAnalytics.SolveYield(eCountry, futures.Delivery, futures.BondPriceClose, DateTime.MinValue,DateTime.MinValue, futures.Maturity, futures.Coupon, 6).First(); if (liborCurveLive != null) { Log.DebugFormat("deliver{0} mat{1} oiscurve{2} libor{3}", futures.Delivery, futures.Maturity, oisCurve.Keys.Select(d => d.ToString("yyyy-MM-dd")).ToArray().JoinStrings(";"), liborCurveLive.Keys.Select(d => d.ToString("yyyy-MM-dd")).ToArray().JoinStrings(";")); futures.LMMSLive = BondAnalytics.CalcMMS(futures.Delivery, futures.Maturity, BondAnalytics.DayCountType.I30360, 6, 3, oisCurve.Keys.ToArray(),oisCurve.Values.ToArray(), liborCurveLive.Keys.ToArray(), liborCurveLive.Values.ToArray(), null, null, null, null, null, null, DateTime.MinValue); } futures.LMMSClose = BondAnalytics.CalcMMS(futures.Delivery, futures.Maturity, BondAnalytics.DayCountType.I30360, 6, 3, oisCurve.Keys.ToArray(), oisCurve.Values.ToArray(), liborCurve.Keys.ToArray(), liborCurve.Values.ToArray(), null, null, null, null, null, null, DateTime.MinValue); if (oisCurveLive != null) futures.OISMMSLive = BondAnalytics.CalcMMS(futures.Delivery, futures.Maturity, BondAnalytics.DayCountType.I30360, 12, 12, oisCurve.Keys.ToArray(), oisCurve.Values.ToArray(), oisCurveLive.Keys.ToArray(), oisCurveLive.Values.ToArray(), null, null, null, null, null, null, DateTime.MinValue); futures.OISMMSClose = BondAnalytics.CalcMMS(futures.Delivery, futures.Maturity, BondAnalytics.DayCountType.I30360, 12, 12, oisCurve.Keys.ToArray(), oisCurve.Values.ToArray(), oisCurve.Keys.ToArray(), oisCurve.Values.ToArray(), null, null, null, null, null, null, DateTime.MinValue); futures.CanComputeSpread = true; }