public void PathsGenerated() { var vol = 0.32; using var engine = new PathEngine(IsCoverageOnly ? 2.IntPow(6) : 2 << 10); engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() { UseNormalInverse = true }); var asset2 = new ConstantVolSingleAsset ( startDate: DateTime.Now.Date, expiry: DateTime.Now.Date.AddYears(1), vol: vol, spot: 500, drift: 0.00, numberOfSteps: IsCoverageOnly ? 1 : 365, name: "TestAsset2" ); engine.AddPathProcess(asset2); var payoff = new EuropeanPut("TestAsset2", 500, DateTime.Now.Date.AddYears(1)); engine.AddPathProcess(payoff); engine.SetupFeatures(); engine.RunProcess(); var pv = payoff.AverageResult; var blackPv = BlackFunctions.BlackPV(500, 500, 0, 1, vol, OptionType.P); if (!IsCoverageOnly) { Assert.Equal(blackPv, pv, 0); } }
public void TestBlockGeneration() { using var engine = new PathEngine(4 << 2); engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64()); engine.AddPathProcess(new FakeAssetProcess("TestUnderlying", numberOfDimensions: 2, timesteps: 10)); engine.SetupFeatures(); engine.RunProcess(); }
public void LVMC_PathsGenerated() { var origin = DateTime.Now.Date; using var engine = new PathEngine(2.IntPow(IsCoverageOnly ? 6 : 12)) { Parallelize = false }; engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() { UseNormalInverse = true, UseAnthithetic = true }); var tenorsStr = new[] { "1m", "2m", "3m", "6m" }; var tenors = tenorsStr.Select(x => new Frequency(x)); var expiries = tenors.Select(t => origin.AddPeriod(RollType.F, new Calendar(), t)).ToArray(); var deltaKs = new[] { 0.1, 0.25, 0.5, 0.75, 0.9 }; var smileVols = new[] { 0.32, 0.3, 0.29, 0.3, 0.32 }; var vols = Enumerable.Repeat(smileVols, expiries.Length).ToArray(); var tExp = (origin.AddMonths(6) - origin).TotalDays / 365.0; var volSurface = new GridVolSurface(origin, deltaKs, expiries, vols, StrikeType.ForwardDelta, Interpolator1DType.GaussianKernel, Interpolator1DType.LinearInVariance, DayCountBasis.Act365F); var fwdCurve = new Func <double, double>(t => { return(900 + 100 * t / tExp); }); var asset = new LVSingleAsset ( startDate: origin, expiryDate: origin.AddMonths(6), volSurface: volSurface, forwardCurve: fwdCurve, nTimeSteps: IsCoverageOnly ? 3 : 100, name: "TestAsset" ); engine.AddPathProcess(asset); var payoff = new EuropeanPut("TestAsset", 900, origin.AddMonths(6)); var payoff2 = new EuropeanCall("TestAsset", 0, origin.AddMonths(6)); engine.AddPathProcess(payoff); engine.AddPathProcess(payoff2); engine.SetupFeatures(); engine.RunProcess(); var pv = payoff.AverageResult; var blackVol = volSurface.GetVolForAbsoluteStrike(900, origin.AddMonths(6), fwdCurve(tExp)); var blackPv = BlackFunctions.BlackPV(fwdCurve(tExp), 900, 0, tExp, blackVol, OptionType.P); if (!IsCoverageOnly) { Assert.True(System.Math.Abs(blackPv / pv - 1.0) < 0.02); var fwd = payoff2.AverageResult; Assert.True(System.Math.Abs(fwdCurve(tExp) / fwd - 1.0) < 0.005); } }
public void TestBlockGenerationSobolFlipShifted() { var engine = new PathEngine(64); var directionNumbers = new Random.Sobol.SobolDirectionNumbers("SobolDirectionNumbers.txt"); engine.AddPathProcess(new Random.Sobol.SobolFlipShiftedPathGenerator(true, directionNumbers)); engine.AddPathProcess(new FakeAssetProcess("TestUnderlying", numberOfDimensions: 2, timesteps: 10)); engine.SetupFeatures(); engine.RunProcess(); }
public void RandsWithNoVectors() { var Paths = (int)System.Math.Pow(2, 14); using var engine = new PathEngine(Paths); engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64()); engine.AddPathProcess(new FakeAssetProcess("TestUnderlying", numberOfDimensions: 2, timesteps: 100)); engine.SetupFeatures(); engine.RunProcess(); }
public void LVMC_PathsGenerated() { var origin = DateTime.Now.Date; var engine = new PathEngine(2.IntPow(17)); //engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() //{ // UseNormalInverse = true, // UseAnthithetic = false //}); engine.AddPathProcess(new Random.Sobol.SobolShiftedPathGenerator(new Random.Sobol.SobolDirectionNumbers(s_directionNumbers), 0) { UseNormalInverse = true }); var tenorsStr = new[] { "1m", "2m", "3m", "6m", "9m", "1y" }; var tenors = tenorsStr.Select(x => new Frequency(x)); var expiries = tenors.Select(t => origin.AddPeriod(RollType.F, new Calendar(), t)).ToArray(); var deltaKs = new[] { -0.1, -0.25, -0.5, -0.75, -0.9 }; var smileVols = new[] { 0.32, 0.3, 0.29, 0.3, 0.32 }; var vols = Enumerable.Repeat(smileVols, expiries.Length).ToArray(); var volSurface = new GridVolSurface(origin, deltaKs, expiries, vols, Core.Basic.StrikeType.ForwardDelta, Interpolator1DType.LinearFlatExtrap, Interpolator1DType.LinearInVariance, DayCountBasis.Act365F); var fwdCurve = new Func <double, double>(t => { return(900 + 100 * t); }); var asset = new LVSingleAsset ( startDate: origin, expiryDate: origin.AddYears(1), volSurface: volSurface, forwardCurve: fwdCurve, nTimeSteps: 365, 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 blackVol = volSurface.GetVolForAbsoluteStrike(900, origin.AddYears(1), fwdCurve(1.0)); var blackPv = BlackFunctions.BlackPV(1000, 900, 0, 1, blackVol, OptionType.P); Assert.Equal(blackPv, pv, 0); var fwd = payoff2.AverageResult; Assert.True(System.Math.Abs(fwdCurve(1) / fwd - 1.0) < 0.001); //var output = new OutputPathsToImage(engine,2000,1000); }
public void PathsGenerated() { var engine = new PathEngine(2 << 8); engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() { UseNormalInverse = true }); var asset = new ConstantVolSingleAsset ( startDate: DateTime.Now.Date, expiry: DateTime.Now.Date.AddYears(1), vol: 0.30, spot: 1000, drift: 0.00, numberOfSteps: 100, name: "TestAsset" ); engine.AddPathProcess(asset); var asset2 = new ConstantVolSingleAsset ( startDate: DateTime.Now.Date, expiry: DateTime.Now.Date.AddYears(1), vol: 0.30, spot: 500, drift: 0.00, numberOfSteps: 25, name: "TestAsset2" ); engine.AddPathProcess(asset2); var payoff = new EuropeanPut("TestAsset2", 500, DateTime.Now.Date.AddYears(1)); engine.AddPathProcess(payoff); engine.SetupFeatures(); engine.RunProcess(); var output = new OutputPathsToImage(engine, 2000, 1000); }
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); } }
public void CompositeSmimleFacts_LocalVol() { var origin = new DateTime(2017, 02, 07); var expiry = origin.AddMonths(2); var tExp = origin.CalculateYearFraction(expiry, DayCountBasis.Act365F); var fwdCurveAsset = new Func <double, double>(t => { return(100); }); var fwdCurveFx = new Func <double, double>(t => { return(15); }); var volAsset = 0.32; var volFx = 0.16; var correl = 0.25; var surfaceAsset = new RiskyFlySurface(origin, new[] { volAsset }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.02, 0.03 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.GaussianKernel, Interpolator1DType.Linear) { FlatDeltaSmileInExtreme = true }; var surfaceFx = new RiskyFlySurface(origin, new[] { volFx }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.015, 0.025 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 0.1 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.GaussianKernel, Interpolator1DType.Linear) { FlatDeltaSmileInExtreme = true }; //var surfaceAsset = new SabrVolSurface(origin, new[] { volAsset }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.02, 0.03 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); //var surfaceFx = new SabrVolSurface(origin, new[] { volFx }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.015, 0.025 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 0.1 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); //var surfaceAsset = new SVIVolSurface(origin, new[] { volAsset }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.02, 0.03 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); //var surfaceFx = new SVIVolSurface(origin, new[] { volFx }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.015, 0.025 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 0.1 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); var invFx = new InverseFxSurface("inv", surfaceFx, TestProviderHelper.CurrencyProvider); var surfaceCompo = surfaceAsset.GenerateCompositeSmile(invFx, 200, expiry, 100, 1.0 / 15, correl); //setup MC using var engine = new PathEngine(2.IntPow(IsCoverageOnly?5:15)); engine.AddPathProcess( new Qwack.Random.MersenneTwister.MersenneTwister64 { UseNormalInverse = true }); var correlMatrix = new double[][] { new double[] { 1.0, correl }, new double[] { correl, 1.0 }, }; engine.AddPathProcess(new Cholesky(correlMatrix)); var asset1 = new TurboSkewSingleAsset ( startDate: origin, expiryDate: expiry, volSurface: surfaceAsset, forwardCurve: fwdCurveAsset, nTimeSteps: 1, name: "Asset" ); var asset2 = new TurboSkewSingleAsset ( startDate: origin, expiryDate: expiry, volSurface: surfaceFx, forwardCurve: fwdCurveFx, nTimeSteps: 1, name: "USD/ZAR" ); engine.AddPathProcess(asset1); engine.AddPathProcess(asset2); var strike = 1500; var product = new EuropeanOption { AssetId = "Asset", CallPut = OptionType.C, ExpiryDate = expiry, PaymentCurrency = TestProviderHelper.CurrencyProvider["ZAR"], PaymentDate = expiry, Notional = 1.0, SpotLag = new Frequency("0b"), Strike = strike, FxConversionType = FxConversionType.ConvertThenAverage }; var productAsset = new EuropeanOption { AssetId = "Asset", CallPut = OptionType.C, ExpiryDate = expiry, PaymentCurrency = TestProviderHelper.CurrencyProvider["USD"], PaymentDate = expiry, Notional = 1.0, SpotLag = new Frequency("0b"), Strike = 100, FxConversionType = FxConversionType.None }; var productFx = new EuropeanOption { AssetId = "USD/ZAR", CallPut = OptionType.C, ExpiryDate = expiry, PaymentCurrency = TestProviderHelper.CurrencyProvider["ZAR"], PaymentDate = expiry, Notional = 1.0, SpotLag = new Frequency("0b"), Strike = 0.1, FxConversionType = FxConversionType.None }; var pathProduct = new AssetPathPayoff(product, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider, TestProviderHelper.CurrencyProvider["ZAR"]); var pathProductAsset = new AssetPathPayoff(productAsset, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider, TestProviderHelper.CurrencyProvider["ZAR"]); var pathProductFx = new AssetPathPayoff(productFx, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider, TestProviderHelper.CurrencyProvider["ZAR"]); engine.AddPathProcess(pathProduct); engine.AddPathProcess(pathProductAsset); engine.AddPathProcess(pathProductFx); engine.SetupFeatures(); engine.RunProcess(); var q = pathProduct.ResultsByPath; var qq = q.Average(); var productIv = BlackFunctions.BlackImpliedVol(1500, strike, 0.0, tExp, pathProduct.AverageResult, OptionType.C); var productAssetIv = BlackFunctions.BlackImpliedVol(100, 100, 0.0, tExp, pathProductAsset.AverageResult, OptionType.C); var productFxIv = BlackFunctions.BlackImpliedVol(10, 10, 0.0, tExp, pathProductFx.AverageResult, OptionType.C); Assert.True(Abs(productIv - surfaceCompo.Interpolate(strike)) < 0.01); }
public void LVMCDualPathsGenerated(double correlation) { var origin = DateTime.Now.Date; using var engine = new PathEngine(2.IntPow(IsCoverageOnly ? 6 : 8)) { Parallelize = false }; engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() { UseNormalInverse = true, UseAnthithetic = false, }); engine.IncrementDepth(); var correlMatrix = new double[][] { new double[] { 1.0, correlation }, new double[] { correlation, 1.0 }, }; engine.AddPathProcess(new Cholesky(correlMatrix)); engine.IncrementDepth(); var tenorsStr = new[] { "1m", "2m", "3m", "6m" }; var tenors = tenorsStr.Select(x => new Frequency(x)); var expiries = tenors.Select(t => origin.AddPeriod(RollType.F, new Calendar(), t)).ToArray(); var deltaKs = new[] { -0.1, -0.25, -0.5, -0.75, -0.9 }; var smileVols = new[] { 0.32, 0.3, 0.29, 0.3, 0.32 }; var vols = Enumerable.Repeat(smileVols, expiries.Length).ToArray(); var volSurface = new GridVolSurface(origin, deltaKs, expiries, vols, StrikeType.ForwardDelta, Interpolator1DType.GaussianKernel, Interpolator1DType.LinearInVariance, DayCountBasis.Act365F); var fwdCurve1 = new Func <double, double>(t => { return(1000); }); var asset1 = new LVSingleAsset ( startDate: origin, expiryDate: origin.AddMonths(6), volSurface: volSurface, forwardCurve: fwdCurve1, nTimeSteps: IsCoverageOnly ? 3 : 100, name: "TestAsset1" ); var fwdCurve2 = new Func <double, double>(t => { return(1000); }); var asset2 = new LVSingleAsset ( startDate: origin, expiryDate: origin.AddMonths(6), volSurface: volSurface, forwardCurve: fwdCurve2, nTimeSteps: IsCoverageOnly ? 3 : 100, name: "TestAsset2" ); engine.AddPathProcess(asset1); engine.AddPathProcess(asset2); engine.IncrementDepth(); var correl = new Correlation("TestAsset1", "TestAsset2"); engine.AddPathProcess(correl); engine.SetupFeatures(); engine.RunProcess(); var corr = correl.AverageResult; var errCorr = correl.ResultStdError; if (!IsCoverageOnly) { Assert.Equal(correlation, corr, 1); } }
public void LVMC_TriplePathsGenerated(double correlationAB, double correlationAC, double correlationBC) { var origin = DateTime.Now.Date; var engine = new PathEngine(2.IntPow(15)); engine.AddPathProcess(new Random.MersenneTwister.MersenneTwister64() { UseNormalInverse = true, UseAnthithetic = false }); var correlMatrix = new double[][] { new double[] { 1.0, correlationAB, correlationAC }, new double[] { correlationAB, 1.0, correlationBC }, new double[] { correlationAC, correlationBC, 1.0 }, }; engine.AddPathProcess(new Cholesky(correlMatrix)); var tenorsStr = new[] { "1m", "2m", "3m", "6m", "9m", "1y" }; var tenors = tenorsStr.Select(x => new Frequency(x)); var expiries = tenors.Select(t => origin.AddPeriod(RollType.F, new Calendar(), t)).ToArray(); var deltaKs = new[] { -0.1, -0.25, -0.5, -0.75, -0.9 }; var smileVols = new[] { 0.32, 0.3, 0.29, 0.3, 0.32 }; var vols = Enumerable.Repeat(smileVols, expiries.Length).ToArray(); var volSurface = new GridVolSurface(origin, deltaKs, expiries, vols, Core.Basic.StrikeType.ForwardDelta, Interpolator1DType.LinearFlatExtrap, Interpolator1DType.LinearInVariance, DayCountBasis.Act365F); var fwdCurve1 = new Func <double, double>(t => { return(1000); }); var fwdCurve2 = new Func <double, double>(t => { return(1000); }); var fwdCurve3 = new Func <double, double>(t => { return(1000); }); var assetA = new LVSingleAsset ( startDate: origin, expiryDate: origin.AddYears(1), volSurface: volSurface, forwardCurve: fwdCurve1, nTimeSteps: 365, name: "TestAssetA" ); var assetB = new LVSingleAsset ( startDate: origin, expiryDate: origin.AddYears(1), volSurface: volSurface, forwardCurve: fwdCurve2, nTimeSteps: 365, name: "TestAssetB" ); var assetC = new LVSingleAsset ( startDate: origin, expiryDate: origin.AddYears(1), volSurface: volSurface, forwardCurve: fwdCurve3, nTimeSteps: 365, name: "TestAssetC" ); engine.AddPathProcess(assetA); engine.AddPathProcess(assetB); engine.AddPathProcess(assetC); var correlAB = new Correlation("TestAssetA", "TestAssetB"); var correlAC = new Correlation("TestAssetA", "TestAssetC"); var correlBC = new Correlation("TestAssetB", "TestAssetC"); engine.AddPathProcess(correlAB); engine.AddPathProcess(correlAC); engine.AddPathProcess(correlBC); engine.SetupFeatures(); engine.RunProcess(); Assert.Equal(correlationAB, correlAB.AverageResult, 2); Assert.Equal(correlationAC, correlAC.AverageResult, 2); Assert.Equal(correlationBC, correlBC.AverageResult, 2); }