public SABRInterpolationImpl( final Array vx, final Array vy, final @Time double t, final double forward, final double alpha, final double beta, final double nu, final double rho, final boolean alphaIsFixed, final boolean betaIsFixed, final boolean nuIsFixed, final boolean rhoIsFixed, final boolean vegaWeighted, final EndCriteria endCriteria, final OptimizationMethod optMethod) { super(vx, vy); itsCoeffs = new SABRCoeffHolder( t, forward, alpha, beta, nu, rho, alphaIsFixed, betaIsFixed, nuIsFixed, rhoIsFixed); endCriteria_ = endCriteria; optMethod_ = optMethod; forward_ = forward; vegaWeighted_ = vegaWeighted; // if no optimization method or endCriteria is provided, we provide // one if (optMethod_ != null) { // optMethod_ = boost::shared_ptr<OptimizationMethod>(new // LevenbergMarquardt(1e-8, 1e-8, 1e-8)); optMethod_ = new Simplex(0.01); } if (endCriteria_ != null) { endCriteria_ = new EndCriteria(60000, 100, 1e-8, 1e-8, 1e-8); } itsCoeffs.weights_ = new Array(vx.size()); for (int i = 0; i < itsCoeffs.weights_.size(); i++) { itsCoeffs.weights_.set(i, 1.0 / vx.size()); } }
@Override public void update() { // forward_ might have changed QL.require( forward_ > 0.0, "at the money forward rate must be " + "positive: " + forward_ + " not allowed"); // we should also check that y contains positive values only // we must update weights if it is vegaWeighted if (vegaWeighted_) { // itsCoeffs.weights_.clear(); double weightsSum = 0.0; for (int i = 0; i < vx.size(); i++) { final double x = vx.get(i); final double y = vy.get(i); final double stdDev = Math.sqrt(y * y * itsCoeffs.t_); itsCoeffs.weights_.set(i, BlackFormula.blackFormulaStdDevDerivative(x, forward_, stdDev)); weightsSum += itsCoeffs.weights_.get(i); } // weight normalization for (int i = 0; i < itsCoeffs.weights_.size(); i++) { itsCoeffs.weights_.set(i, itsCoeffs.weights_.get(i) / weightsSum); } } // there is nothing to optimize if (itsCoeffs.alphaIsFixed_ && itsCoeffs.betaIsFixed_ && itsCoeffs.nuIsFixed_ && itsCoeffs.rhoIsFixed_) { itsCoeffs.error_ = interpolationError(); itsCoeffs.maxError_ = interpolationMaxError(); itsCoeffs.SABREndCriteria_ = EndCriteria.Type.None; return; } else { final SABRError costFunction = new SABRError(this); transformation_ = new SabrParametersTransformation(); final Array guess = new Array(4); guess.set(0, itsCoeffs.alpha_); guess.set(1, itsCoeffs.beta_); guess.set(2, itsCoeffs.nu_); guess.set(3, itsCoeffs.rho_); final boolean[] parameterAreFixed = new boolean[4]; parameterAreFixed[0] = itsCoeffs.alphaIsFixed_; parameterAreFixed[1] = itsCoeffs.betaIsFixed_; parameterAreFixed[2] = itsCoeffs.nuIsFixed_; parameterAreFixed[3] = itsCoeffs.rhoIsFixed_; final Array inversedTransformatedGuess = new Array(transformation_.inverse(guess)); final ProjectedCostFunction constrainedSABRError = new ProjectedCostFunction(costFunction, inversedTransformatedGuess, parameterAreFixed); final Array projectedGuess = new Array(constrainedSABRError.project(inversedTransformatedGuess)); final NoConstraint constraint = new NoConstraint(); final Problem problem = new Problem(constrainedSABRError, constraint, projectedGuess); itsCoeffs.SABREndCriteria_ = optMethod_.minimize(problem, endCriteria_); final Array projectedResult = new Array(problem.currentValue()); final Array transfResult = new Array(constrainedSABRError.include(projectedResult)); final Array result = transformation_.direct(transfResult); itsCoeffs.alpha_ = result.get(0); itsCoeffs.beta_ = result.get(1); itsCoeffs.nu_ = result.get(2); itsCoeffs.rho_ = result.get(3); } itsCoeffs.error_ = interpolationError(); itsCoeffs.maxError_ = interpolationMaxError(); }