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;
             
            
        }