public static BondSpreadResult GetSpreads(Symmetry.Data.FIBond bond_, QuoteValueType priceType_, double priceValue_, SwapCurveType curveType_, DateTime asOf_, CarbonClient client_, ThrowBehavior behavior_ = ThrowBehavior.DontThrow) { return GetSpreads( bondType_: OTBondHelper.GetBond(bond_), maturity_:bond_.FI.Maturity.Value.ToNodaLocalDate(), issueDate_:bond_.IssueDate.Value.ToNodaLocalDate(), firstCouponDate_: bond_.Coupon==0 ? bond_.IssueDate.Value.ToNodaLocalDate() : bond_.FirstCouponDate.Value.ToNodaLocalDate(), priceType_:priceType_, priceValue_:priceValue_, coupon_: Convert.ToDouble(bond_.Coupon)/100d, pricingSetup_: CurveMappings.GetMapping(curveType_), asOf_: asOf_, client_: client_, behavior_: behavior_); }
public static BondSpreadResult GetSpreads(OTBond bondType_, SwapCurveType curveType_, NodaTime.LocalDate maturity_, NodaTime.LocalDate issueDate_, NodaTime.LocalDate firstCouponDate_, QuoteValueType priceType_, double priceValue_, double coupon_, DateTime asOf_, CarbonClient client_, ThrowBehavior behavior_ = ThrowBehavior.DontThrow) { return GetSpreads( bondType_, maturity_, issueDate_, firstCouponDate_, priceType_, priceValue_, coupon_, CurveMappings.GetMapping(curveType_), asOf_, client_, behavior_); }
/// <summary> /// Calculate the bondspreads for the given bond over the given swap curve /// </summary> /// <param name="bond_"></param> /// <param name="priceType_">either yield or price</param> /// <param name="priceValue_">if price, then pass 100.3 rather than 1.003</param> /// <param name="curveType_">the swap curve</param> /// <param name="country_">JB's country definitions</param> /// <param name="asOf_">the date of the price. will determine the date of the curves that are used</param> /// <param name="client_">carbon client to get holidays</param> /// <param name="quoteSource_">mlp/sym</param> /// <param name="snapCode_">mlp/nyk/ldn</param> /// <param name="behavior_">whether you want exceptions to be swallowed or not</param> /// <returns></returns> public static async Task<BondSpreadResult> GetSpreads( Symmetry.Data.FIBond bond_, QuoteValueType priceType_, double priceValue_, SwapCurveType curveType_, BondAnalytics.Country country_, DateTime asOf_, CarbonClient client_, string quoteSource_, string snapCode_, ThrowBehavior behavior_ = ThrowBehavior.DontThrow) { try { var mapping = CurveMappings.GetMapping(curveType_); var settleDate = await client_.RollDateAsync( date: asOf_.Date.ToNodaLocalDate(), count: country_.SettleDateDays(), unit: DateUnit.Bd, convention: BusinessDayConvention.Following, calendar: country_.OTHolidayCode()); var holidays = CalendarRetriever.GetCalendar(country_.OTHolidayCode(), client_).ToList(); var startDate = bond_.EffectiveDate.Value; var firstCpnDate = bond_.Coupon==0 ? bond_.IssueDate.Value : bond_.FirstCouponDate.Value; var maturity = bond_.FI.Maturity; var coupon = Convert.ToDouble(bond_.Coupon); // get the persisted discount curves for the fixed and floating legs var discCurve = SObjectManager.Instance().LoadSObject<DiscountCurve>(new Moniker() { Close = snapCode_, Source = quoteSource_, Name = KnownCurveHelpers.GetKnownCurveCode(mapping.DiscountCurve), Type = "discountcurve", Date = asOf_.Date }); if (discCurve == null) { SLog.log.ErrorFormat("Could not load {0} discount curve from database for {1}", mapping.DiscountCurve, asOf_.Date); return null; } var fcstCurve = SObjectManager.Instance().LoadSObject<DiscountCurve>(new Moniker() { Close = snapCode_, Source = quoteSource_, Name = KnownCurveHelpers.GetKnownCurveCode(mapping.ForecastCurve), Type = "discountcurve", Date = asOf_.Date }); if (fcstCurve == null) { SLog.log.ErrorFormat("Could not load {0} discount curve from database for {1}", mapping.ForecastCurve, asOf_.Date); return null; } double price=0, yield=0; switch (priceType_) { case QuoteValueType.Price: price = priceValue_; yield = BondAnalytics.SolveYield( country: country_, settleDate: settleDate.ToDateTime(), cleanPrice: price, startDate: startDate, firstCpnDate: firstCpnDate, maturityDate: maturity.Value, coupon: coupon, freq: country_.BondFreq())[0]; break; case QuoteValueType.Yield: yield = priceValue_; price = BondAnalytics.PriceFromYield( country: country_, settleDate: settleDate.ToDateTime(), yield: priceValue_, startDate: startDate, firstCpnDate: firstCpnDate, maturityDate: maturity.Value, coupon: coupon, freq: country_.BondFreq())[0]; break; } var mms = BondAnalytics.CalcMMS( startDate: settleDate.ToDateTime(), maturityDate: maturity.Value, dctType: mapping.DayCountType, fixedFreq: (long) mapping.FixedFreq, floatFreq: (long) mapping.FloatFreq, discCurveDates: discCurve.AsDoubleArray().SliceColumn(0).Select(DateTime.FromOADate).ToArray(), discDfs: discCurve.AsDoubleArray().SliceColumn(1), fcstCurveDates: fcstCurve.AsDoubleArray().SliceColumn(0).Select(DateTime.FromOADate).ToArray(), fcstDfs: fcstCurve.AsDoubleArray().SliceColumn(1), holidays: holidays, stubExpiries: null, stubTenors: null, stubValues: null, fixingTenors: null, fixings: null, firstCpnDate: firstCpnDate ); var truespread = BondAnalytics.SolveZSpread( country: country_, settleDate: settleDate.ToDateTime(), cleanPrice: price, startDate: startDate, firstCpnDate: firstCpnDate, maturityDate: maturity.Value, coupon: coupon, freq: country_.BondFreq(), curveDates: fcstCurve.AsDoubleArray().SliceColumn(0).Select(DateTime.FromOADate).ToArray(), dfs: fcstCurve.AsDoubleArray().SliceColumn(1), holidays: holidays); return new BondSpreadResult { Price = price, Spreads = new BondSpread { Yield=yield, MMS=mms, TrueSpread=truespread * -1d, Spread = mms-yield, } }; } catch (Exception ex_) { Exceptions.Rethrow("Error calculating bondspread", behavior_, ex_); return null; } }