/**
   * Sample demonstrating the usage of the (full set of) bond analytics API. Also shows the usage of
   * the bond loss and coupon flow functionality
   *
   * <p>USE WITH CARE: This sample ignores errors and does not handle exceptions.
   */
  public static final void BondAPISample() throws Exception {
    Set<String> setstrTickers = FI.GetAvailableTickers();

    for (String strTicker : setstrTickers) System.out.println(strTicker);

    List<String> lsstrISIN = FI.GetISINsForTicker("DB");

    for (String strBondISIN : lsstrISIN) System.out.println(strBondISIN);

    String strISIN = "US78490FUS63"; // Short-dated floater maturing at 9/15/2012
    // String strISIN = "US760677FD19"; // Amortizer
    double dblZTMFromPrice = Double.NaN;
    double dblOASTMFromPrice = Double.NaN;
    double dblZSpreadFromPrice = Double.NaN;
    double dblOASpreadFromPrice = Double.NaN;
    double dblZSpreadFromTSYSpread = Double.NaN;
    double dblOASpreadFromTSYSpread = Double.NaN;

    QuotingParams quotingParams = new QuotingParams("30/360", 2, true, null, "USD", false);

    Bond bond = FI.GetBond(strISIN);

    JulianDate dtToday = JulianDate.Today();

    DiscountCurve dc = DiscountCurve.CreateFromFlatRate(dtToday, "USD", 0.03);

    DiscountCurve dcTSY = DiscountCurve.CreateFromFlatRate(dtToday, "USD", 0.04);

    CreditCurve cc = CreditCurve.FromFlatHazard(dtToday.getJulian(), "CC", 0.02, 0.);

    ValuationParams valParams =
        ValuationParams.CreateValParams(dtToday, 0, "", DayCountBasis.DR_ACTUAL);

    PricerParams pricerParams = PricerParams.MakeStdPricerParams();

    ComponentMarketParams cmp = ComponentMarketParams.MakeCreditCMP(dc, cc);

    WorkoutInfo wi = FI.BondWorkoutInfoFromPrice(strISIN, dtToday, dc, 1.);

    double dblYieldFromPrice = FI.BondYieldFromPrice(strISIN, dtToday, dc, 1.);

    double dblYTMFromPrice = FI.BondYTMFromPrice(strISIN, valParams, dc, 1., quotingParams);

    if (!FI.IsBondFloater(strISIN)) {
      dblZSpreadFromPrice = FI.BondZSpreadFromPrice(strISIN, dtToday, dc, 1.);

      dblZTMFromPrice = FI.BondZTMFromPrice(strISIN, valParams, dc, 1., quotingParams);

      dblOASpreadFromPrice = FI.BondOASFromPrice(strISIN, dtToday, dc, 1.);

      dblOASTMFromPrice = FI.BondZTMFromPrice(strISIN, valParams, dc, 1., quotingParams);
    }

    double dblISpreadFromPrice = FI.BondISpreadFromPrice(strISIN, dtToday, dc, 1.);

    double dblITMFromPrice = FI.BondITMFromPrice(strISIN, valParams, dc, 1., quotingParams);

    double dblDiscountMarginFromPrice = FI.BondDiscountMarginFromPrice(strISIN, dtToday, dc, 1.);

    double dblDiscountMarginTMFromPrice =
        FI.BondDiscountMarginTMFromPrice(strISIN, valParams, dc, 1., quotingParams);

    double dblTSYSpreadFromPrice = FI.BondTSYSpreadFromPrice(strISIN, dtToday, dc, dcTSY, 1.);

    double dblTSYTMFromPrice =
        FI.BondTSYTMFromPrice(strISIN, valParams, dc, dcTSY, 1., quotingParams);

    double dblGSpreadFromPrice = FI.BondGSpreadFromPrice(strISIN, dtToday, dc, dcTSY, 1.);

    double dblGTMFromPrice = FI.BondGTMFromPrice(strISIN, valParams, dc, dcTSY, 1., quotingParams);

    double dblParASWFromPrice = FI.BondParASWFromPrice(strISIN, dtToday, dc, 1.);

    double dblParASWTMFromPrice = FI.BondParASWTMFromPrice(strISIN, valParams, dc, 1., null);

    double dblCreditBasisFromPrice = FI.BondCreditBasisFromPrice(strISIN, dtToday, dc, cc, 1.);

    double dblCreditBasisTMFromPrice =
        FI.BondCreditBasisTMFromPrice(strISIN, valParams, dc, cc, 1., quotingParams);

    double dblPriceFromTSYSpread = FI.BondPriceFromTSYSpread(strISIN, dtToday, dc, dcTSY, 0.0271);

    double dblYieldFromTSYSpread = FI.BondYieldFromTSYSpread(strISIN, dtToday, dcTSY, 0.0271);

    if (!FI.IsBondFloater(strISIN)) {
      dblZSpreadFromTSYSpread = FI.BondZSpreadFromTSYSpread(strISIN, dtToday, dc, dcTSY, 0.0271);

      dblOASpreadFromTSYSpread = FI.BondOASFromTSYSpread(strISIN, dtToday, dc, dcTSY, 0.0271);
    }

    double dblISpreadFromTSYSpread =
        FI.BondISpreadFromTSYSpread(strISIN, dtToday, dc, dcTSY, 0.0271);

    double dblDiscountMarginFromTSYSpread =
        FI.BondDiscountMarginFromTSYSpread(strISIN, dtToday, dc, dcTSY, 0.0271);

    double dblGSpreadFromTSYSpread =
        FI.BondGSpreadFromTSYSpread(strISIN, dtToday, dc, dcTSY, 0.0271);

    double dblParASWFromTSYSpread = FI.BondParASWFromTSYSpread(strISIN, dtToday, dc, dcTSY, 0.0271);

    double dblCreditBasisFromTSYSpread =
        FI.BondCreditBasisFromTSYSpread(strISIN, dtToday, dc, dcTSY, cc, 0.0271);

    double dblBondCreditPrice = FI.BondCreditPrice(strISIN, valParams, dc, cc, quotingParams);

    JulianDate dtPreviousCoupon = FI.PreviousCouponDate(strISIN, dtToday);

    JulianDate dtCurrentCoupon = FI.NextCouponDate(strISIN, dtToday);

    JulianDate dtNextCoupon = FI.NextCouponDate(strISIN, dtToday);

    JulianDate dtEffective = FI.EffectiveDate(strISIN);

    JulianDate dtMaturity = FI.MaturityDate(strISIN);

    boolean bInFirstPeriod = FI.InFirstPeriod(strISIN, dtToday.getJulian());

    boolean bInLastPeriod = FI.InLastPeriod(strISIN, dtToday.getJulian());

    NextExerciseInfo nei = FI.NextExerciseInfo(strISIN, dtToday);

    System.out.println(
        strISIN
            + "    "
            + bond.getTicker()
            + " "
            + FIGen.FormatPrice(bond.getCoupon(valParams._dblValue, cmp, null))
            + " "
            + bond.getMaturityDate());

    System.out.println("Work-out date From Price: " + new JulianDate(wi._dblDate));

    System.out.println("Work-out factor From Price: " + wi._dblExerciseFactor);

    System.out.println("Work-out Yield From Price: " + FIGen.FormatPrice(wi._dblYield));

    System.out.println(
        "Work-out Type for Price: "
            + org.drip.util.internal.FIUtil.WorkoutTypeToString(wi._iWOType));

    System.out.println(
        "Yield From Price: "
            + FIGen.FormatPrice(dblYieldFromPrice)
            + " / "
            + FIGen.FormatPrice(dblYTMFromPrice));

    System.out.println(
        "Z Spread From Price: "
            + (int) (10000. * dblZSpreadFromPrice)
            + " / "
            + (int) (10000. * dblZTMFromPrice));

    System.out.println(
        "Option Adj Spread From Price: "
            + (int) (10000. * dblOASpreadFromPrice)
            + " / "
            + (int) (10000. * dblOASTMFromPrice));

    System.out.println(
        "I Spread From Price: "
            + (int) (10000. * dblISpreadFromPrice)
            + " / "
            + (int) (10000. * dblITMFromPrice));

    System.out.println(
        "Discount Margin From Price: "
            + (int) (10000. * dblDiscountMarginFromPrice)
            + " / "
            + (int) (10000. * dblDiscountMarginTMFromPrice));

    System.out.println(
        "TSY Spread From Price: "
            + (int) (10000. * dblTSYSpreadFromPrice)
            + " / "
            + (int) (10000. * dblTSYTMFromPrice));

    System.out.println(
        "G Spread From Price: "
            + (int) (10000. * dblGSpreadFromPrice)
            + " / "
            + (int) (10000. * dblGTMFromPrice));

    System.out.println(
        "Par ASW From Price: " + (int) dblParASWFromPrice + " / " + (int) dblParASWTMFromPrice);

    System.out.println(
        "Credit Basis From Price: "
            + (int) (10000. * dblCreditBasisFromPrice)
            + " / "
            + (int) (10000. * dblCreditBasisTMFromPrice));

    System.out.println("Price From TSY Spread: " + FIGen.FormatPrice(dblPriceFromTSYSpread));

    System.out.println("Yield From TSY Spread: " + FIGen.FormatPrice(dblYieldFromTSYSpread));

    System.out.println("Z Spread From TSY Spread: " + (int) (10000. * dblZSpreadFromTSYSpread));

    System.out.println("OAS From TSY Spread: " + (int) (10000. * dblOASpreadFromTSYSpread));

    System.out.println("I Spread From TSY Spread: " + (int) (10000. * dblISpreadFromTSYSpread));

    System.out.println(
        "Discount Margin From TSY Spread: " + (int) (10000. * dblDiscountMarginFromTSYSpread));

    System.out.println("G Spread From TSY Spread: " + (int) (10000. * dblGSpreadFromTSYSpread));

    System.out.println("Par ASW From TSY Spread: " + (int) dblParASWFromTSYSpread);

    System.out.println(
        "Credit Basis From TSY Spread: " + (int) (10000. * dblCreditBasisFromTSYSpread));

    System.out.println("Credit Risky Price: " + FIGen.FormatPrice(dblBondCreditPrice));

    System.out.println("Valuation Date: " + JulianDate.Today());

    System.out.println("Effective Date: " + dtEffective);

    System.out.println("Maturity Date: " + dtMaturity);

    System.out.println("Is Val Date in the first period? " + bInFirstPeriod);

    System.out.println("Is Val Date in the last period? " + bInLastPeriod);

    System.out.println("Previous Coupon Date: " + dtPreviousCoupon);

    System.out.println("Current Coupon Date: " + dtCurrentCoupon);

    System.out.println("Next Coupon Date: " + dtNextCoupon);

    System.out.println("Next Exercise Date: " + new JulianDate(nei._dblDate));

    System.out.println("Next Exercise Factor: " + nei._dblExerciseFactor);

    System.out.println(
        "Next Exercise Type: " + org.drip.util.internal.FIUtil.WorkoutTypeToString(nei._iWOType));

    if (bond.isFloater()) {
      System.out.println(
          "Acc Start       Acc End     Pay Date    Index   Spread   Cpn DCF    Pay01    Surv01");

      System.out.println(
          "---------      ---------    ---------   ------  ------   -------- --------- --------");

      for (ProductCouponPeriodCurveMeasures p : bond.getCouponFlow(valParams, pricerParams, cmp))
        System.out.println(
            JulianDate.fromJulian(p.getAccrualStartDate())
                + FIELD_SEPARATOR
                + JulianDate.fromJulian(p.getAccrualEndDate())
                + FIELD_SEPARATOR
                + JulianDate.fromJulian(p.getPayDate())
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(p.getIndexRate(), 1, 4, 1.)
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(p.getSpread(), 1, 4, 1.)
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(p.getCouponDCF(), 1, 4, 1.)
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(dc.getDF(p.getPayDate()), 1, 4, 1.)
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(cc.getSurvival(p.getPayDate()), 1, 4, 1.));
    } else {
      System.out.println("Acc Start       Acc End     Pay Date   Cpn DCF    Pay01    Surv01");

      System.out.println("---------      ---------    ---------  -------- --------- --------");

      for (ProductCouponPeriodCurveMeasures p : bond.getCouponFlow(valParams, pricerParams, cmp))
        System.out.println(
            JulianDate.fromJulian(p.getAccrualStartDate())
                + FIELD_SEPARATOR
                + JulianDate.fromJulian(p.getAccrualEndDate())
                + FIELD_SEPARATOR
                + JulianDate.fromJulian(p.getPayDate())
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(p.getCouponDCF(), 1, 4, 1.)
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(dc.getDF(p.getPayDate()), 1, 4, 1.)
                + FIELD_SEPARATOR
                + FIGen.FormatSpreadSimple(cc.getSurvival(p.getPayDate()), 1, 4, 1.));
    }

    System.out.println(
        "Loss Start     Loss End      Pay Date      Cpn    Notl     Rec    EffDF    StartSurv  EndSurv");

    System.out.println(
        "----------     --------      --------      ---    ----     ---    -----    ---------  -------");

    for (ProductLossPeriodCurveMeasures dp : bond.getLossFlow(valParams, pricerParams, cmp))
      System.out.println(
          JulianDate.fromJulian(dp.getStartDate())
              + FIELD_SEPARATOR
              + JulianDate.fromJulian(dp.getEndDate())
              + FIELD_SEPARATOR
              + JulianDate.fromJulian(dp.getPayDate())
              + FIELD_SEPARATOR
              + FIGen.FormatSpreadSimple(dp.getCouponDCF(), 1, 4, 1.)
              + FIELD_SEPARATOR
              + FIGen.FormatSpreadSimple(dp.getEffectiveNotional(), 1, 0, 1.)
              + FIELD_SEPARATOR
              + FIGen.FormatSpreadSimple(dp.getEffectiveRecovery(), 1, 2, 1.)
              + FIELD_SEPARATOR
              + FIGen.FormatSpreadSimple(dp.getEffectiveDF(), 1, 4, 1.)
              + FIELD_SEPARATOR
              + FIGen.FormatSpreadSimple(dp.getStartSurvival(), 1, 4, 1.)
              + FIELD_SEPARATOR
              + FIGen.FormatSpreadSimple(dp.getEndSurvival(), 1, 4, 1.));
  }