public int SabrFunc(double[] p, double[] dy, IList <double>[] dvec, object vars) { var b = _initBeta; // beta = 0.5 var r = p[0]; // rho var nv = p[1]; // nu var a = _estimateAlpha // alpha ? p[2] : FindAlpha(b, r, nv, MaturityInYears, _spotPrice, AtmVol); CustomUserVariable v = (CustomUserVariable)vars; double[] x, y, ey; x = v.X; y = v.Y; ey = v.Ey; for (var i = 0; i < dy.Length; i++) { var estVol = SabrVolSurface.SABRVolFineTune(a, b, r, nv, _spotPrice, _strikes[i], MaturityInYears, _useFineTune); dy[i] = (Math.Abs(r) > 1 || nv < 0) ? 1e100 : estVol - _marketVols[i]; //Impose the constraint that -1<=rho <=1 and v>0 } return(0); }
public SabrCoeffOptimizer( double maturity, double spotPrice, double atmVol, IList <double> strikes, IList <double> marketVols, bool estimateAlpha, bool useFineTune, double initAlpha = 0.3, double initBeta = 0.5, double initNu = 0.3, double initRho = 0.3) { MaturityInYears = maturity; _spotPrice = spotPrice; AtmVol = atmVol; _strikes = strikes; _marketVols = marketVols; _estimateAlpha = estimateAlpha; _useFineTune = useFineTune; _initBeta = initBeta; if (strikes.Count != marketVols.Count) { throw new PricingLibraryException("strikes and marketVols should have same number of elements!"); } double bestAlpha, bestBeta, bestRho, bestNu; var nDataPoints = _marketVols.Count(); double[] ey = new double[nDataPoints]; for (int i = 0; i < nDataPoints; ++i) { ey[i] = 0.1; // error for data points, we do not need to use this } const int nParams = 3; mp_par[] pars = new mp_par[nParams] // parameter constraints { new mp_par(), // no constraint new mp_par(), new mp_par() }; if (!estimateAlpha) // fix alpha { pars[2] = new mp_par() { isFixed = 1 }; } CustomUserVariable v = new CustomUserVariable() { X = _strikes.ToArray(), Y = _marketVols.ToArray(), Ey = ey }; double[] p = new double[nParams] { initRho, initNu, initAlpha }; mp_result result = new mp_result(nParams); int status = MPFit.Solve(SabrFunc, nDataPoints, nParams, p, pars, null, v, ref result); bestRho = p[0]; bestNu = p[1]; bestAlpha = estimateAlpha ? p[2] : FindAlpha(_initBeta, p[0], p[1], MaturityInYears, _spotPrice, AtmVol); bestBeta = _initBeta; Result = new SabrCoeffOptimizerResult(MaturityInYears, bestAlpha, bestBeta, bestRho, bestNu); }