public double CalculateIVByOptionPrice(double stockPrice, int dayLefts) { var blackNScholesCaculator = new BlackNScholesCaculator() { DayLefts = dayLefts, RiskFreeInterestRate = RiskFreeInterestRate, StockPrice = stockPrice, Strike = StrikePrice }; double iv = 0; try { iv = OptionType == EOptionType.Call ? blackNScholesCaculator.GetCallIVBisections(BaseOptionPrice) : blackNScholesCaculator.GetPutIVBisections(BaseOptionPrice); } catch (Exception ex) { Logger.Error(ex.Message + ": wrong calculation, ImpliedVolatilitiesBase = 0 !!!!", ex); } ImpliedVolatilitiesBase = iv; return(iv); }
public void Calculate() { var blackNScholesCaculator = new BlackNScholesCaculator { DayLefts = DayLefts, ImpliedVolatilities = ImpliedVolatilities, RiskFreeInterestRate = RiskFreeInterestRate, StockPrice = StockPrice, Strike = StrikePrice, Multiplier = Multiplier }; blackNScholesCaculator.CalculateAll(); if (OptionType == EOptionType.Call) { ResultDataValues.OptionPrice = Double.IsNaN(blackNScholesCaculator.CallValue) ? 0 : blackNScholesCaculator.CallValue; ResultDataValues.Delta = blackNScholesCaculator.DeltaCall; ResultDataValues.Gamma = blackNScholesCaculator.GamaCall; ResultDataValues.Theta = blackNScholesCaculator.ThetaCall; ResultDataValues.Vega = blackNScholesCaculator.VegaCall; } else { ResultDataValues.OptionPrice = Double.IsNaN(blackNScholesCaculator.PutValue) ? 0 : blackNScholesCaculator.PutValue; //ResultDataValues.OptionPrice = blackNScholesCaculator.PutValue; ResultDataValues.Delta = blackNScholesCaculator.DeltaPut; ResultDataValues.Gamma = blackNScholesCaculator.GamaPut; ResultDataValues.Theta = blackNScholesCaculator.ThetaPut; ResultDataValues.Vega = blackNScholesCaculator.VegaPut; } }
public static bool TestPutCalculation() { var o = new BlackNScholesCaculator { DayLefts = 90, ImpliedVolatilities = 0.2, OptionType = EOptionType.Call, RiskFreeInterestRate = 0.1, StockPrice = 50, Strike = 40 }; var putValue = o.CalculatePutValue(); return(!(Abs(putValue - 0.078) > 0.001)); }
//public double CalculateImpliedVolatilityBNSNewton(double callOptionPrice) //{ // double impliedVolatility = OptionPriceImpliedVolatilityCallBlackScholesNewton(StockPrice, Strike, // RiskFreeInterestRate, ExpiryTime, callOptionPrice); // return impliedVolatility; //} /// <summary> /// Calculates implied volatility for the Black Scholes formula using /// the Newton-Raphson formula /// /// Converted to C# from "Financial Numerical Recipes in C" by: /// Bernt Arne Odegaard /// http://finance.bi.no/~bernt/gcc_prog/index.html /// /// (NOTE: In the original code a large negative number was used as an /// exception handling mechanism. This has been replace with a generic /// 'Exception' that is thrown. The original code is in place and commented /// if you want to use the pure version of this code) /// </summary> /// <param name="spot">spot (underlying) price</param> /// <param name="strike">strike (exercise) price</param> /// <param name="interestRate">interest rate</param> /// <param name="time">time to maturity</param> /// <param name="optionPrice">The price of the option</param> /// <returns>Sigma (implied volatility)</returns> public double OptionPriceImpliedVolatilityCallBlackScholesNewton(double spot, double strike, double interestRate, double time, double optionPrice) { // check for arbitrage violations. Option price is too low if this happens if (optionPrice < 0.99 * (spot - strike * Exp(-time * interestRate))) { return(0.0); } const int MAX_ITERATIONS = 100; const double ACCURACY = 1.0e-5; double tSqrt = Sqrt(time); var blackNScholesCaculator = new BlackNScholesCaculator { ExpiryTime = time, RiskFreeInterestRate = interestRate, StockPrice = spot, Strike = strike, //ImpliedVolatilities = sigmaHigh }; double sigma = (optionPrice / spot) / (0.398 * tSqrt); // find initial value for (int i = 0; i < MAX_ITERATIONS; i++) { blackNScholesCaculator.ImpliedVolatilities = sigma; blackNScholesCaculator.CalculateAll(); double price = blackNScholesCaculator.CallValue; // price = OptionPriceCallBlackScholes(spot, strike, interestRate, sigma, time); double diff = optionPrice - price; if (Abs(diff) < ACCURACY) { return(sigma); } double d1 = (Log(spot / strike) + interestRate * time) / (sigma * tSqrt) + 0.5 * sigma * tSqrt; double vega = spot * tSqrt * CumulativeNormDist(d1); sigma = sigma + diff / vega; } //return -99e10; // something screwy happened, should throw exception // <--- original code throw new Exception("An error occurred"); // Comment this line if you uncomment the line above }
public static bool TestCallCalculation() { var o = new BlackNScholesCaculator { //ExpiryTime = 0.25, DayLefts = 90, ImpliedVolatilities = 0.2, OptionType = EOptionType.Call, RiskFreeInterestRate = 0.1, StockPrice = 50, Strike = 40 }; double callValue = o.CalculateCallValue(); if (Abs(callValue - 11.01) > 0.1) { return(false); } return(true); }
/// <summary> /// Calculates implied volatility for the Black Scholes formula using /// binomial search algorithm /// /// Converted to C# from "Financial Numerical Recipes in C" by: /// Bernt Arne Odegaard /// http://finance.bi.no/~bernt/gcc_prog/index.html /// /// (NOTE: In the original code a large negative number was used as an /// exception handling mechanism. This has been replace with a generic /// 'Exception' that is thrown. The original code is in place and commented /// if you want to use the pure version of this code) /// </summary> /// <param name="spot">spot (underlying) price</param> /// <param name="strike">strike (exercise) price</param> /// <param name="interestRate">interest rate</param> /// <param name="time">time to maturity</param> /// <param name="optionPrice">The price of the option</param> /// <returns>Sigma (implied volatility)</returns> public double PutOptionPriceIVBisections(double spot, double strike, double interestRate, double time, double optionPrice) { // check for arbitrage violations. if (optionPrice < 0.99 * (spot - strike * Exp(-time * interestRate))) { return(0.0); // Option price is too low if this happens } // simple binomial search for the implied volatility. // relies on the value of the option increasing in volatility const double ACCURACY = 1.0e-5; // make this smaller for higher accuracy const int MAX_ITERATIONS = 100; const double HIGH_VALUE = 1e10; //const double ERROR = -1e40; // <--- original code // want to bracket sigma. first find a maximum sigma by finding a sigma // with a estimated price higher than the actual price. double sigmaLow = 1e-5; double sigmaHigh = 0.3; var blackNScholesCaculator = new BlackNScholesCaculator { ExpiryTime = time, RiskFreeInterestRate = interestRate, StockPrice = spot, Strike = strike, ImpliedVolatilities = sigmaHigh }; blackNScholesCaculator.CalculateAll(); double price = blackNScholesCaculator.PutValue; while (price < optionPrice) { sigmaHigh = 2.0 * sigmaHigh; // keep doubling. blackNScholesCaculator.ImpliedVolatilities = sigmaHigh; blackNScholesCaculator.CalculateAll(); price = blackNScholesCaculator.PutValue; if (sigmaHigh > HIGH_VALUE) { //return ERROR; // panic, something wrong. // <--- original code throw new Exception("panic, something wrong."); // Comment this line if you uncomment the line above } } for (int i = 0; i < MAX_ITERATIONS; i++) { double sigma = (sigmaLow + sigmaHigh) * 0.5; blackNScholesCaculator.ImpliedVolatilities = sigma; blackNScholesCaculator.CalculateAll(); price = blackNScholesCaculator.PutValue; double test = (price - optionPrice); if (Abs(test) < ACCURACY) { IterationCounter = i; return(sigma); } if (test < 0.0) { sigmaLow = sigma; } else { sigmaHigh = sigma; } } //return ERROR; // <--- original code throw new Exception("An error occurred"); // Comment this line if you uncomment the line above }