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); }
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."); } }