private double[] bracketRoot(double optionPrice, double sigma) { BracketRoot bracketer = new BracketRoot(); Function<Double, Double> func = new Function<Double, Double>() { @Override public Double apply(Double volatility) { return priceFunc.apply(volatility) / optionPrice - 1.0; } }; return bracketer.getBracketedPoints( func, Math.max(0.0, sigma - BRACKET_STEP), sigma + BRACKET_STEP, 0d, Double.POSITIVE_INFINITY); }
/** * Computes the conventional real yield from the dirty price. * <p> * The input dirty price should be real price or nominal price depending on the yield convention. This is coherent to * the implementation of {@link #dirtyPriceFromRealYield(ResolvedCapitalIndexedBond, RatesProvider, LocalDate, double)}. * <p> * The input price and output are expressed in fraction. * * @param bond the product * @param ratesProvider the rates provider, used to determine price index values * @param settlementDate the settlement date * @param dirtyPrice the bond dirty price * @return the yield of the product */ public double realYieldFromDirtyPrice( ResolvedCapitalIndexedBond bond, RatesProvider ratesProvider, LocalDate settlementDate, double dirtyPrice) { final Function<Double, Double> priceResidual = new Function<Double, Double>() { @Override public Double apply(Double y) { return dirtyPriceFromRealYield(bond, ratesProvider, settlementDate, y) - dirtyPrice; } }; double[] range = ROOT_BRACKETER.getBracketedPoints(priceResidual, -0.05, 0.10); double yield = ROOT_FINDER.getRoot(priceResidual, range[0], range[1]); return yield; }
private static final BracketRoot ROOT_BRACKETER = new BracketRoot();
double[] range = ROOT_BRACKETER.getBracketedPoints(residual, -0.01, 0.01); // Starting range is [-1%, 1%] return ROOT_FINDER.getRoot(residual, range[0], range[1]);
/** * Calculates the exercise boundary for swaptions. * <p> * Reference: Henrard, M. (2003). "Explicit bond option and swaption formula in Heath-Jarrow-Morton one-factor model". * International Journal of Theoretical and Applied Finance, 6(1):57--72. * * @param discountedCashFlow the cash flow equivalent discounted to today * @param alpha the zero-coupon bond volatilities * @return the exercise boundary */ public double kappa(DoubleArray discountedCashFlow, DoubleArray alpha) { final Function<Double, Double> swapValue = new Function<Double, Double>() { @Override public Double apply(Double x) { double error = 0.0; for (int loopcf = 0; loopcf < alpha.size(); loopcf++) { error += discountedCashFlow.get(loopcf) * Math.exp(-0.5 * alpha.get(loopcf) * alpha.get(loopcf) - (alpha.get(loopcf) - alpha.get(0)) * x); } return error; } }; BracketRoot bracketer = new BracketRoot(); double accuracy = 1.0E-8; RidderSingleRootFinder rootFinder = new RidderSingleRootFinder(accuracy); double[] range = bracketer.getBracketedPoints(swapValue, -2.0, 2.0); return rootFinder.getRoot(swapValue, range[0], range[1]); }
double[] range = ROOT_BRACKETER.getBracketedPoints(residual, -0.5, 0.5); // Starting range is [-1%, 1%] return ROOT_FINDER.getRoot(residual, range[0], range[1]);
/** * Calculates the common part of the exercise boundary of European swaptions forward. * <p> * This is intended to be used in particular for Bermudan swaption first step of the pricing. * <p> * Reference: Henrard, "M. Bermudan Swaptions in Gaussian HJM One-Factor Model: Analytical and Numerical Approaches". * SSRN, October 2008. Available at SSRN: http://ssrn.com/abstract=1287982 * * @param discountedCashFlow the swap discounted cash flows * @param alpha2 square of the alpha parameter * @param hwH the H factors * @return the exercise boundary */ public double lambda(DoubleArray discountedCashFlow, DoubleArray alpha2, DoubleArray hwH) { final Function<Double, Double> swapValue = new Function<Double, Double>() { @Override public Double apply(Double x) { double value = 0.0; for (int loopcf = 0; loopcf < alpha2.size(); loopcf++) { value += discountedCashFlow.get(loopcf) * Math.exp(-0.5 * alpha2.get(loopcf) - hwH.get(loopcf) * x); } return value; } }; BracketRoot bracketer = new BracketRoot(); double accuracy = 1.0E-8; RidderSingleRootFinder rootFinder = new RidderSingleRootFinder(accuracy); double[] range = bracketer.getBracketedPoints(swapValue, -2.0, 2.0); return rootFinder.getRoot(swapValue, range[0], range[1]); }
double[] range = ROOT_BRACKETER.getBracketedPoints(residual, -0.5, 0.5); // Starting range is [-1%, 1%] return ROOT_FINDER.getRoot(residual, range[0], range[1]);
private double[] computesFittingParameters() { double[] param = new double[3]; // Implementation note: called a,b,c in the note. // Computes derivatives at cut-off. double[] vD = new double[6]; double[][] vD2 = new double[2][2]; volatilityK = sabrFunction.volatilityAdjoint2(forward, cutOffStrike, timeToExpiry, sabrData, vD, vD2); Pair<ValueDerivatives, double[][]> pa2 = BlackFormulaRepository.priceAdjoint2(forward, cutOffStrike, timeToExpiry, volatilityK, true); double[] bsD = pa2.getFirst().getDerivatives().toArrayUnsafe(); double[][] bsD2 = pa2.getSecond(); priceK[0] = pa2.getFirst().getValue(); priceK[1] = bsD[1] + bsD[3] * vD[1]; priceK[2] = bsD2[1][1] + bsD2[1][2] * vD[1] + (bsD2[2][1] + bsD2[2][2] * vD[1]) * vD[1] + bsD[3] * vD2[1][1]; if (Math.abs(priceK[0]) < SMALL_PRICE && Math.abs(priceK[1]) < SMALL_PRICE && Math.abs(priceK[2]) < SMALL_PRICE) { // Implementation note: If value and its derivatives is too small, then parameters are such that the extrapolated price is "very small". return new double[] {-100.0, 0, 0}; } Function<Double, Double> toSolveC = getCFunction(priceK, cutOffStrike, mu); BracketRoot bracketer = new BracketRoot(); double accuracy = 1.0E-5; RidderSingleRootFinder rootFinder = new RidderSingleRootFinder(accuracy); double[] range = bracketer.getBracketedPoints(toSolveC, -1.0, 1.0); param[2] = rootFinder.getRoot(toSolveC, range[0], range[1]); param[1] = -2 * param[2] / cutOffStrike - (priceK[1] / priceK[0] * cutOffStrike + mu) * cutOffStrike; param[0] = Math.log(priceK[0] / Math.pow(cutOffStrike, -mu)) - param[1] / cutOffStrike - param[2] / (cutOffStrike * cutOffStrike); return param; }
BRACKETER.getBracketedPoints(func, 0.8 * guess, 1.25 * guess, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY) : BRACKETER.getBracketedPoints(func, 1.25 * guess, 0.8 * guess, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); double r = rootFinder.getRoot(func, grad, bracket[0], bracket[1]); return curve.withParameter(curveIndex, r);
BracketRoot bracketer = new BracketRoot(); BisectionSingleRootFinder rootFinder = new BisectionSingleRootFinder(EPS); Function<Double, Double> func = new Function<Double, Double>() { double[] range = bracketer.getBracketedPoints(func, 0d, 10d); return rootFinder.getRoot(func, range[0], range[1]);
/** * Calculates the yield of the fixed coupon bond product from dirty price. * <p> * The dirty price must be fractional. * If the analytic formula is not available, the yield is computed by solving * a root-finding problem with {@link #dirtyPriceFromYield(ResolvedFixedCouponBond, LocalDate, double)}. * The result is also expressed in fraction. * * @param bond the product * @param settlementDate the settlement date * @param dirtyPrice the dirty price * @return the yield of the product */ public double yieldFromDirtyPrice(ResolvedFixedCouponBond bond, LocalDate settlementDate, double dirtyPrice) { if (bond.getYieldConvention().equals(JP_SIMPLE)) { double cleanPrice = cleanPriceFromDirtyPrice(bond, settlementDate, dirtyPrice); LocalDate maturityDate = bond.getUnadjustedEndDate(); double maturity = bond.getDayCount().relativeYearFraction(settlementDate, maturityDate); return (bond.getFixedRate() + (1d - cleanPrice) / maturity) / cleanPrice; } final Function<Double, Double> priceResidual = new Function<Double, Double>() { @Override public Double apply(final Double y) { return dirtyPriceFromYield(bond, settlementDate, y) - dirtyPrice; } }; double[] range = ROOT_BRACKETER.getBracketedPoints(priceResidual, 0.00, 0.20); double yield = ROOT_FINDER.getRoot(priceResidual, range[0], range[1]); return yield; }
case IGNORE: { try { double[] bracket = BRACKETER.getBracketedPoints( func, 0.8 * guess[i], 1.25 * guess[i], Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); double zeroRate = bracket[0] > bracket[1] ? double[] bracket = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, Double.POSITIVE_INFINITY); double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]); creditCurve = creditCurve.withParameter(i, zeroRate); guess[i] = Math.max(minValue, guess[i]); final double[] bracket = BRACKETER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, Double.POSITIVE_INFINITY); final double zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]); creditCurve = creditCurve.withParameter(i, zeroRate);
recoveryRates, refData); double[] bracket = BRACKER.getBracketedPoints(func, 0.8 * guess[i], 1.25 * guess[i], 0.0, Double.POSITIVE_INFINITY); double zeroRate = bracket[0] > bracket[1] ? ROOTFINDER.getRoot(func, bracket[1], bracket[0]) :