public static object EquityImpliedVol(object mktObj, string assetName, object maturity, double strike, double price, string optionType) { return(FunctionRunnerUtils.Run("EquityImpliedVol", () => { Market market = MarketManager.Instance.GetMarket(mktObj); AssetMarket assetMkt = market.AssetMarketFromName(assetName); var pricer = BlackScholesWithDividendOption.Build(assetMkt.Spot, assetMkt.Dividends, assetMkt.RiskFreeDiscount, assetMkt.Time); 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)); } var matAsDate = ObjectConverters.ConvertDate(maturity, assetMkt.RefDate); return pricer.ImpliedVol(assetMkt.Time[matAsDate], strike, price, q); })); }
public override IModelDescription Calibrate(BlackScholesModelCalibDesc bsDesc, Market market) { AssetMarket assetMkt = market.AssetMarketFromName(bsDesc.Asset); var volSurface = assetMkt.VolSurface(); var forwardCurve = assetMkt.Forward(); var optionPricer = BlackScholesWithDividendOption.Build(assetMkt.Spot, assetMkt.Dividends, assetMkt.RiskFreeDiscount, assetMkt.Time); var calibMaturities = bsDesc.CalibrationMaturities.Map(d => d.ToDate(assetMkt.RefDate)); var calibStrikes = bsDesc.CalibrationStrikes; var calibDates = assetMkt.Time[calibMaturities]; double[] targetPrices = new double[calibDates.Length]; double[] optionTypes = new double[calibDates.Length]; for (int i = 0; i < calibMaturities.Length; i++) { var targetVol = volSurface.Volatility(calibDates[i], calibStrikes[i]); var optionType = (calibStrikes[i] > forwardCurve.Fwd(calibMaturities[i])) ? 1.0 : -1.0; targetPrices[i] = optionPricer.Price(calibDates[i], calibStrikes[i], targetVol, optionType); optionTypes[i] = optionType; } var calibratedVols = optionPricer.CalibrateVol(calibDates, targetPrices, bsDesc.CalibrationStrikes, optionTypes); var sigma = new MapRawDatas <DateOrDuration, double>(bsDesc.CalibrationMaturities, calibratedVols); return(new BlackScholesModelDescription(bsDesc.Asset, sigma, bsDesc.WithDivs)); }
public void CalibrationTest(AssetMarket assetMkt) { var maturities = new [] { 3 * Duration.Month, 6 * Duration.Month, Duration.Year, 2 * Duration.Year, 3 * Duration.Year, 4 * Duration.Year, 5 * Duration.Year }; var vols = new[] { 0.20, 0.15, 0.20, 0.15, 0.20, 0.18, 0.20 }; var calibDates = assetMkt.Time[maturities.Map(p => assetMkt.RefDate + p)]; var strikes = ArrayUtils.Constant(calibDates.Length, assetMkt.Spot); var pricer = BlackScholesWithDividendOption.Build(assetMkt.Spot, assetMkt.Dividends, assetMkt.RiskFreeDiscount, assetMkt.Time); var targetPrices = EnumerableUtils.For(0, calibDates.Length, i => pricer.Price(calibDates[i], strikes[i], vols[i], 1.0)); var calibVols = pricer.CalibrateVol(calibDates, targetPrices, assetMkt.Spot, 1.0); }
public void SampleStrike(AssetMarket assetMkt) { DateTime maturity = assetMkt.RefDate + 3 * Duration.Year; var fwd = assetMkt.Forward().Fwd(maturity); double t = assetMkt.Time[maturity]; var pricer = BlackScholesWithDividendOption.Build(assetMkt.Spot, assetMkt.Dividends, assetMkt.RiskFreeDiscount, assetMkt.Time); var vols = GridUtils.RegularGrid(0.05, 1.0, 50); var moneynesses = GridUtils.RegularGrid(-10.0, 10.0, 51); foreach (double vol in vols) { var stdDev = vol * Math.Sqrt(t); foreach (double m in moneynesses) { var strike = fwd * Math.Exp(stdDev * m); var price = pricer.Price(t, strike, vol, m > 0 ? 1 : -1); var impliedVol = pricer.ImpliedVol(t, strike, price, m > 0 ? 1 : -1); var errRelative = (impliedVol - vol) / vol; Assert.IsTrue(Math.Abs(errRelative) < 5.0e-13); } } }