private static final CalibratableFixedIncomeComponent[] DepositInstrumentsFromMaturityDays(
      final JulianDate dtEffective,
      final int[] aiDay,
      final int iNumFutures,
      final String strCurrency)
      throws Exception {
    CalibratableFixedIncomeComponent[] aCalibComp =
        new CalibratableFixedIncomeComponent[aiDay.length + iNumFutures];

    for (int i = 0; i < aiDay.length; ++i)
      aCalibComp[i] =
          SingleStreamComponentBuilder.Deposit(
              dtEffective,
              dtEffective.addBusDays(aiDay[i], strCurrency),
              ForwardLabel.Create(strCurrency, aiDay[i] + "D"));

    CalibratableFixedIncomeComponent[] aEDF =
        SingleStreamComponentBuilder.FuturesPack(dtEffective, iNumFutures, strCurrency);

    for (int i = aiDay.length; i < aiDay.length + iNumFutures; ++i)
      aCalibComp[i] = aEDF[i - aiDay.length];

    return aCalibComp;
  }
  @Test(dataProvider = "mainparam", dataProviderClass = org.drip.sample.TestNGDataProvider.class)
  public static void main(final String[] astrArgs) throws Exception {
    /*
     * Initialize the Credit Analytics Library
     */

    CreditAnalytics.Init("");

    JulianDate dtValue = DateUtil.CreateFromYMD(2012, DateUtil.DECEMBER, 11);

    String strTenor = "1M";
    String strCurrency = "USD";

    ForwardLabel fri = ForwardLabel.Create(strCurrency, strTenor);

    DiscountCurve dcEONIA = OvernightIndexCurve.MakeDC(dtValue, strCurrency);

    SegmentCustomBuilderControl scbcCubic =
        new SegmentCustomBuilderControl(
            MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
            new PolynomialFunctionSetParams(5),
            SegmentInelasticDesignControl.Create(2, 2),
            new ResponseScalingShapeControl(true, new QuadraticRationalShapeControl(0.)),
            null);

    /*
     * Construct the Array of Deposit Instruments and their Quotes from the given set of parameters
     */

    double[] adblDepositQuote = new double[] {0.000661, 0.000980, 0.000993};

    String[] astrDepositTenor = new String[] {"1D", "7D", "14D"};

    /*
     * Construct the Array of Fix-Float Component and their Quotes from the given set of parameters
     */

    double[] adblFixFloatQuote =
        new double[] {
          0.001100, 0.001060, 0.000960, 0.000850, 0.000790, 0.000750, 0.000710, 0.000690, 0.000660,
          0.000650, 0.000640, 0.000630
        };

    String[] astrFixFloatTenor =
        new String[] {"1M", "2M", "3M", "4M", "5M", "6M", "7M", "8M", "9M", "10M", "11M", "12M"};

    /*
     * Construct the Array of Float-Float Component and their Quotes from the given set of parameters
     */

    double[] adblFloatFloatQuote =
        new double[] {
          0.002260, //  2Y
          0.002380, //  3Y
          0.002460, //  4Y
          0.002500, //  5Y
          0.002500, //  6Y
          0.002480, //  7Y
          0.002450, //  8Y
          0.002410, //  9Y
          0.002370, // 10Y
          0.002330, // 11Y
          0.002280, // 12Y
          0.002110, // 15Y
          0.001890, // 20Y
          0.001750, // 25Y
          0.001630 // 30Y
        };

    String[] astrFloatFloatTenor =
        new String[] {
          "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y", "25Y",
          "30Y"
        };

    /*
     * Construct the Array of Terminal Synthetic Float-Float Components and their Quotes from the given set of parameters
     */

    String[] astrSyntheticFloatFloatTenor = new String[] {"35Y", "40Y", "50Y", "60Y"};

    double[] adblSyntheticFloatFloatQuote = new double[] {0.001630, 0.001630, 0.001630, 0.001630};

    ForwardCurve fc6M = IBOR6MCubicPolyVanilla.Make6MForward(dtValue, strCurrency, "6M", true);

    ForwardCurve fc =
        IBORCurve.CustomIBORBuilderSample(
            dcEONIA,
            fc6M,
            fri,
            scbcCubic,
            astrDepositTenor,
            adblDepositQuote,
            "ForwardRate",
            null,
            null,
            "ParForwardRate",
            astrFixFloatTenor,
            adblFixFloatQuote,
            "SwapRate",
            astrFloatFloatTenor,
            adblFloatFloatQuote,
            "DerivedParBasisSpread",
            astrSyntheticFloatFloatTenor,
            adblSyntheticFloatFloatQuote,
            "DerivedParBasisSpread",
            "---- VANILLA QUARTIC POLYNOMIAL FORWARD CURVE ---",
            true);

    IBORCurve.ForwardJack(
        dtValue,
        "---- VANILLA QUARTIC POLYNOMIAL FORWARD CURVE SENSITIVITY ---",
        fc,
        "DerivedParBasisSpread");
  }
  private static final Map<String, ForwardCurve> xM6MBasisSample(
      final JulianDate dtSpot,
      final String strCurrency,
      final DiscountCurve dc,
      final int iTenorInMonths,
      final String[] astrxM6MFwdTenor,
      final double[] adblxM6MBasisSwapQuote)
      throws Exception {
    System.out.println("------------------------------------------------------------");

    System.out.println(" SPL =>              n=4               |         |         |");

    System.out.println("---------------------------------------|  LOG DF |  LIBOR  |");

    System.out.println(" MSR =>  RECALC  |  REFEREN |  DERIVED |         |         |");

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

    /*
     * Construct the 6M-xM float-float basis swap.
     */

    FloatFloatComponent[] aFFC =
        MakexM6MBasisSwap(dtSpot, strCurrency, astrxM6MFwdTenor, iTenorInMonths);

    String strBasisTenor = iTenorInMonths + "M";

    ValuationParams valParams = new ValuationParams(dtSpot, dtSpot, strCurrency);

    /*
     * Calculate the starting forward rate off of the discount curve.
     */

    double dblStartingFwd = dc.forward(dtSpot.julian(), dtSpot.addTenor(strBasisTenor).julian());

    /*
     * Set the discount curve based component market parameters.
     */

    CurveSurfaceQuoteSet mktParams =
        MarketParamsBuilder.Create(dc, null, null, null, null, null, null);

    Map<String, ForwardCurve> mapForward = new HashMap<String, ForwardCurve>();

    /*
     * Construct the shape preserving forward curve off of Quartic Polynomial Basis Spline.
     */

    ForwardCurve fcxMQuartic =
        ScenarioForwardCurveBuilder.ShapePreservingForwardCurve(
            "QUARTIC_FWD" + strBasisTenor,
            ForwardLabel.Create(strCurrency, strBasisTenor),
            valParams,
            null,
            mktParams,
            null,
            MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL,
            new PolynomialFunctionSetParams(5),
            aFFC,
            "ReferenceParBasisSpread",
            adblxM6MBasisSwapQuote,
            dblStartingFwd);

    mapForward.put(" QUARTIC_FWD" + strBasisTenor, fcxMQuartic);

    /*
     * Set the discount curve + quartic polynomial forward curve based component market parameters.
     */

    CurveSurfaceQuoteSet mktParamsQuarticFwd =
        MarketParamsBuilder.Create(dc, fcxMQuartic, null, null, null, null, null, null);

    int i = 0;
    int iFreq = 12 / iTenorInMonths;

    /*
     * Compute the following forward curve metrics for each of cubic polynomial forward, quartic
     * 	polynomial forward, and KLK Hyperbolic tension forward curves:
     * 	- Reference Basis Par Spread
     * 	- Derived Basis Par Spread
     *
     * Further compare these with a) the forward rate off of the discount curve, b) the LIBOR rate, and
     * 	c) Input Basis Swap Quote.
     */

    for (String strMaturityTenor : astrxM6MFwdTenor) {
      double dblFwdEndDate = dtSpot.addTenor(strMaturityTenor).julian();

      double dblFwdStartDate =
          dtSpot.addTenor(strMaturityTenor).subtractTenor(strBasisTenor).julian();

      FloatFloatComponent ffc = aFFC[i++];

      CaseInsensitiveTreeMap<Double> mapQuarticValue =
          ffc.value(valParams, null, mktParamsQuarticFwd, null);

      System.out.println(
          " "
              + strMaturityTenor
              + " =>  "
              + FormatUtil.FormatDouble(fcxMQuartic.forward(strMaturityTenor), 2, 2, 100.)
              + "  |  "
              + FormatUtil.FormatDouble(mapQuarticValue.get("ReferenceParBasisSpread"), 2, 2, 1.)
              + "  |  "
              + FormatUtil.FormatDouble(mapQuarticValue.get("DerivedParBasisSpread"), 2, 2, 1.)
              + "  |  "
              + FormatUtil.FormatDouble(
                  iFreq * java.lang.Math.log(dc.df(dblFwdStartDate) / dc.df(dblFwdEndDate)),
                  1,
                  2,
                  100.)
              + "  |  "
              + FormatUtil.FormatDouble(dc.libor(dblFwdStartDate, dblFwdEndDate), 1, 2, 100.)
              + "  |  ");
    }

    return mapForward;
  }
  public static final void main(final String[] astrArgs) throws Exception {
    /*
     * Initialize the Credit Analytics Library
     */

    CreditAnalytics.Init("");

    JulianDate dtToday = DateUtil.Today();

    String[] astrTenor =
        new String[] {
          "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9Y", "10Y", "11Y", "12Y", "15Y", "20Y",
          "25Y", "30Y"
        };

    double[] adblBasis =
        new double[] {
          0.00186, //  1Y
          0.00127, //  2Y
          0.00097, //  3Y
          0.00080, //  4Y
          0.00067, //  5Y
          0.00058, //  6Y
          0.00051, //  7Y
          0.00046, //  8Y
          0.00042, //  9Y
          0.00038, // 10Y
          0.00035, // 11Y
          0.00033, // 12Y
          0.00028, // 15Y
          0.00022, // 20Y
          0.00020, // 25Y
          0.00018 // 30Y
        };

    BasisCurve bcCubicPolynomial =
        ScenarioBasisCurveBuilder.CubicPolynomialBasisCurve(
            "USD3M6MBasis_CubicPolynomial",
            dtToday,
            ForwardLabel.Create("USD", "6M"),
            ForwardLabel.Create("USD", "3M"),
            false,
            new CollateralizationParams("OVERNIGHT", "USD"),
            astrTenor,
            adblBasis);

    BasisCurve bcQuinticPolynomial =
        ScenarioBasisCurveBuilder.QuarticPolynomialBasisCurve(
            "USD3M6MBasis_QuinticPolynomial",
            dtToday,
            ForwardLabel.Create("USD", "6M"),
            ForwardLabel.Create("USD", "3M"),
            false,
            new CollateralizationParams("OVERNIGHT", "USD"),
            astrTenor,
            adblBasis);

    BasisCurve bcKaklisPandelis =
        ScenarioBasisCurveBuilder.KaklisPandelisBasisCurve(
            "USD3M6MBasis_KaklisPandelis",
            dtToday,
            ForwardLabel.Create("USD", "6M"),
            ForwardLabel.Create("USD", "3M"),
            false,
            new CollateralizationParams("OVERNIGHT", "USD"),
            astrTenor,
            adblBasis);

    BasisCurve bcKLKHyperbolic =
        ScenarioBasisCurveBuilder.KLKHyperbolicBasisCurve(
            "USD3M6MBasis_KLKHyperbolic",
            dtToday,
            ForwardLabel.Create("USD", "6M"),
            ForwardLabel.Create("USD", "3M"),
            false,
            new CollateralizationParams("OVERNIGHT", "USD"),
            astrTenor,
            adblBasis,
            1.);

    BasisCurve bcKLKRationalLinear =
        ScenarioBasisCurveBuilder.KLKRationalLinearBasisCurve(
            "USD3M6MBasis_KLKRationalLinear",
            dtToday,
            ForwardLabel.Create("USD", "6M"),
            ForwardLabel.Create("USD", "3M"),
            false,
            new CollateralizationParams("OVERNIGHT", "USD"),
            astrTenor,
            adblBasis,
            0.1);

    BasisCurve bcKLKRationalQuadratic =
        ScenarioBasisCurveBuilder.KLKRationalLinearBasisCurve(
            "USD3M6MBasis_KLKRationalQuadratic",
            dtToday,
            ForwardLabel.Create("USD", "6M"),
            ForwardLabel.Create("USD", "3M"),
            false,
            new CollateralizationParams("OVERNIGHT", "USD"),
            astrTenor,
            adblBasis,
            2.);

    System.out.println("\tPrinting the Basis Node Values in Order (Left -> Right):");

    System.out.println("\t\tCalculated Cubic Polynomial Basis (%)");

    System.out.println("\t\tCalculated Quintic Polynomial Basis (%)");

    System.out.println("\t\tCalculated Kaklis Pandelis Basis (%)");

    System.out.println("\t\tCalculated KLK Hyperbolic Basis (%)");

    System.out.println("\t\tCalculated KLK Rational Linear Basis (%)");

    System.out.println("\t\tCalculated KLK Rational Quadratic Basis (%)");

    System.out.println("\t\tInput Quote (bp)");

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

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

    for (int i = 0; i < adblBasis.length; ++i)
      System.out.println(
          "\t"
              + astrTenor[i]
              + " => "
              + FormatUtil.FormatDouble(bcCubicPolynomial.basis(astrTenor[i]), 1, 2, 10000.)
              + " | "
              + FormatUtil.FormatDouble(bcQuinticPolynomial.basis(astrTenor[i]), 1, 2, 10000.)
              + " | "
              + FormatUtil.FormatDouble(bcKaklisPandelis.basis(astrTenor[i]), 1, 2, 10000.)
              + " | "
              + FormatUtil.FormatDouble(bcKLKHyperbolic.basis(astrTenor[i]), 1, 2, 10000.)
              + " | "
              + FormatUtil.FormatDouble(bcKLKRationalLinear.basis(astrTenor[i]), 1, 2, 10000.)
              + " | "
              + FormatUtil.FormatDouble(bcKLKRationalQuadratic.basis(astrTenor[i]), 1, 2, 10000.)
              + " | "
              + FormatUtil.FormatDouble(adblBasis[i], 1, 2, 10000.));

    System.out.println(
        "\n\t|----------------------------------------------------------------------------|");

    System.out.println(
        "\t|  DATE    =>  CUBIC | QUINTIC  | KAKPAND | KLKHYPER | KLKRATLNR | KLKRATQUA |");

    System.out.println(
        "\t|----------------------------------------------------------------------------|\n");

    for (int i = 3; i < 30; ++i) {
      JulianDate dt = dtToday.addTenor(i + "Y");

      System.out.println(
          "\t"
              + dt
              + " => "
              + FormatUtil.FormatDouble(bcCubicPolynomial.basis(dt), 1, 2, 10000.)
              + "  |  "
              + FormatUtil.FormatDouble(bcQuinticPolynomial.basis(dt), 1, 2, 10000.)
              + "   |  "
              + FormatUtil.FormatDouble(bcKaklisPandelis.basis(dt), 1, 2, 10000.)
              + "  |  "
              + FormatUtil.FormatDouble(bcKLKHyperbolic.basis(dt), 1, 2, 10000.)
              + "   |  "
              + FormatUtil.FormatDouble(bcKLKRationalLinear.basis(dt), 1, 2, 10000.)
              + "    |  "
              + FormatUtil.FormatDouble(bcKLKRationalQuadratic.basis(dt), 1, 2, 10000.)
              + "    |  ");
    }

    System.out.println(
        "\n\t|----------------------------------------------------------------------------|");
  }