Example #1
0
 @Test
 public void test() {
   RealSingleRootFinder finder = getRootFinder();
   assertEquals(finder.getRoot(F, 2.5, 3.5), 3, EPS);
   assertEquals(finder.getRoot(F, 1.5, 2.5), 2, EPS);
   assertEquals(finder.getRoot(F, -1.5, 0.5), -1, EPS);
 }
  private double getCriticalValue(
      final OptionDefinition definition, final StandardOptionDataBundle data, final double k) {
    final Function1D<Double, Double> f =
        new Function1D<Double, Double>() {

          @SuppressWarnings("synthetic-access")
          @Override
          public Double evaluate(final Double x) {
            return k - BSM.getPricingFunction(definition).evaluate(data.withSpot(x));
          }
        };
    return ROOT_FINDER.getRoot(f, 0., 10000.);
  }
  /** {@inheritDoc} */
  @Override
  public IsdaCompliantCreditCurve calibrateCreditCurve(
      CdsAnalytic[] cds,
      double[] premiums,
      IsdaCompliantYieldCurve yieldCurve,
      double[] pointsUpfront) {

    ArgChecker.noNulls(cds, "null CDSs");
    ArgChecker.notEmpty(premiums, "empty fractionalSpreads");
    ArgChecker.notEmpty(pointsUpfront, "empty pointsUpfront");
    ArgChecker.notNull(yieldCurve, "null yieldCurve");
    int n = cds.length;
    ArgChecker.isTrue(n == premiums.length, "Number of CDSs does not match number of spreads");
    ArgChecker.isTrue(
        n == pointsUpfront.length, "Number of CDSs does not match number of pointsUpfront");
    double proStart = cds[0].getEffectiveProtectionStart();
    for (int i = 1; i < n; i++) {
      ArgChecker.isTrue(
          proStart == cds[i].getEffectiveProtectionStart(),
          "all CDSs must has same protection start");
      ArgChecker.isTrue(
          cds[i].getProtectionEnd() > cds[i - 1].getProtectionEnd(),
          "protection end must be ascending");
    }

    // use continuous premiums as initial guess
    double[] guess = new double[n];
    double[] t = new double[n];
    for (int i = 0; i < n; i++) {
      t[i] = cds[i].getProtectionEnd();
      guess[i] = (premiums[i] + pointsUpfront[i] / t[i]) / cds[i].getLGD();
    }

    IsdaCompliantCreditCurve creditCurve = new IsdaCompliantCreditCurve(t, guess);
    for (int i = 0; i < n; i++) {
      Pricer pricer = new Pricer(cds[i], yieldCurve, t, premiums[i], pointsUpfront[i]);
      Function1D<Double, Double> func = pricer.getPointFunction(i, creditCurve);

      switch (getArbHanding()) {
        case Ignore:
          {
            try {
              double[] bracket =
                  BRACKER.getBracketedPoints(
                      func,
                      0.8 * guess[i],
                      1.25 * guess[i],
                      Double.NEGATIVE_INFINITY,
                      Double.POSITIVE_INFINITY);
              double zeroRate =
                  bracket[0] > bracket[1]
                      ? ROOTFINDER.getRoot(func, bracket[1], bracket[0])
                      : ROOTFINDER.getRoot(func, bracket[0], bracket[1]); // Negative guess handled
              creditCurve = creditCurve.withRate(zeroRate, i);
            } catch (
                MathException e) { // handling bracketing failure due to small survival probability
              if (Math.abs(func.evaluate(creditCurve.getZeroRateAtIndex(i - 1))) < 1.e-12) {
                creditCurve = creditCurve.withRate(creditCurve.getZeroRateAtIndex(i - 1), i);
              } else {
                throw new MathException(e);
              }
            }
            break;
          }
        case Fail:
          {
            double minValue =
                i == 0 ? 0.0 : creditCurve.getRTAtIndex(i - 1) / creditCurve.getTimeAtIndex(i);
            if (i > 0 && func.evaluate(minValue) > 0.0) { // can never fail on the first spread
              StringBuilder msg = new StringBuilder();
              if (pointsUpfront[i] == 0.0) {
                msg.append("The par spread of " + premiums[i] + " at index " + i);
              } else {
                msg.append(
                    "The premium of "
                        + premiums[i]
                        + "and points up-front of "
                        + pointsUpfront[i]
                        + " at index "
                        + i);
              }
              msg.append(
                  " is an arbitrage; cannot fit a curve with positive forward hazard rate. ");
              throw new IllegalArgumentException(msg.toString());
            }
            guess[i] = Math.max(minValue, guess[i]);
            double[] bracket =
                BRACKER.getBracketedPoints(
                    func, guess[i], 1.2 * guess[i], minValue, Double.POSITIVE_INFINITY);
            double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]);
            creditCurve = creditCurve.withRate(zeroRate, i);
            break;
          }
        case ZeroHazardRate:
          {
            double minValue =
                i == 0 ? 0.0 : creditCurve.getRTAtIndex(i - 1) / creditCurve.getTimeAtIndex(i);
            if (i > 0 && func.evaluate(minValue) > 0.0) { // can never fail on the first spread
              creditCurve = creditCurve.withRate(minValue, i);
            } else {
              guess[i] = Math.max(minValue, guess[i]);
              double[] bracket =
                  BRACKER.getBracketedPoints(
                      func, guess[i], 1.2 * guess[i], minValue, Double.POSITIVE_INFINITY);
              double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]);
              creditCurve = creditCurve.withRate(zeroRate, i);
            }
            break;
          }
        default:
          throw new IllegalArgumentException("unknow case " + getArbHanding());
      }
    }
    return creditCurve;
  }