public double PriceVIXOption(VIXOption Option, Func <double, double> epsilon, double stock_0) { int n = 500; double T = Option.maturity; Grid grid = new Grid(0, T, (int)Math.Abs(T * n)); int n_T = grid.get_timeNmbrStep(); int kappa = 2; //Correlation : SymmetricMatrix correl = MakeCorrel(n, grid); SquareMatrix choleskyCorrel = correl.CholeskyDecomposition().SquareRootMatrix(); double rho = 0.1;//correlation between the two Brownian Func <double, double> payoff; switch (Option.type) { case VIXOption.OptionType.Call: payoff = S => Math.Max(S - Option.strike, 0); break; case VIXOption.OptionType.Put: payoff = S => Math.Max(Option.strike - S, 0); break; default: payoff = S => Math.Max(S - Option.strike, 0); break; } double price = 0.0; double McNbSimulation = 1E5; for (int mc = 1; mc <= McNbSimulation; mc++) { // 1-simulation of volterra Hybrid Scheme ColumnVector Z; ColumnVector volterra; //ColumnVector Z_Brownian; HybridScheme hybridscheme = new HybridScheme(choleskyCorrel, grid, kappa, H); hybridscheme.simulate(out Z, out volterra); GaussianSimulator simulator = new GaussianSimulator(); //Z_Brownian = ExtractBrownian(kappa, n_T, Z, volterra); ColumnVector Variance = new ColumnVector(n_T + 1); Variance[0] = epsilon(grid.t(0)); for (int i = 1; i <= grid.get_timeNmbrStep(); i++) { Variance[i] = epsilon(grid.t(i)) * Math.Exp(2 * vi * Ch * volterra[i - 1] - Math.Pow(vi * Ch, 2) * Math.Pow(grid.t(i), 2 * H)); } double X = Math.Log(stock_0); for (int i = 0; i < n_T; i++) { double dW = (rho * Z[i] + Math.Sqrt(1 - Math.Pow(rho, 2)) * Math.Sqrt(grid.get_Step()) * simulator.Next()); X = X - 0.5 * Variance[i] * grid.get_Step() + Math.Sqrt(Variance[i]) * dW; } double S = Math.Exp(X); price += payoff(S); } price /= McNbSimulation; return(price); }
public double VIXfuture_TruncatedChlsky(double T, Func <double, double> epsilon) { DateTime start = DateTime.Now; //StreamWriter sw = new StreamWriter("C:\\Users\\Marouane\\Desktop\\M2IF\\rough volatility\\rBergomiFile.txt"); //Grid int N = 100; int S = 7; Grid grid = new Grid(T, T + Delta, N); #region Correlation "Correl Matrix Construction" // Small Covariance Matrix t_0 , ... , t_7 SymmetricMatrix covM_Small = new SymmetricMatrix(S); //the full Covariance Matrix SymmetricMatrix covM = new SymmetricMatrix(N + 1); //Setting for integrale approximations EvaluationSettings settings = new EvaluationSettings(); settings.AbsolutePrecision = 1.0E-7; settings.RelativePrecision = 0.0; // Small Covariance Calcul t_0,.....,t_7 for (int i = 0; i < S; i++) { covM_Small[i, i] = (Math.Pow(grid.t(i), 2 * H) - Math.Pow(grid.t(i) - T, 2 * H)) / (2 * H); for (int j = 0; j < i; j++) { Func <double, double> covfunc = t => Math.Pow((grid.t(j) - t) * (grid.t(i) - t), H - 0.5); IntegrationResult integresult = FunctionMath.Integrate(covfunc, Meta.Numerics.Interval.FromEndpoints(0.0, T), settings); covM_Small[i, j] = integresult.Value; } } // full COrrelation Calcul for (int i = 0; i <= N; i++) { covM[i, i] = (Math.Pow(grid.t(i), 2 * H) - Math.Pow(grid.t(i) - T, 2 * H)) / (2 * H); for (int j = 0; j < i; j++) { Func <double, double> covfunc = t => Math.Pow((grid.t(j) - t) * (grid.t(i) - t), H - 0.5); IntegrationResult integresult = FunctionMath.Integrate(covfunc, Meta.Numerics.Interval.FromEndpoints(0.0, T), settings); covM[i, j] = integresult.Value; } } Func <int, int, double> corrf_Small = (i, j) => covM_Small[i, j] / (Math.Sqrt(covM_Small[i, i] * covM_Small[j, j])); SymmetricMatrix Correl_Small = new SymmetricMatrix(S); Correl_Small.Fill(corrf_Small); Func <int, int, double> corrf = (i, j) => covM[i, j] / (Math.Sqrt(covM[i, i] * covM[j, j])); SymmetricMatrix Correl = new SymmetricMatrix(N + 1); Correl.Fill(corrf); #endregion CholeskyDecomposition cholesky = Correl_Small.CholeskyDecomposition(); SquareMatrix choleskyCorrel_Small = new SquareMatrix(S); choleskyCorrel_Small = cholesky.SquareRootMatrix(); GaussianSimulator simulator = new GaussianSimulator(); double VIX = 0.0; var MC = 1.0E5; for (int mc = 1; mc < MC; mc++) { ColumnVector GaussianVector = new ColumnVector(S); // Simulating Volterra at 8 first steps on [T, T+Delta] for (int i = 0; i < S; i++) { GaussianVector[i] = simulator.Next(); } ColumnVector Volterra_small = choleskyCorrel_Small * GaussianVector; //Adjusting the variance of Volterra Processus for (int i = 0; i < S; i++) { Volterra_small[i] = Volterra_small[i] * Math.Sqrt((Math.Pow(grid.t(i), 2 * H) - Math.Pow(grid.t(i) - grid.t(0), 2 * H)) / (2 * H)); } // Simulating VOlterra on t_8 ... t_N with the truncated Formula double[] Volterra = new double[N + 1]; for (int i = 0; i <= N; i++) { if (i < S) { Volterra[i] = Volterra_small[i]; } //Tranceted Formula else { Volterra[i] = Math.Sqrt(covM[i, i]) * (Correl[i, i - 1] * Volterra[i - 1] / Math.Sqrt(covM[i - 1, i - 1]) + Math.Sqrt(1 - Math.Pow(Correl[i, i - 1], 2)) * simulator.Next()); } } double VIX_ = VIX_Calculate(epsilon, grid, Volterra); VIX += VIX_; } //sw.Close(); VIX /= MC; TimeSpan dur = DateTime.Now - start; return(VIX); }