//------------------------------------------------------------------------- // print for debugging protected internal virtual void print(IborCapletFloorletVolatilityCalibrationResult res, DoubleArray strikes, double maxTime) { Console.WriteLine("Print in CapletStrippingSetup \n"); Console.WriteLine("Chi-square: " + res.ChiSquare); IborCapletFloorletVolatilities vols = res.Volatilities; const int nSamples = 51; const int nStrikeSamples = 51; Console.Write("\n"); for (int i = 0; i < nStrikeSamples; i++) { Console.Write("\t" + (strikes.get(0) + (strikes.get(strikes.size() - 1) - strikes.get(0)) * i) / (nStrikeSamples - 1)); } Console.Write("\n"); for (int index = 0; index < nSamples; index++) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double t = 0.25 + index * maxTime / (nSamples - 1); double t = 0.25 + index * maxTime / (nSamples - 1); double forward = FWD_CURVE.yValue(t); Console.Write(t); for (int i = 0; i < nStrikeSamples; i++) { double strike = (strikes.get(0) + (strikes.get(strikes.size() - 1) - strikes.get(0)) * i) / (nStrikeSamples - 1); Console.Write("\t" + vols.volatility(t, strike, forward)); } Console.Write("\n"); } }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value of the Ibor caplet/floorlet period. /// <para> /// The result is expressed using the currency of the period. /// /// </para> /// </summary> /// <param name="period"> the Ibor caplet/floorlet period </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the present value </returns> public virtual CurrencyAmount presentValue(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities) { validate(volatilities); Currency currency = period.Currency; if (ratesProvider.ValuationDate.isAfter(period.PaymentDate)) { return(CurrencyAmount.of(currency, 0d)); } double expiry = volatilities.relativeTime(period.FixingDateTime); double df = ratesProvider.discountFactor(currency, period.PaymentDate); PutCall putCall = period.PutCall; double strike = period.Strike; double indexRate = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation); if (expiry < 0d) { // Option has expired already double sign = putCall.Call ? 1d : -1d; double payoff = Math.Max(sign * (indexRate - strike), 0d); return(CurrencyAmount.of(currency, df * payoff * period.YearFraction * period.Notional)); } double volatility = volatilities.volatility(expiry, strike, indexRate); double price = df * period.YearFraction * volatilities.price(expiry, putCall, strike, indexRate, volatility); return(CurrencyAmount.of(currency, price * period.Notional)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value rates sensitivity of the Ibor caplet/floorlet. /// <para> /// The present value rates sensitivity of the caplet/floorlet is the sensitivity /// of the present value to the underlying curves. /// /// </para> /// </summary> /// <param name="period"> the Ibor caplet/floorlet period </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the present value curve sensitivity </returns> public virtual PointSensitivityBuilder presentValueSensitivityRates(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities) { validate(volatilities); Currency currency = period.Currency; if (ratesProvider.ValuationDate.isAfter(period.PaymentDate)) { return(PointSensitivityBuilder.none()); } double expiry = volatilities.relativeTime(period.FixingDateTime); PutCall putCall = period.PutCall; double strike = period.Strike; double indexRate = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation); PointSensitivityBuilder dfSensi = ratesProvider.discountFactors(currency).zeroRatePointSensitivity(period.PaymentDate); if (expiry < 0d) { // Option has expired already double sign = putCall.Call ? 1d : -1d; double payoff = Math.Max(sign * (indexRate - strike), 0d); return(dfSensi.multipliedBy(payoff * period.YearFraction * period.Notional)); } PointSensitivityBuilder indexRateSensiSensi = ratesProvider.iborIndexRates(period.Index).ratePointSensitivity(period.IborRate.Observation); double volatility = volatilities.volatility(expiry, strike, indexRate); double df = ratesProvider.discountFactor(currency, period.PaymentDate); double factor = period.Notional * period.YearFraction; double fwdPv = factor * volatilities.price(expiry, putCall, strike, indexRate, volatility); double fwdDelta = factor * volatilities.priceDelta(expiry, putCall, strike, indexRate, volatility); return(dfSensi.multipliedBy(fwdPv).combinedWith(indexRateSensiSensi.multipliedBy(fwdDelta * df))); }
//------------------------------------------------------------------------- /// <summary> /// Computes the implied volatility of the Ibor caplet/floorlet. /// </summary> /// <param name="period"> the Ibor caplet/floorlet period </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the implied volatility </returns> public virtual double impliedVolatility(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities) { validate(volatilities); double expiry = volatilities.relativeTime(period.FixingDateTime); ArgChecker.isTrue(expiry >= 0d, "Option must be before expiry to compute an implied volatility"); double forward = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation); double strike = period.Strike; return(volatilities.volatility(expiry, strike, forward)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value volatility sensitivity of the Ibor caplet/floorlet. /// <para> /// The present value volatility sensitivity of the caplet/floorlet is the sensitivity /// of the present value to the implied volatility. /// </para> /// <para> /// The sensitivity to the implied volatility is also called vega. /// /// </para> /// </summary> /// <param name="period"> the Ibor caplet/floorlet period </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the point sensitivity to the volatility </returns> public virtual PointSensitivityBuilder presentValueSensitivityModelParamsVolatility(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities) { validate(volatilities); double expiry = volatilities.relativeTime(period.FixingDateTime); double strike = period.Strike; Currency currency = period.Currency; if (expiry <= 0d) { // Option has expired already or at expiry return(PointSensitivityBuilder.none()); } double forward = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation); double volatility = volatilities.volatility(expiry, strike, forward); PutCall putCall = period.PutCall; double df = ratesProvider.discountFactor(currency, period.PaymentDate); double vega = df * period.YearFraction * volatilities.priceVega(expiry, putCall, strike, forward, volatility); return(IborCapletFloorletSensitivity.of(volatilities.Name, expiry, strike, forward, currency, vega * period.Notional)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value theta of the Ibor caplet/floorlet period. /// <para> /// The present value theta is given by the minus of the present value sensitivity to the {@code timeToExpiry} /// parameter of the model. /// /// </para> /// </summary> /// <param name="period"> the Ibor caplet/floorlet period </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the present value theta </returns> public virtual CurrencyAmount presentValueTheta(IborCapletFloorletPeriod period, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities) { validate(volatilities); double expiry = volatilities.relativeTime(period.FixingDateTime); Currency currency = period.Currency; if (expiry < 0d) { // Option has expired already return(CurrencyAmount.of(currency, 0d)); } double forward = ratesProvider.iborIndexRates(period.Index).rate(period.IborRate.Observation); double strike = period.Strike; double volatility = volatilities.volatility(expiry, strike, forward); PutCall putCall = period.PutCall; double df = ratesProvider.discountFactor(currency, period.PaymentDate); double priceTheta = df * period.YearFraction * volatilities.priceTheta(expiry, putCall, strike, forward, volatility); return(CurrencyAmount.of(currency, priceTheta * period.Notional)); }