public void WorksWIthBackwardsStrikes() { //flat surface var origin = new DateTime(2017, 02, 07); var atms = new double[] { 0.3, 0.32, 0.34 }; var fwds = new double[] { 100, 102, 110 }; var maturities = new DateTime[] { new DateTime(2017, 04, 06), new DateTime(2017, 06, 07), new DateTime(2017, 08, 07) }; var wingDeltas = new[] { 0.1, 0.25 }; var riskies = new[] { new[] { 0.025, 0.015 }, new[] { 0.025, 0.015 }, new[] { 0.025, 0.015 } }; var flies = new[] { new[] { 0.0025, 0.0015 }, new[] { 0.0025, 0.0015 }, new[] { 0.0025, 0.0015 } }; var surface = new Qwack.Options.VolSurfaces.RiskyFlySurface( origin, atms, maturities, wingDeltas, riskies, flies, fwds, WingQuoteType.Simple, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear, Interpolator1DType.LinearInVariance); var wingDeltas2 = new[] { 0.25, 0.1 }; var riskies2 = new[] { new[] { 0.015, 0.025 }, new[] { 0.015, 0.025 }, new[] { 0.015, 0.025 } }; var flies2 = new[] { new[] { 0.0015, 0.0025 }, new[] { 0.0015, 0.0025 }, new[] { 0.0015, 0.0025 } }; var surface2 = new Qwack.Options.VolSurfaces.RiskyFlySurface( origin, atms, maturities, wingDeltas2, riskies2, flies2, fwds, WingQuoteType.Simple, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear, Interpolator1DType.LinearInVariance); Assert.Equal(surface.GetVolForDeltaStrike(0.5, maturities[1], fwds[1]), surface2.GetVolForDeltaStrike(0.5, maturities[1], fwds[1])); Assert.Equal(surface.GetVolForDeltaStrike(0.2, maturities[0], fwds[0]), surface2.GetVolForDeltaStrike(0.2, maturities[0], fwds[0])); Assert.Equal(surface.GetVolForDeltaStrike(0.1, maturities[2], fwds[2]), surface2.GetVolForDeltaStrike(0.1, maturities[2], fwds[2])); }
public static IVolSurface GenerateCompositeSurface(this IAssetFxModel model, string AssetId, string FxPair, int numSamples, double correlation, bool newMethod = false) { var inSurface = model.GetVolSurface(AssetId); var inFxSurface = model.FundingModel.GetVolSurface(FxPair); var priceCurve = model.GetPriceCurve(AssetId); var fxPair = model.FundingModel.FxMatrix.GetFxPair(FxPair); var compoInterpolators = new Dictionary <DateTime, IInterpolator1D>(); var fwds = new Dictionary <DateTime, double>(); var locker = new object(); ParallelUtils.Instance.Foreach(inSurface.Expiries, expiry => { var assetFwd = priceCurve.GetPriceForFixingDate(expiry); var fxFwd = model.FundingModel.GetFxRate(fxPair.SpotDate(expiry), FxPair); var compoSmile = newMethod ? GenerateCompositeSmile(inSurface, inFxSurface, numSamples, expiry, assetFwd, fxFwd, correlation, true) : GenerateCompositeSmileBasic(inSurface, inFxSurface, numSamples, expiry, assetFwd, fxFwd, correlation, true); lock (locker) { compoInterpolators.Add(expiry, compoSmile); fwds.Add(expiry, assetFwd * fxFwd); } }).Wait(); var ATMs = compoInterpolators.OrderBy(x => x.Key).Select(x => x.Value.Interpolate(0.5)).ToArray(); var wingDeltas = new[] { 0.25, 0.1 }; var riskies = compoInterpolators.OrderBy(x => x.Key).Select(x => wingDeltas.Select(w => x.Value.Interpolate(1 - w) - x.Value.Interpolate(w)).ToArray()).ToArray(); var flies = compoInterpolators.OrderBy(x => x.Key).Select(x => wingDeltas.Select(w => (x.Value.Interpolate(1 - w) + x.Value.Interpolate(w)) / 2.0 - x.Value.Interpolate(0.5)).ToArray()).ToArray(); var outSurface = new RiskyFlySurface(model.BuildDate, ATMs, inSurface.Expiries, wingDeltas, riskies, flies, fwds.OrderBy(x => x.Key).Select(x => x.Value).ToArray(), WingQuoteType.Simple, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.GaussianKernel, Interpolator1DType.LinearInVariance); return(outSurface); }