public double CalcAvgMonteCaroError(int nForAverage, int N) { double callOptionPriceBS = BlackScholesFormula.CalculateCallOptionPrice(sigma, S, K, r, T); double avgErr = 0; for (int i = 0; i < nForAverage; ++i) { BlackScholesMonteCarlo mc = new BlackScholesMonteCarlo(sigma, r, N); double mcPrice = mc.CalculateEuropeanCallOptionPrice(S, K, T); avgErr += Math.Abs(mcPrice - callOptionPriceBS); } return(avgErr / nForAverage); }
public static double CalculateImpliedVolCall(double C, double S, double K, double r, double T, double x0 = 0.5, double maxErr = 1e-6, int N = 10000) { if (C <= 0 || T <= 0 || K <= 0 || S <= 0 || maxErr <= 0 || N <= 0) { throw new System.ArgumentException("Need C > 0, T > 0, K > 0, S > 0, maxErr > 0, N > 0."); } Func <double, double> F = (x) => { return(C - BlackScholesFormula.CalculateCallOptionPrice(x, S, K, r, T)); }; NewtonSolver s = new NewtonSolver(maxErr, N); return(s.Solve(F, null, x0)); }
static void TestImpliedVol(double sigma = 0.1, //volatilty double S = 100, //underlying price double K = 100, //strike price double r = 0.05, //risk free rate double T = 1) //time to maturity in years { double CallOptionPrice = BlackScholesFormula.CalculateCallOptionPrice(sigma, S, K, r, T); double PutOptionPrice = BlackScholesFormula.CalculatePutOptionPrice(sigma, S, K, r, T); System.Console.WriteLine("Price of a call option using Black Scholes formula is: {0}", BlackScholesFormula.CalculateCallOptionPrice(sigma, S, K, r, T)); System.Console.WriteLine("Price of a put option using Black Scholes formula is: {0}", BlackScholesFormula.CalculatePutOptionPrice(sigma, S, K, r, T)); System.Console.WriteLine("Implied volatiliy of a call option given the price from Black Scholes is: {0}", BlackScholesImpliedVolEuropean.CalculateImpliedVolCall(10, S, K, r, T)); System.Console.WriteLine("Implied volatiliy of a put option given the price from Black Scholes is: {0}", BlackScholesImpliedVolEuropean.CalculateImpliedVolPut(3, S, K, r, T)); }
public static double CalculateImpliedVolPut(double P, double S, double K, double r, double T, double x0 = 0.5, double maxErr = 1e-6, int N = 10000) { if (P <= 0 || T <= 0 || K <= 0 || S <= 0 || maxErr <= 0 || N <= 0) { throw new System.ArgumentException("Need P > 0, T > 0, K > 0, S > 0, maxErr > 0, N > 0."); } double callPrice = BlackScholesFormula.GetCallFromPutPrice(S, K, r, T, P); if (callPrice < 0) { throw new System.ArgumentException("Input arguments violate put/call parity."); } return(CalculateImpliedVolCall(callPrice, S, K, r, T, x0, maxErr, N)); }
public static void Main(string[] args) { // Model params double r = 0.05; double sigma = 0.1; double K = 100; double T = 1; double S0 = 100; BlackScholesFormula bsFormula = new BlackScholesFormula(new BlackScholesModelParams(r, sigma)); double bsPrice = bsFormula.PutPrice(new EuropeanCallPutParams(T, S0, K)); Func <double, double> putPayoff = (S) => Math.Max(K - S, 0); BlackScholesFiniteDifferenceSolver solverFD = new BlackScholesFiniteDifferenceSolver(T, putPayoff, r, sigma, 3 * K, 10, 10); double bsPriceFD = solverFD.Price(100); uint N, M; int numberRefinments = 5; // test convergence w.r.t. number of partitions of space interval N = 200; M = 100; for (int refinementIndex = 0; refinementIndex < numberRefinments; ++refinementIndex, M *= 2) { BlackScholesFiniteDifferenceSolver solverForThisLevelOfRefinement = new BlackScholesFiniteDifferenceSolver(T, putPayoff, r, sigma, 5 * K, N, M); double error = Math.Abs(bsPrice - solverForThisLevelOfRefinement.Price(S0)); Console.WriteLine("Space partitions: {0}, time steps: {1}, error: {2}", M, N, error); } // test convergence w.r.t. number of time steps N = 10; M = 8001; for (int refinementIndex = 0; refinementIndex < numberRefinments; ++refinementIndex, N *= 2) { BlackScholesFiniteDifferenceSolver solverForThisLevelOfRefinement = new BlackScholesFiniteDifferenceSolver(T, putPayoff, r, sigma, 5 * K, N, M); double error = Math.Abs(bsPrice - solverForThisLevelOfRefinement.Price(S0)); Console.WriteLine("Space partitions: {0}, time steps: {1}, error: {2}", M, N, error); } Console.WriteLine("Finished. Press any key."); //Console.ReadKey (); }
public static object DupireSsviEuropeanVanillaOptionPrice([ExcelArgument(Description = "the current risky asset price")] double S0, [ExcelArgument(Description = "constant continuously compounded rate of return")] double riskFreeRate, [ExcelArgument(Description = "parameter in theta(t) := alpha^2(e^(beta^2 t) - 1)")] double alpha, [ExcelArgument(Description = "parameter in theta(t) := alpha^2(e^(beta^2 t) - 1)")] double beta, [ExcelArgument(Description = "SSVI parameter")] double gamma, [ExcelArgument(Description = "SSVI parameter")] double eta, [ExcelArgument(Description = "SSVI parameter")] double rho, [ExcelArgument(Description = "option maturity (time to expiry)")] double maturity, [ExcelArgument(Description = "option strike")] double strike, [ExcelArgument(Description = "option type, 'C' for call 'P' for put")] string type) { try { Ssvi SsviSurface = new Ssvi(alpha, beta, gamma, eta, rho); double k = Math.Log(strike * Math.Exp(-riskFreeRate * maturity) / S0); double sigmaBs = Math.Sqrt(SsviSurface.OmegaSsvi(maturity, k) / maturity); if (type == "Call" || type == "call" || type == "C" || type == "c") { return(BlackScholesFormula.CalculateCallOptionPrice(sigmaBs, S0, k, riskFreeRate, maturity)); } else if (type == "Put" || type == "put" || type == "P" || type == "p") { return(BlackScholesFormula.CalculatePutOptionPrice(sigmaBs, S0, k, riskFreeRate, maturity)); } else { throw new ArgumentException("Input must be either Call, call, C, c, Put, put, P or p."); } } catch (Exception e) { XLInterfaceBase.AddErrorMessage("DupireSsviEuropeanVanillaOptionPrice error: " + e.Message); } return(FunctionError); }