/// <summary> /// Constructs smile model fitter from forward, strikes, time to expiry, implied volatilities and error values. /// <para> /// {@code strikes}, {@code impliedVols} and {@code error} should be the same length and ordered coherently. /// /// </para> /// </summary> /// <param name="forward"> the forward value of the underlying </param> /// <param name="strikes"> the ordered values of strikes </param> /// <param name="timeToExpiry"> the time-to-expiry </param> /// <param name="impliedVols"> the market implied volatilities </param> /// <param name="error"> the 'measurement' error to apply to the market volatility of a particular option TODO: Review should this be part of EuropeanOptionMarketData? </param> /// <param name="model"> the volatility function provider </param> public SmileModelFitter(double forward, DoubleArray strikes, double timeToExpiry, DoubleArray impliedVols, DoubleArray error, VolatilityFunctionProvider <T> model) { ArgChecker.notNull(strikes, "strikes"); ArgChecker.notNull(impliedVols, "implied vols"); ArgChecker.notNull(error, "errors"); ArgChecker.notNull(model, "model"); int n = strikes.size(); ArgChecker.isTrue(n == impliedVols.size(), "vols not the same length as strikes"); ArgChecker.isTrue(n == error.size(), "errors not the same length as strikes"); this.marketValues = impliedVols; this.errors = error; this.model = model; this.volFunc = (DoubleArray x) => { T data = toSmileModelData(x); double[] res = new double[n]; for (int i = 0; i < n; ++i) { res[i] = model.volatility(forward, strikes.get(i), timeToExpiry, data); } return(DoubleArray.copyOf(res)); }; this.volAdjointFunc = (DoubleArray x) => { T data = toSmileModelData(x); double[][] resAdj = new double[n][]; for (int i = 0; i < n; ++i) { DoubleArray deriv = model.volatilityAdjoint(forward, strikes.get(i), timeToExpiry, data).Derivatives; resAdj[i] = deriv.subArray(2).toArrayUnsafe(); } return(DoubleMatrix.copyOf(resAdj)); }; }
internal abstract SmileModelFitter <T> getFitter(double forward, double[] strikes, double timeToExpiry, double[] impliedVols, double[] error, VolatilityFunctionProvider <T> model);
/// <summary> /// Constructs SABR model fitter from forward, strikes, time to expiry, implied volatilities and error values. /// <para> /// {@code strikes}, {@code impliedVols} and {@code error} should be the same length and ordered coherently. /// /// </para> /// </summary> /// <param name="forward"> the forward value of the underlying </param> /// <param name="strikes"> the ordered values of strikes </param> /// <param name="timeToExpiry"> the time-to-expiry </param> /// <param name="impliedVols"> the market implied volatilities </param> /// <param name="error"> the 'measurement' error to apply to the market volatility of a particular option </param> /// <param name="model"> the volatility function provider </param> public SabrModelFitter(double forward, DoubleArray strikes, double timeToExpiry, DoubleArray impliedVols, DoubleArray error, VolatilityFunctionProvider <SabrFormulaData> model) : base(forward, strikes, timeToExpiry, impliedVols, error, model) { }
internal override SmileModelFitter <SabrFormulaData> getFitter(double forward, double[] strikes, double timeToExpiry, double[] impliedVols, double[] error, VolatilityFunctionProvider <SabrFormulaData> model) { return(new SabrModelFitter(forward, DoubleArray.copyOf(strikes), timeToExpiry, DoubleArray.copyOf(impliedVols), DoubleArray.copyOf(error), model)); }