Estoy tratando de implementar una vainilla opción Europea encargado del precio de Monte Carlo y comparar el resultado con el BS fórmula analítica es el resultado.
Me di cuenta de que como yo (incremento de 1 millón a 10 millones) el número de simulaciones, el MC resultado empieza a divergir.
Tenga en cuenta que yo deliberadamente sólo utilizar sólo una técnica de reducción de varianza: antitético de las variables. Tenía la esperanza de que por el mero hecho de aumentar el número de simulaciones, me las arreglaría para aumentar la precisión.
Puede alguien por favor me dan pistas o indicaciones de por qué mi resultado diverge?
A continuación se incluye el código de C# para el encargado del precio:
using System;
using System.Threading.Tasks;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.Random;
namespace MonteCarlo
{
class VanillaEuropeanCallMonteCarlo
{
static void Main(string[] args)
{
const int NUM_SIMULATIONS = 10000000;
const decimal strike = 50m;
const decimal initialStockPrice = 52m;
const decimal volatility = 0.2m;
const decimal riskFreeRate = 0.05m;
const decimal maturity = 0.5m;
Normal n = new Normal();
n.RandomSource = new MersenneTwister();
VanillaEuropeanCallMonteCarlo vanillaCallMonteCarlo = new VanillaEuropeanCallMonteCarlo();
Task<decimal>[] simulations = new Task<decimal>[NUM_SIMULATIONS];
for (int i = 0; i < simulations.Length; i++)
{
simulations[i] = new Task<decimal>(() => vanillaCallMonteCarlo.RunMonteCarloSimulation(strike, initialStockPrice, volatility, riskFreeRate, maturity, n));
simulations[i].Start();
}
Task.WaitAll(simulations);
decimal total = 0m;
for (int i = 0; i < simulations.Length; i++)
{
total += simulations[i].Result;
}
decimal callPrice = (decimal)(Math.Exp((double)(-riskFreeRate * maturity)) * (double)total / (NUM_SIMULATIONS * 2));
Console.WriteLine("Call Price: " + callPrice);
Console.WriteLine("Difference: " + Math.Abs(callPrice - 4.744741008m));
}
decimal RunMonteCarloSimulation(decimal strike, decimal initialStockPrice, decimal volatility, decimal riskFreeRate, decimal maturity, Normal n)
{
decimal randGaussian = (decimal)n.Sample();
decimal endStockPriceA = initialStockPrice * (decimal)Math.Exp((double)((riskFreeRate - (decimal)(0.5 * Math.Pow((double)volatility, 2))) * maturity + volatility * (decimal)Math.Sqrt((double)maturity) * randGaussian));
decimal endStockPriceB = initialStockPrice * (decimal)Math.Exp((double)((riskFreeRate - (decimal)(0.5 * Math.Pow((double)volatility, 2))) * maturity + volatility * (decimal)Math.Sqrt((double)maturity) * (-randGaussian)));
decimal sumPayoffs = (decimal)(Math.Max(0, endStockPriceA - strike) + Math.Max(0, endStockPriceB - strike));
return sumPayoffs;
}
}
}