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