示例#1
0
        /// <summary>
        /// Generates a 2d array of N stock paths over M time steps.
        /// </summary>
        /// <returns></returns>
        public static double[,] GenerateMcPaths(int N, int M, double T, double r, double S0, double[] ssviParams)
        {
            Ssvi ssvi = new Ssvi(ssviParams);

            // N = number of samples, M = number of time steps
            double[,] pathOfS = new double[N, M];
            double[] Z   = new double[N];
            double   tau = T / M;

            for (int m = 1; m < M; ++m)  // foreach time step
            {
                Normal.Samples(Z, 0, 1); //Fill Z with normal 0,1 samples
                double sqrtTau = Math.Sqrt(tau);

                for (int n = 0; n < N; ++n) // foreach sample
                {
                    pathOfS[n, 0] = S0;
                    double s_n_m = pathOfS[n, m - 1];
                    if (s_n_m < 0)
                    {
                        s_n_m = 1e-10;
                    }
                    double dw = sqrtTau * Z[n];
                    double k  = Math.Log(s_n_m * Math.Exp(-r * T) / S0);
                    pathOfS[n, m] = s_n_m + r * s_n_m * tau + ssvi.VolatilityDup(tau * m, k) * s_n_m * dw;
                }
            }
            return(pathOfS);
        }
        public void GetCalibrationStatus(ref CalibrationOutcome calibOutcome, ref double pricingError)
        {
            calibOutcome = outcome;
            Ssvi m = new Ssvi(calibratedParams);

            pricingError = CalcMeanSquareErrorBetweenOmegaAndMarketNonATM(m);
        }
示例#3
0
        public static void RunVolatilityTest()
        {
            double alpha = Math.Sqrt(0.1);
            double beta  = 1;
            double gamma = 0.7;
            double eta   = 0.2;
            double rho   = 0.3;
            double r     = 0.025;
            double S     = 100;
            double K     = 102.5313;
            double T     = 1;

            double k        = Math.Log(K * Math.Exp(-r * T) / S);
            Ssvi   SsviTest = new Ssvi(alpha, beta, gamma, eta, rho);

            Console.WriteLine("SSVI Volatility = {0}", SsviTest.VolatilityDup(T, k));
        }
示例#4
0
        public static void RunEurOptionPricing()
        {
            double[] ssviParams = new double[] { Math.Sqrt(0.1), 1, 0.7, 0.2, 0.3 };
            double   r          = 0.025;
            double   S0         = 100;
            double   T          = 1;
            int      N          = 10000;
            int      M          = 128;
            double   K          = 102;
            double   k          = Math.Log(K * Math.Exp(-r * T) / S0);

            MonteCarloPricingLocalVol pricer = new MonteCarloPricingLocalVol(r, N, M, ssviParams);
            double McPriceCall = pricer.CalculateEurPutOptionPrice(S0, K, T);
            Ssvi   SsviSurface = new Ssvi(ssviParams[0], ssviParams[1], ssviParams[2], ssviParams[3], ssviParams[4]);
            double sigmaBs     = Math.Sqrt(SsviSurface.OmegaSsvi(T, k) / T);
            double BsPriceCall = BlackScholesFormula.CalculatePutOptionPrice(sigmaBs, 100, k, r, T);

            Console.WriteLine("Call price: MC: £{0}, BS £{1}", McPriceCall, BsPriceCall);
        }
示例#5
0
        public static double[][] ParallelGenerateMcPaths(int N, int M, double T, double r, double S0, double[] ssviParams)
        {
            Ssvi ssvi = new Ssvi(ssviParams);

            // N = number of samples 10000, M = number of time steps 128
            double[][] pathOfS = new double[N][];
            double[]   Z       = new double[M];
            double     tau     = T / M;

            ConcurrentBag <double[]> paths = new ConcurrentBag <double[]>();

            object mylock = new object();

            Parallel.For(0, N, n =>
            {
                double[] vec = new double[M];
                Normal.Samples(Z, 0, 1);    //Fill Z with normal 0,1 samples
                double sqrtTau = Math.Sqrt(tau);

                for (int m = 0; m < (M - 1); ++m) // foreach sample
                {
                    vec[0]     = S0;
                    double s_n = vec[m];
                    if (s_n < 0)
                    {
                        s_n = 1e-10;
                    }
                    double dw  = sqrtTau * Z[m];
                    double k   = Math.Log(s_n * Math.Exp(-r * T) / S0);
                    vec[m + 1] = s_n + r * s_n * tau + ssvi.VolatilityDup(tau * m, k) * s_n * dw;
                }
                paths.Add(vec);
            }
                         );

            pathOfS = paths.ToArray();
            return(pathOfS);
        }
        public double CalcMeanSquareErrorBetweenOmegaAndMarketNonATM(Ssvi m)
        {
            double meanSqErr = 0;
            int    nElements = 0;

            foreach (OptionMarketData option in marketOptionsList)
            {
                double maturity = option.maturity;
                string type     = option.type;
                double strike   = option.strike;
                double k        = Math.Log(strike * Math.Exp(-r0) / S0);
                double omega    = m.OmegaSsvi(maturity, k);
                double bsImpliedVolatility;
                if (option.type == "Call" || option.type == "call" || option.type == "C" || option.type == "c")
                {
                    bsImpliedVolatility = BlackScholesImpliedVolatility.CalculateImpliedVolCall(option.marketPrice, S0, k, r0, maturity);
                }
                else if (option.type == "Put" || option.type == "put" || option.type == "P" || option.type == "p")
                {
                    bsImpliedVolatility = BlackScholesImpliedVolatility.CalculateImpliedVolPut(option.marketPrice, S0, k, r0, maturity);
                }
                else
                {
                    throw new CalibrationFailedException("Option type in marketOptionsList was not Call, call, C, c, Put, put, P or p");
                }
                double difference = omega - bsImpliedVolatility * bsImpliedVolatility * maturity;
                meanSqErr += difference * difference;
                nElements++;
            }
            if (nElements > 0)
            {
                return(meanSqErr / nElements);
            }
            else
            {
                throw new ArgumentNullException("There is no market data to use for error calculation.");
            }
        }
        // Must ensure calibration of all Parameters alpha, beta, eta, gamma & rho
        public Ssvi GetCalibratedModel()
        {
            Ssvi m = new Ssvi(calibratedParams);

            return(m);
        }
        // Used by Alglib minimisation algorithm
        public void CalibrationObjectiveFunctionNonATM(double[] x, ref double func, object obj)
        {
            Ssvi m = new Ssvi(x);

            func = CalcMeanSquareErrorBetweenOmegaAndMarketNonATM(m);
        }
        // Used by Alglib minimisation algorithm
        public void CalibrationObjectiveFunctionATM(double[] ssviParams, ref double func, object obj)
        {
            Ssvi m = new Ssvi(ssviParams);

            func = CalcMeanSquareErrorBetweenThetaAndMarketATM(m);
        }