public void CallNaiveImplemXCheck() { var maturities = GridUtils.RegularGrid(0.1, 5.0, 100); var vols = GridUtils.RegularGrid(0.01, 1.0, 10); var volMoneynesses = GridUtils.RegularGrid(-3, 3, 100); foreach (var mat in maturities) { foreach (var vol in vols) { var sigma = Math.Sqrt(mat) * vol; foreach (var vm in volMoneynesses) { var strike = Math.Exp(vm * sigma); var call = BlackScholesOption.Price(1.0, strike, vol, mat, 1); //Naive implementation of black-scholes formulae var d_plus = -(vm * sigma) / sigma + 0.5 * sigma; var d_minus = d_plus - sigma; var call_xcheck = NormalDistribution.Cumulative(d_plus) - strike * NormalDistribution.Cumulative(d_minus); if (DoubleUtils.EqualZero(call)) { Assert.IsTrue(DoubleUtils.EqualZero(call_xcheck)); } else { var errRelative = (call - call_xcheck) / call_xcheck; Assert.IsTrue(Math.Abs(errRelative) < 1.0e-11); } } } } }
/// <summary> /// Price option using Lehman Brother proxy. /// </summary> /// <param name="maturity">option maturity</param> /// <param name="strike">option strike</param> /// <param name="vol">volatility</param> /// <param name="q">option type : 1 for call, -1 for put</param> /// <returns></returns> public double PriceLehman(double maturity, double strike, double vol, double q) { double effectiveForward, strikeShift; affineDivUtils.LehmanProxy(maturity, spot, out effectiveForward, out strikeShift); return(BlackScholesOption.Price(effectiveForward, strike + strikeShift, vol, maturity, q)); }
public void Implied_VolSample_Test() { const double mat = 1.0; const double strike = 1.50; var vols = GridUtils.RegularGrid(0.015, 2.0, 100); foreach (double vol in vols) { var option = BlackScholesOption.Price(1.0, strike, vol, mat, 1); var impliedVol = BlackScholesOption.ImpliedVol(option, 1.0, strike, mat, 1); var errRelative = (impliedVol - vol) / vol; Assert.IsTrue(Math.Abs(errRelative) < 6 * DoubleUtils.MachineEpsilon); } }
private double Price(double volBeforeMidT, double volAfterMidT, double q) { double aCvx = a * Math.Exp(-0.5 * volBeforeMidT * volBeforeMidT * midT); var price = 0.0; for (int i = 0; i < z.Length; i++) { double x = aCvx * Math.Exp(volBeforeMidT * z[i]) + b; double midTprice = (x > 0.0) ? BlackScholesOption.Price(x, k, volAfterMidT, dT, q) : (q > 0.0) ? 0.0 : k - x; price += quadWeights[i] * midTprice; } return(price); }
public double PriceProxy(double maturity, double strike, double vol, double q) { var growth = affineDivUtils.AssetGrowth(maturity); double cashBpv = affineDivUtils.CashDivBpv(maturity); double cashBpvTimeWAvg = affineDivUtils.CashBpvTimeWeightedAverage(maturity); double cashBpbAvg = affineDivUtils.CashBpvAverage(0.0, maturity); double volAdj = 1.0 + (cashBpvTimeWAvg - cashBpbAvg) / spot; double displacement = cashBpvTimeWAvg / volAdj; double formulaForward = growth * (spot - displacement); double formulaStrike = strike + growth * (cashBpv - displacement); double formulaVol = vol * volAdj; return(BlackScholesOption.Price(formulaForward, formulaStrike, formulaVol, maturity, q)); }
public void ImpliedVol_MoneynessSample_Test() { const double mat = 0.5; const double vol = 0.253251; var moneynesses = GridUtils.RegularGrid(-5.0, 5.0, 100); foreach (double m in moneynesses) { var strike = Math.Exp(m); var option = BlackScholesOption.Price(1.0, strike, vol, mat, m > 0 ? 1 : -1); var impliedVol = BlackScholesOption.ImpliedVol(option, 1.0, strike, mat, m > 0 ? 1 : -1); var errRelative = (impliedVol - vol) / vol; Assert.IsTrue(Math.Abs(errRelative) < 6 * DoubleUtils.MachineEpsilon); } }
public static object BlackOption(double forward, double strike, double maturity, double vol, string optionType) { return(FunctionRunnerUtils.Run("BlackOption", () => { double q; switch (optionType.Trim().ToLower()) { case "call": q = 1.0; break; case "put": q = -1.0; break; default: throw new Exception(string.Format("Unknow option type : {0}", optionType)); } return BlackScholesOption.Price(forward, strike, vol, maturity, q); })); }