public static ImpliedVolSurface ToImpliedVolSurface(this VolSurfMktData volSurfMktData, Date valuationDate, string dc = "Bus244") { if (!double.IsNaN(volSurfMktData.ConstVol)) { double constData = 0.0; if (volSurfMktData is CorrSurfMktData) { constData = (volSurfMktData as CorrSurfMktData).ConstCorr; } else if (volSurfMktData is VolSurfMktData) { constData = (volSurfMktData as VolSurfMktData).ConstVol; } var maturities = new[] { new Term("1Y").Prev(valuationDate), new Term("30Y").Next(valuationDate) }; var strikes = new[] { 0.0, 1.0e6 }; var cols = new[, ] { { constData, constData }, { constData, constData } }; return(new ImpliedVolSurface(valuationDate, maturities, strikes, cols, Interpolation2D.VarianceBiLinear, dcConvention: dc, volSurfaceType: volSurfMktData.VolSurfaceType.ToVolSurfaceType())); } else { if (volSurfMktData is CorrSurfMktData) { var corr = (volSurfMktData as CorrSurfMktData).CorrSurface; return(new ImpliedVolSurface(valuationDate, volSurfMktData.Maturities, volSurfMktData.Strikes, corr, volSurfMktData.Interpolation.ToInterpolation2D(), dcConvention: dc, volSurfaceType: volSurfMktData.VolSurfaceType.ToVolSurfaceType())); } else if (volSurfMktData is VolSurfMktData) { return(new ImpliedVolSurface(valuationDate, volSurfMktData.Maturities, volSurfMktData.Strikes, volSurfMktData.VolSurfaces, volSurfMktData.Interpolation.ToInterpolation2D(), dcConvention: dc, volSurfaceType: volSurfMktData.VolSurfaceType.ToVolSurfaceType())); } else { throw new PricingBaseException("unexpected vol type! not supported yet"); } } }
public void BasicVanillaOptionTest() { var startDate = new Date(2014, 03, 18); var maturityDate = new Date(2015, 03, 18); var valueDate = new Date(2014, 03, 18); #region Prepare Market // build discount curve and dividend curve var fr007CurveName = "Fr007"; var fr007RateDefinition = new[] { new RateMktData("1D", 0.06, "Spot", "None", fr007CurveName), new RateMktData("5Y", 0.06, "Spot", "None", fr007CurveName), }; var dividendCurveName = "Dividend"; var dividendRateDefinition = new[] { new RateMktData("1D", 0.03, "Spot", "None", dividendCurveName), new RateMktData("5Y", 0.03, "Spot", "None", dividendCurveName), }; var discountCurve = new YieldCurve( name: fr007CurveName, referenceDate: valueDate, keyPoints: fr007RateDefinition.Select(x => Tuple.Create((ITerm) new Term(x.Tenor), x.Rate)).ToArray(), bda: BusinessDayConvention.ModifiedFollowing, dayCount: new Act365(), calendar: CalendarImpl.Get("Chn"), currency: CurrencyCode.CNY, compound: Compound.Continuous, interpolation: Interpolation.CubicHermiteMonotic, trait: YieldCurveTrait.SpotCurve); var dividendCurve = new YieldCurve( name: dividendCurveName, referenceDate: valueDate, keyPoints: dividendRateDefinition.Select(x => Tuple.Create((ITerm) new Term(x.Tenor), x.Rate)).ToArray(), bda: BusinessDayConvention.ModifiedFollowing, dayCount: new Act365(), calendar: CalendarImpl.Get("Chn"), currency: CurrencyCode.CNY, compound: Compound.Continuous, interpolation: Interpolation.CubicHermiteMonotic, trait: YieldCurveTrait.SpotCurve); // build vol surface var volSurfData = new VolSurfMktData("VolSurf", 0.25); var volSurface = volSurfData.ToImpliedVolSurface( valuationDate: valueDate, dc: "Act365"); // construct market var market = new MarketCondition( x => x.ValuationDate.Value = valueDate, x => x.DiscountCurve.Value = discountCurve, x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> { { "", dividendCurve } }, x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> { { "", volSurface } }, x => x.SpotPrices.Value = new Dictionary <string, double> { { "", 1.0 } } ); #endregion // construct a put option var put = new VanillaOption(startDate, maturityDate, OptionExercise.European, OptionType.Put, 1.0, InstrumentType.Stock, CalendarImpl.Get("chn"), new Act365(), CurrencyCode.CNY, CurrencyCode.CNY, new[] { maturityDate }, new[] { maturityDate }); var engine = new AnalyticalVanillaEuropeanOptionEngine(); var result = engine.Calculate(put, market, PricingRequest.All); }
/// <summary> /// Calibrate implied bs vol from spot premium of an european option /// </summary> /// <param name="premium"></param> /// <param name="isCall"></param> /// <param name="strike"></param> /// <param name="spot"></param> /// <param name="rate"></param> /// <param name="expiryDateStr"></param> /// <param name="valuationDateStr"></param> /// <param name="underlyingInstrumentType"></param> /// <param name="calendarStr"></param> /// <param name="dayCountStr"></param> /// <param name="commodityFuturesPreciseTimeMode"></param> /// <param name="hasNightMarket"></param> /// <returns>if succeed then return implied vol, if falied then return error message</returns> public static double xl_ImpliedVolFromPremium(double premium, bool isCall, double strike, double spot, double rate, string expiryDateStr, string valuationDateStr, string underlyingInstrumentType, string calendarStr, string dayCountStr, bool commodityFuturesPreciseTimeMode = false, bool hasNightMarket = false) { var bsEngine = new AnalyticalVanillaEuropeanOptionEngine(); var expiryDate = expiryDateStr.ToDate(); var valuationDate = valuationDateStr.ToDate(); var instrumentType = underlyingInstrumentType.ToInstrumentType(); var calendar = calendarStr.ToCalendarImpl(); var dayCount = dayCountStr.ToDayCountImpl(); var trade = new VanillaOption( valuationDate, expiryDate, OptionExercise.European, isCall ? OptionType.Call : OptionType.Put, strike, instrumentType, calendar, dayCount, CurrencyCode.CNY, CurrencyCode.CNY, new[] { expiryDate }, new[] { expiryDate }, notional: 1, hasNightMarket: hasNightMarket, commodityFuturesPreciseTimeMode: commodityFuturesPreciseTimeMode ); var curve = new YieldCurve( "riskFreeRate", valuationDate, new[] { Tuple.Create((ITerm) new Term("1D"), rate), Tuple.Create((ITerm) new Term("1Y"), rate) }, BusinessDayConvention.ModifiedFollowing, dayCount, calendar, CurrencyCode.CNY, Compound.Continuous, Interpolation.CubicHermiteMonotic, YieldCurveTrait.SpotCurve ); var volSurf = new VolSurfMktData("VolSurf", 0.1).ToImpliedVolSurface(valuationDate); var market = new MarketCondition( x => x.ValuationDate.Value = valuationDate, x => x.DiscountCurve.Value = curve, x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> { { "", curve } }, //not used by futures option x => x.FixingCurve.Value = curve, x => x.RiskfreeCurve.Value = curve, x => x.SpotPrices.Value = new Dictionary <string, double> { { "", spot } }, x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> { { "", volSurf } }); //not used by this calibration return(bsEngine.ImpliedVolFromPremium(targetPremium: premium, option: trade, market: market)); }