public void SABRSurfaceRRBF() { //flat surface var origin = new DateTime(2017, 02, 07); var expiry = origin.AddYears(1); var t = (expiry - origin).TotalDays / 365.0; var fwd = 1.5; var vol = 0.32; var rr = new[] { new[] { 0.02, 0.03 } }; var bf = new[] { new[] { 0.005, 0.007 } }; Func <double, double> fwdCurve = (tt => { return(fwd); }); var surface = new SabrVolSurface(origin, new[] { vol }, new[] { expiry }, new[] { 0.25, 0.1 }, rr, bf, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Math.Interpolation.Interpolator1DType.Linear); var gSurface = new RiskyFlySurface(origin, new[] { vol }, new[] { expiry }, new[] { 0.25, 0.1 }, rr, bf, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Math.Interpolation.Interpolator1DType.Linear, Math.Interpolation.Interpolator1DType.Linear); var atmK = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, 0.5, 0.0, t, vol); Assert.Equal(vol, surface.GetVolForAbsoluteStrike(atmK, expiry, fwd), 2); var v25c = gSurface.GetVolForDeltaStrike(0.75, expiry, fwd); var v25p = gSurface.GetVolForDeltaStrike(0.25, expiry, fwd); var k25c = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, 0.25, 0.0, t, v25c); var k25p = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -0.25, 0.0, t, v25p); var t25c = surface.GetVolForAbsoluteStrike(k25c, expiry, fwd); var t25p = surface.GetVolForAbsoluteStrike(k25p, expiry, fwd); Assert.Equal(rr[0][0], t25c - t25p, 2); }
public void SABRSurfaceFlat() { //flat surface var origin = new DateTime(2017, 02, 07); var strikes = new double[][] { new[] { 1.4, 1.6 }, new[] { 1.4, 1.6 } }; var maturities = new DateTime[] { new DateTime(2018, 02, 07), new DateTime(2019, 02, 07) }; var fwd = 1.5; Func <double, double> fwdCurve = (t => { return(fwd); }); var vols = new double[][] { new double[] { 0.32, 0.32 }, new double[] { 0.32, 0.32 } }; var surface = new SabrVolSurface( origin, strikes, maturities, vols, fwdCurve, Math.Interpolation.Interpolator1DType.Linear, Dates.DayCountBasis.Act_365F); Assert.Equal(vols[0][0], surface.GetVolForAbsoluteStrike(1.5, origin.AddDays(33), fwd), 2); Assert.Equal(vols[0][0], surface.GetVolForDeltaStrike(-0.3, origin.AddDays(303), fwd), 2); Assert.Equal(vols[0][0], surface.GetVolForAbsoluteStrike(3, 0.777, fwd), 2); Assert.Equal(vols[0][0], surface.GetVolForDeltaStrike(0.9, 0.123, fwd), 2); }
public static object CreateSABRVolSurfaceFromRiskyFly( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Asset Id")] string AssetId, [ExcelArgument(Description = "Origin date")] DateTime OriginDate, [ExcelArgument(Description = "Wing deltas")] double[] WingDeltas, [ExcelArgument(Description = "Expiries")] double[] Expiries, [ExcelArgument(Description = "ATM Volatilities")] double[] ATMVols, [ExcelArgument(Description = "Risk Reversal quotes")] double[,] Riskies, [ExcelArgument(Description = "Butterfly quotes")] double[,] Flies, [ExcelArgument(Description = "Forwards or price curve object")] object FwdsOrCurve, [ExcelArgument(Description = "ATM vol type - default zero-delta straddle")] object ATMType, [ExcelArgument(Description = "Wing quote type - Simple or Market")] object WingType, [ExcelArgument(Description = "Time Interpolation - default LinearInVariance")] object TimeInterpolation, [ExcelArgument(Description = "Pillar labels (optional)")] object PillarLabels, [ExcelArgument(Description = "Currency - default USD")] object Currency) { return(ExcelHelper.Execute(_logger, () => { var labels = (PillarLabels is ExcelMissing) ? null : ((object[, ])PillarLabels).ObjectRangeToVector <string>(); var ccyStr = Currency.OptionalExcel("USD"); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ccyStr, out var ccyCal); var atmType = ATMType.OptionalExcel("ZeroDeltaStraddle"); var wingType = WingType.OptionalExcel("Simple"); var timeInterpType = TimeInterpolation.OptionalExcel("LinearInVariance"); var expiries = ExcelHelper.ToDateTimeArray(Expiries); var rr = Riskies.SquareToJagged <double>(); var bf = Flies.SquareToJagged <double>(); if (!Enum.TryParse(wingType, out WingQuoteType wType)) { return $"Could not parse wing quote type - {wingType}"; } if (!Enum.TryParse(atmType, out AtmVolType aType)) { return $"Could not parse atm quote type - {atmType}"; } if (!Enum.TryParse(timeInterpType, out Interpolator1DType tiType)) { return $"Could not parse time interpolator type - {timeInterpType}"; } double[] fwds = null; if (FwdsOrCurve is double) { fwds = new double[] { (double)FwdsOrCurve }; } else if (FwdsOrCurve is string) { if (!ContainerStores.GetObjectCache <IPriceCurve>().TryGetObject(FwdsOrCurve as string, out var curve)) { return $"Could not find fwd curve with name - {FwdsOrCurve as string}"; } fwds = expiries.Select(e => curve.Value.GetPriceForDate(e)).ToArray(); } else { fwds = ((object[, ])FwdsOrCurve).ObjectRangeToVector <double>(); } var surface = new SabrVolSurface(OriginDate, ATMVols, expiries, WingDeltas, rr, bf, fwds, wType, aType, tiType, labels) { Currency = ContainerStores.CurrencyProvider[ccyStr], Name = AssetId ?? ObjectName, AssetId = AssetId ?? ObjectName, }; return ExcelHelper.PushToCache <IVolSurface>(surface, ObjectName); })); }