public void ConstVol() { var constVolA = 0.32; var constVolB = 0.16; var originDate = new DateTime(2017, 02, 21); var impliedSurfaceA = new ConstantVolSurface(originDate, constVolA) { AssetId = "A" }; var impliedSurfaceB = new ConstantVolSurface(originDate, constVolB) { AssetId = "B" }; var model = new AssetFxModel(originDate, null); model.AddVolSurface("A", impliedSurfaceA); model.AddVolSurface("B", impliedSurfaceB); var timesteps = Enumerable.Range(1, 4).Select(x => x / 4.0).ToArray(); var termCorrels = new[] { 0.9, 0.85, 0.8, 0.75 }; var correlVector = new CorrelationTimeVector("A", "B", termCorrels, timesteps); model.CorrelationMatrix = correlVector; var lc = model.LocalCorrelationRaw(timesteps); var lcVec = lc.Select(x => x[0][0]).ToArray(); for (var i = 0; i < termCorrels.Length; i++) { var expected = lcVec.Take(i + 1).Average(); Assert.Equal(expected, termCorrels[i], 8); } }
public void ConstLV() { var constVol = 0.32; var originDate = new DateTime(2017, 02, 21); var impliedSurface = new ConstantVolSurface(originDate, constVol); var strikes = new double[3][] { new double[] { 1, 2 }, new double[] { 1, 2 }, new double[] { 1, 2 } }; var timesteps = Enumerable.Range(0, 3).Select(x => (double)x / 3.0).ToArray(); Func <double, double> fwdCurve = (t => { return(1.5); }); var localVarianceGrid = impliedSurface.ComputeLocalVarianceOnGrid(strikes, timesteps, fwdCurve); for (var t = 0; t < localVarianceGrid.Length; t++) { var expectedLocalVariance = constVol * constVol; for (var k = 0; k < localVarianceGrid[t].Length; k++) { Assert.Equal(expectedLocalVariance, localVarianceGrid[t][k]); } } }
public void StrikeForPVFacts() { var evalDate = DateTime.Today; var avgStart = evalDate.AddDays(365); var avgEnd = avgStart.AddDays(32); var k = 110.0; var f = 100.0; var vol = 0.32; var rf = 0.0; var volSurface = new ConstantVolSurface(evalDate, vol); var pv = TurnbullWakeman.PV(f, 0, vol, k, evalDate, avgStart, avgEnd, rf, OptionType.C); var strike = TurnbullWakeman.StrikeForPV(pv, f, 0, volSurface, DateTime.Today, avgStart, avgEnd, rf, OptionType.C); Assert.Equal(k, strike, 10); var fixingDates = avgStart.CalendarDaysInPeriod(avgEnd).ToArray(); var fwds = fixingDates.Select(d => f).ToArray(); var sigmas = fixingDates.Select(d => vol).ToArray(); pv = TurnbullWakeman.PV(fwds, fixingDates, evalDate, avgEnd, sigmas, k, rf, OptionType.C); strike = TurnbullWakeman.StrikeForPV(pv, fwds, fixingDates, volSurface, evalDate, avgEnd, rf, OptionType.C); Assert.Equal(k, strike, 10); }
private AssetFxMCModel GetSut() { var buildDate = DateTime.Parse("2018-10-04"); var usd = TestProviderHelper.CurrencyProvider["USD"]; TestProviderHelper.CalendarProvider.Collection.TryGetCalendar("NYC", out var usdCal); var dfCurve = new IrCurve(new[] { buildDate, buildDate.AddDays(1000) }, new[] { 0.0, 0.0 }, buildDate, "disco", Interpolator1DType.Linear, usd, "DISCO"); var comCurve = new BasicPriceCurve(buildDate, new[] { buildDate, buildDate.AddDays(15), buildDate.AddDays(100) }, new[] { 100.0, 100.0, 100.0 }, PriceCurveType.NYMEX, TestProviderHelper.CurrencyProvider) { Name = "CL", AssetId = "CL" }; var comSurface = new ConstantVolSurface(buildDate, 0.32) { AssetId = "CL" }; var fModel = new FundingModel(buildDate, new Dictionary <string, IrCurve> { { "DISCO", dfCurve } }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxM = new FxMatrix(TestProviderHelper.CurrencyProvider); fxM.Init(usd, buildDate, new Dictionary <Currency, double>(), new List <FxPair>(), new Dictionary <Currency, string> { { usd, "DISCO" } }); fModel.SetupFx(fxM); var aModel = new AssetFxModel(buildDate, fModel); aModel.AddVolSurface("CL", comSurface); aModel.AddPriceCurve("CL", comCurve); var product = AssetProductFactory.CreateAsianOption(buildDate.AddDays(10), buildDate.AddDays(20), 101, "CL", OptionType.Call, usdCal, buildDate.AddDays(21), usd); product.TradeId = "waaah"; product.DiscountCurve = "DISCO"; var pfolio = new Portfolio { Instruments = new List <IInstrument> { product } }; var settings = new McSettings { Generator = RandomGeneratorType.MersenneTwister, NumberOfPaths = (int)System.Math.Pow(2, 13), NumberOfTimesteps = 1, ReportingCurrency = usd, Parallelize = false, CreditSettings = new CreditSettings { ExposureDates = new DateTime[] { buildDate.AddDays(5), buildDate.AddDays(20), buildDate.AddDays(22) } }, }; var sut = new AssetFxMCModel(buildDate, pfolio, aModel, settings, TestProviderHelper.CurrencyProvider, TestProviderHelper.FutureSettingsProvider, TestProviderHelper.CalendarProvider); return(sut); }
public void PremiumInterpolatorFacts() { var origin = new DateTime(2017, 02, 07); var expiry = origin.AddYears(1); var t = (expiry - origin).TotalDays / 365.0; var volAsset = 0.32; var fwd = 100.0; var surfaceAsset = new ConstantVolSurface(origin, volAsset); var premInterp = surfaceAsset.GeneratePremiumInterpolator(100, expiry, fwd, OptionType.P); var strike = fwd * 0.8; Assert.Equal(BlackFunctions.BlackPV(fwd, strike, 0.0, t, volAsset, OptionType.P), premInterp.Interpolate(strike), 2); }
public static object CreateConstantVolSurface( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Origin date")] DateTime OriginDate, [ExcelArgument(Description = "Volatility")] double Volatility) { return(ExcelHelper.Execute(_logger, () => { var surface = new ConstantVolSurface(OriginDate, Volatility); var cache = ContainerStores.GetObjectCache <ConstantVolSurface>(); cache.PutObject(ObjectName, new SessionItem <ConstantVolSurface> { Name = ObjectName, Value = surface }); return ObjectName + '¬' + cache.GetObject(ObjectName).Version; })); }
public void CompositeSmimleFacts_Trivial() { var origin = new DateTime(2017, 02, 07); var volAsset = 0.32; var volFx = 0.16; var correl = 0.4; var surfaceAsset = new ConstantVolSurface(origin, volAsset); var surfaceFx = new ConstantVolSurface(origin, volFx); var surfaceCompo = surfaceAsset.GenerateCompositeSmileBasic(surfaceFx, 100, origin.AddYears(1), 100, 10, correl); var expectedVol = Sqrt(volFx * volFx + volAsset * volAsset + 2.0 * correl * volAsset * volFx); Assert.Equal(expectedVol, surfaceCompo.Interpolate(100.0 * 10.0), 6); Assert.Equal(expectedVol, surfaceCompo.Interpolate(200.0 * 10.0), 6); Assert.Equal(expectedVol, surfaceCompo.Interpolate(0.0 * 10.0), 6); Assert.Equal(expectedVol, surfaceCompo.Interpolate(101 * 10.0), 6); }
private AssetFxModel GetModel() { var irCurveZar = new ConstantRateIrCurve(0.07, ValDate, "ZAR-IR", zar); var irCurveUsd = new ConstantRateIrCurve(0.02, ValDate, "USD-IR", zar); var fxMatrix = new FxMatrix(TestProviderHelper.CurrencyProvider); var fxPair = new FxPair() { Domestic = usd, Foreign = zar, PrimaryCalendar = TestProviderHelper.CalendarProvider.GetCalendar("ZAR"), SecondaryCalendar = TestProviderHelper.CalendarProvider.GetCalendar("USD"), SpotLag = new Frequency("2b") }; fxMatrix.Init(usd, ValDate, new Dictionary <Currency, double> { { zar, 20.0 } }, new List <FxPair> { fxPair }, new Dictionary <Currency, string> { { zar, "ZAR-IR" }, { usd, "USD-IR" } }); var fModel = new FundingModel(ValDate, new[] { irCurveUsd, irCurveZar }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); fModel.SetupFx(fxMatrix); var fxSurface = new ConstantVolSurface(ValDate, 0.16); fModel.VolSurfaces.Add("USD/ZAR", fxSurface); var crudeCurve = new ConstantPriceCurve(100, ValDate, TestProviderHelper.CurrencyProvider) { Name = "OIL", AssetId = "OIL", Currency = usd }; var crudeSurface = new ConstantVolSurface(ValDate, 0.32) { Name = "OIL", AssetId = "OIL", Currency = usd }; var aModel = new AssetFxModel(ValDate, fModel); aModel.AddPriceCurve("OIL", crudeCurve); aModel.AddVolSurface("OIL", crudeSurface); aModel.CorrelationMatrix = new CorrelationMatrix(new[] { "OIL" }, new[] { "USD/ZAR" }, new double[][] { new [] { 0.5 } }); return(aModel); }
public static object CreateConstantVolSurface( [ExcelArgument(Description = "Object name")] string ObjectName, [ExcelArgument(Description = "Asset Id")] string AssetId, [ExcelArgument(Description = "Origin date")] DateTime OriginDate, [ExcelArgument(Description = "Volatility")] double Volatility, [ExcelArgument(Description = "Currency - default USD")] object Currency) { return(ExcelHelper.Execute(_logger, () => { var ccyStr = Currency.OptionalExcel("USD"); ContainerStores.SessionContainer.GetService <ICalendarProvider>().Collection.TryGetCalendar(ccyStr, out var ccyCal); var surface = new ConstantVolSurface(OriginDate, Volatility) { Currency = ContainerStores.CurrencyProvider[ccyStr], Name = AssetId ?? ObjectName, AssetId = AssetId ?? ObjectName, }; return ExcelHelper.PushToCache <IVolSurface>(surface, ObjectName); })); }
public void BlackMC_PathsGenerated() { var origin = DateTime.Now.Date; using var engine = new PathEngine(2.IntPow(IsCoverageOnly ? 6 : 15)); engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() { UseNormalInverse = true, UseAnthithetic = false }); var volSurface = new ConstantVolSurface(origin, 0.32); var fwdCurve = new Func <double, double>(t => { return(900 + 100 * t); }); var asset = new BlackSingleAsset ( startDate: origin, expiryDate: origin.AddYears(1), volSurface: volSurface, forwardCurve: fwdCurve, nTimeSteps: IsCoverageOnly ? 1 : 10, name: "TestAsset" ); engine.AddPathProcess(asset); var payoff = new EuropeanPut("TestAsset", 900, origin.AddYears(1)); var payoff2 = new EuropeanCall("TestAsset", 0, origin.AddYears(1)); engine.AddPathProcess(payoff); engine.AddPathProcess(payoff2); engine.SetupFeatures(); engine.RunProcess(); var pv = payoff.AverageResult; var blackPv = BlackFunctions.BlackPV(1000, 900, 0, 1, 0.32, OptionType.P); if (!IsCoverageOnly) { Assert.True(System.Math.Abs(blackPv - pv) < 1.0); var fwd = payoff2.AverageResult; Assert.True(System.Math.Abs(fwdCurve(1) / fwd - 1.0) < 0.001); } }
private AssetFxModel GetModel() { var vol = new ConstantVolSurface(valDate, assetVol) { AssetId = assetId, Name = assetId }; var fwd = new ConstantPriceCurve(assetPrice, valDate, TestProviderHelper.CurrencyProvider) { AssetId = assetId, Name = assetId }; var ir = new FlatIrCurve(0.0, usd, "USD"); var fm = new FundingModel(valDate, new[] { ir }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var am = new AssetFxModel(valDate, fm); am.AddPriceCurve(assetId, fwd); am.AddVolSurface(assetId, vol); return(am); }
private AssetFxMCModel GetSut() { var buildDate = DateTime.Parse("2018-10-04"); var usd = TestProviderHelper.CurrencyProvider["USD"]; var zar = TestProviderHelper.CurrencyProvider["ZAR"]; TestProviderHelper.CalendarProvider.Collection.TryGetCalendar("NYC", out var usdCal); var pair = new FxPair() { Domestic = zar, Foreign = usd, PrimaryCalendar = usdCal, SpotLag = 2.Bd() }; var dfCurve = new IrCurve(new[] { buildDate, buildDate.AddDays(1000) }, new[] { 0.0, 0.0 }, buildDate, "disco", Interpolator1DType.Linear, usd, "DISCO"); var dates = new[] { buildDate, buildDate.AddDays(32), buildDate.AddDays(60), buildDate.AddDays(90) }; var times = dates.Select(d => buildDate.CalculateYearFraction(d, DayCountBasis.Act365F)).ToArray(); var vols = new[] { 0.32, 0.30, 0.29, 0.28 }; var comCurve = new PriceCurve(buildDate, dates, new[] { 100.0, 100.0, 100.0, 100.0 }, PriceCurveType.NYMEX, TestProviderHelper.CurrencyProvider) { Name = "CL", AssetId = "CL" }; var comSurface = new GridVolSurface(buildDate, new[] { 0.5 }, dates, vols.Select(x => new double[] { x }).ToArray(), StrikeType.ForwardDelta, Interpolator1DType.Linear, Interpolator1DType.LinearInVariance, DayCountBasis.Act365F) { AssetId = "CL" }; var fxSurface = new ConstantVolSurface(buildDate, 0.16) { AssetId = "USD/ZAR" }; var correlVector = new CorrelationTimeVector("CL", "USD/ZAR", _correls, times); var fModel = new FundingModel(buildDate, new Dictionary <string, IrCurve> { { "DISCO", dfCurve } }, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider); var fxM = new FxMatrix(TestProviderHelper.CurrencyProvider); fxM.Init(usd, buildDate, new Dictionary <Currency, double>() { { zar, 14.0 } }, new List <FxPair>() { pair }, new Dictionary <Currency, string> { { usd, "DISCO" }, { zar, "DISCO" } }); fModel.SetupFx(fxM); fModel.VolSurfaces.Add("ZAR/USD", fxSurface); fModel.VolSurfaces.Add("USD/ZAR", fxSurface); var aModel = new AssetFxModel(buildDate, fModel); aModel.AddVolSurface("CL", comSurface); aModel.AddPriceCurve("CL", comCurve); aModel.CorrelationMatrix = correlVector; var product1 = AssetProductFactory.CreateAsianOption(dates[1], dates[1], 1400, "CL", OptionType.Call, usdCal, dates[1], zar); product1.TradeId = "P1"; product1.DiscountCurve = "DISCO"; product1.FxConversionType = FxConversionType.AverageThenConvert; var product2 = AssetProductFactory.CreateAsianOption(dates[2], dates[2], 1400, "CL", OptionType.Call, usdCal, dates[2], zar); product2.TradeId = "P2"; product2.DiscountCurve = "DISCO"; product2.FxConversionType = FxConversionType.AverageThenConvert; var product3 = AssetProductFactory.CreateAsianOption(dates[3], dates[3], 1400, "CL", OptionType.Call, usdCal, dates[3], zar); product3.TradeId = "P3"; product3.DiscountCurve = "DISCO"; product3.FxConversionType = FxConversionType.AverageThenConvert; var pfolio = new Portfolio { Instruments = new List <IInstrument> { product1, product2, product3 } }; var settings = new McSettings { Generator = RandomGeneratorType.MersenneTwister, NumberOfPaths = (int)2.0.IntPow(15), NumberOfTimesteps = 1, ReportingCurrency = zar, Parallelize = false, LocalCorrelation = true, }; var sut = new AssetFxMCModel(buildDate, pfolio, aModel, settings, TestProviderHelper.CurrencyProvider, TestProviderHelper.FutureSettingsProvider, TestProviderHelper.CalendarProvider); return(sut); }