public static DiscountCurve LinearRateInterpol(FinancingId financing, DateTime[] pillars, double[] zcs, ITimeMeasure time) { if (pillars.Length != zcs.Length) throw new Exception("LinearRateDiscountProvider : Incompatible size"); var dates = time[pillars]; var zcRates = new double[pillars.Length]; if (DoubleUtils.EqualZero(dates[0])) { if (!DoubleUtils.MachineEquality(1.0, zcs[0])) throw new Exception("LinearRateInterpol : Discount for refDate must equal to 1.0 "); zcRates[0] = 0.0; } else { zcRates[0] = -Math.Log(zcs[0]) / dates[0]; } for (int i = 1; i < zcs.Length; i++) { zcRates[i] = -Math.Log(zcs[i]) / dates[i]; } return new DiscountCurveFromRate(financing, time, RrFunctions.LinearInterpolation(dates, zcRates)); }
public void TestEval() { var abs = new[] { 0.0, 0.5, 0.99, 2.5 }; var vals = new[] { 5.0, 5.4, 3.1, 1.0 }; const double leftSlope = 0.0; const double rightSlope = 0.98181; var stepFunc = RrFunctions.LinearInterpolation(abs, vals, leftSlope, rightSlope); foreach (var i in Enumerable.Range(0, abs.Length)) { Assert.AreEqual(stepFunc.Eval(abs[i]), vals[i]); if (i < abs.Length - 1) { var midPoint = 0.5 * (abs[i] + abs[i + 1]); Assert.AreEqual(stepFunc.Eval(midPoint), 0.5 * (vals[i] + vals[i + 1])); } } double leftExtrapolPoint = abs[0] - 10.0; Assert.AreEqual(stepFunc.Eval(leftExtrapolPoint), vals[0] + leftSlope * (leftExtrapolPoint - abs[0])); double rightExtrapolPoint = abs[abs.Length - 1] + 10.0; Assert.AreEqual(stepFunc.Eval(rightExtrapolPoint), vals[abs.Length - 1] + rightSlope * (rightExtrapolPoint - abs[abs.Length - 1])); }
public static RrFunction ZcRateCoeffFunction(double maturity, double meanReversion) { var expMat = Math.Exp(-meanReversion * maturity); if (DoubleUtils.MachineEquality(1.0, expMat)) { return(RrFunctions.Affine(1.0, -maturity)); } return((expMat / meanReversion) * RrFunctions.Exp(meanReversion) - (1.0 / meanReversion)); }
public void TestIntegralExp() { var exp = RrFunctions.Exp(0.1); var step = new StepFunction(new[] { 0.0, 5.0 }, new[] { 0.015, 0.010 }, 0.0); var f = exp * step; var integral = f.Integral(0.0); var testVal = integral.Eval(10.0); var expintegral = exp.Integral(0.0); var refVal = 0.015 * (expintegral.Eval(5.0) - expintegral.Eval(0.0)) + 0.01 * (expintegral.Eval(10.0) - expintegral.Eval(5.0)); Assert.IsTrue(DoubleUtils.Equality(testVal, refVal, 1.5 * DoubleUtils.MachineEpsilon)); }
private static RrFunction BuildXi(MapRawDatas <DateOrDuration, double> sigma, ITimeMeasure time) { var matVars = EnumerableUtils.For(0, sigma.Pillars.Length, i => { var mat = time[sigma.Pillars[i].ToDate(time.RefDate)]; var variance = sigma.Values[i] * sigma.Values[i] * mat; return(new { Mat = mat, Variance = variance }); }).OrderBy(t => t.Mat).ToArray(); if (!DoubleUtils.EqualZero(matVars.First().Mat)) { matVars = matVars.Concat(new[] { new { Mat = 0.0, Variance = 0.0 } }) .OrderBy(t => t.Mat).ToArray(); } var varianceFunc = RrFunctions.LinearInterpolation(matVars.Map(t => t.Mat), matVars.Map(t => t.Variance), 0.0, double.NaN); return(varianceFunc.Derivative()); }
private static double[][] VarSwapDeformation(Bergomi2FModel b2F, double[] fwdVolStart, double[] fwdVolEnd) { Debug.Assert(fwdVolStart.Length == fwdVolEnd.Length); var initCurve = b2F.Xi.Integral(0.0); var factor1 = (b2F.Xi * RrFunctions.Exp(-b2F.K1)).Integral(0.0); var factor2 = (b2F.Xi * RrFunctions.Exp(-b2F.K2)).Integral(0.0); var alpha = Alpha(b2F); return(EnumerableUtils.For(0, fwdVolStart.Length, i => { double volMatStart = fwdVolStart[i]; double volMatEnd = fwdVolEnd[i]; double initFwdVariance = initCurve.Eval(volMatEnd) - initCurve.Eval(volMatStart); double def1 = factor1.Eval(volMatEnd) - factor1.Eval(volMatStart); double def2 = factor2.Eval(volMatEnd) - factor2.Eval(volMatStart); return new[] { (1.0 - b2F.Theta) * def1, b2F.Theta * def2 }.Mult(b2F.Nu * alpha / initFwdVariance); })); }
public static RrFunction IntegratedCovariance(RrFunction instantCovariance, double meanReversion1, double meanReversion2, double startDate = 0.0) { var integratedExpCov = (instantCovariance * RrFunctions.Exp(meanReversion1 + meanReversion2)).Integral(startDate); return(integratedExpCov * RrFunctions.Exp(-(meanReversion1 + meanReversion2))); }
public static RrFunction IntegratedDrift(RrFunction instantDrift, double meanReversion, double startDate = 0.0) { var integratedExpDrift = (instantDrift * RrFunctions.Exp(meanReversion)).Integral(startDate); return(integratedExpDrift * RrFunctions.Exp(-meanReversion)); }
public double[] CalibrateVol(double[] maturities, double[] targetPrices, double[] strikes, double[] optionTypes) { Contract.Requires(EnumerableUtils.IsSorted(maturities)); Contract.Requires(maturities.Length == strikes.Length && strikes.Length == targetPrices.Length && targetPrices.Length == optionTypes.Length); double[] variances = new double[maturities.Length + 1]; double[] varPillars = new[] { 0.0 }.Concat(maturities).ToArray(); double[] calibVols = new double[maturities.Length]; for (int step = 0; step < maturities.Length; step++) { var maturity = maturities[step]; var strike = strikes[step]; var targetPrice = targetPrices[step]; var q = optionTypes[step]; //Proxy using Lehman Formula double proxyFwd, proxyDk; affineDivUtils.LehmanProxy(maturity, spot, out proxyFwd, out proxyDk); double lehmanTargetVol = BlackScholesOption.ImpliedVol(targetPrice, proxyFwd, strike + proxyDk, maturity, q); var pricer = new BsDivPrice(maturities[step], strikes[step], spot, affineDivUtils, quadPoints, quadWeights); Func <double, double> volToLehmanVolErr = v => { variances[1 + step] = v * v * maturity; var varFunc = RrFunctions.LinearInterpolation(varPillars, variances); Func <double, double> volFunc = t => Math.Sqrt(varFunc.Eval(t) / t); var price = pricer.Price(volFunc, q); return(BlackScholesOption.ImpliedVol(price, proxyFwd, strike + proxyDk, maturity, q) - lehmanTargetVol); };//TODO use a cache //Bracket & Solve double v1 = lehmanTargetVol; double v2; if (step == 0) { v2 = lehmanTargetVol - volToLehmanVolErr(lehmanTargetVol); } else { var volIfZeroVolOnStep = Math.Sqrt(calibVols[step - 1] * calibVols[step - 1] * maturities[step - 1] / maturities[step]); var minError = volToLehmanVolErr(volIfZeroVolOnStep); if (minError > 0.0) //saturation case { calibVols[step] = volIfZeroVolOnStep; variances[1 + step] = volIfZeroVolOnStep * volIfZeroVolOnStep * maturity; continue; } v2 = volIfZeroVolOnStep; } if (!RootUtils.Bracket(volToLehmanVolErr, v1, v2, out v1, out v2)) { throw new Exception("Failed to inverse vol"); } var impliedVol = RootUtils.Brenth(volToLehmanVolErr, v1, v2, 1.0e-10, 2.0 * DoubleUtils.MachineEpsilon, 10); calibVols[step] = impliedVol; variances[1 + step] = impliedVol * impliedVol * maturity; } return(calibVols); }