public virtual void test_cloned() { FxOptionSensitivity @base = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity test = @base.cloned(); assertSame(test, @base); }
public virtual void test_build() { FxOptionSensitivity @base = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); PointSensitivities test = @base.build(); assertEquals(test.Sensitivities, ImmutableList.of(@base)); }
public virtual void test_compareExcludingSensitivity() { FxOptionSensitivity a1 = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity a2 = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity b = FxOptionSensitivity.of(NAME, CurrencyPair.of(EUR, USD), EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity c = FxOptionSensitivity.of(NAME, PAIR, EXPIRY + 1, STRIKE, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity d = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, 0.96, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity e = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, 0.81, GBP, SENSI_VALUE); FxOptionSensitivity f = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, EUR, SENSI_VALUE); ZeroRateSensitivity other = ZeroRateSensitivity.of(GBP, 2d, 32d); assertEquals(a1.compareKey(a2), 0); assertEquals(a1.compareKey(b) < 0, true); assertEquals(b.compareKey(a1) > 0, true); assertEquals(a1.compareKey(c) < 0, true); assertEquals(c.compareKey(a1) > 0, true); assertEquals(a1.compareKey(d) < 0, true); assertEquals(d.compareKey(a1) > 0, true); assertEquals(a1.compareKey(e) < 0, true); assertEquals(e.compareKey(a1) > 0, true); assertEquals(a1.compareKey(f) > 0, true); assertEquals(f.compareKey(a1) < 0, true); assertEquals(a1.compareKey(other) < 0, true); assertEquals(other.compareKey(a1) > 0, true); }
private CurrencyParameterSensitivity parameterSensitivity(FxOptionSensitivity point) { double expiryTime = point.Expiry; double strike = currencyPair.isInverse(point.CurrencyPair) ? 1d / point.Strike : point.Strike; double forward = currencyPair.isInverse(point.CurrencyPair) ? 1d / point.Forward : point.Forward; double pointValue = point.Sensitivity; DoubleMatrix bucketedSensi = smile.volatilityAndSensitivities(expiryTime, strike, forward).Sensitivities; double[] times = smile.Expiries.toArray(); int nTimes = times.Length; IList <double> sensiList = new List <double>(); IList <ParameterMetadata> paramList = new List <ParameterMetadata>(); for (int i = 0; i < nTimes; ++i) { DoubleArray deltas = smile.VolatilityTerm.get(i).Delta; int nDeltas = deltas.size(); int nDeltasTotal = 2 * nDeltas + 1; double[] deltasTotal = new double[nDeltasTotal]; // absolute delta deltasTotal[nDeltas] = 0.5d; for (int j = 0; j < nDeltas; ++j) { deltasTotal[j] = 1d - deltas.get(j); deltasTotal[2 * nDeltas - j] = deltas.get(j); } for (int j = 0; j < nDeltasTotal; ++j) { sensiList.Add(bucketedSensi.get(i, j) * pointValue); DeltaStrike absoluteDelta = DeltaStrike.of(deltasTotal[j]); ParameterMetadata parameterMetadata = FxVolatilitySurfaceYearFractionParameterMetadata.of(times[i], absoluteDelta, currencyPair); paramList.Add(parameterMetadata); } } return(CurrencyParameterSensitivity.of(name, paramList, point.Currency, DoubleArray.copyOf(sensiList))); }
private CurrencyParameterSensitivity parameterSensitivity(FxOptionSensitivity point) { double expiry = point.Expiry; UnitParameterSensitivity unitSens = curve.yValueParameterSensitivity(expiry); return(unitSens.multipliedBy(point.Currency, point.Sensitivity)); }
public virtual void test_mapSensitivity() { FxOptionSensitivity @base = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity expected = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, 1.0 / SENSI_VALUE); FxOptionSensitivity test = @base.mapSensitivity(s => 1 / s); assertEquals(test, expected); }
private CurrencyParameterSensitivity parameterSensitivity(FxOptionSensitivity point) { double expiry = point.Expiry; double strike = point.CurrencyPair.isInverse(currencyPair) ? 1d / point.Strike : point.Strike; UnitParameterSensitivity unitSens = surface.zValueParameterSensitivity(expiry, strike); return(unitSens.multipliedBy(point.Currency, point.Sensitivity)); }
public int compareKey(PointSensitivity other) { if (other is FxOptionSensitivity) { FxOptionSensitivity otherOption = (FxOptionSensitivity)other; return(ComparisonChain.start().compare(volatilitiesName, otherOption.volatilitiesName).compare(currencyPair.ToString(), otherOption.currencyPair.ToString()).compare(expiry, otherOption.expiry).compare(strike, otherOption.strike).compare(forward, otherOption.forward).compare(currency, otherOption.currency).result()); } return(this.GetType().Name.CompareTo(other.GetType().Name)); }
public virtual void test_multipliedBy() { FxOptionSensitivity @base = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); double factor = 5.2d; FxOptionSensitivity expected = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE * factor); FxOptionSensitivity test = @base.multipliedBy(factor); assertEquals(test, expected); }
public virtual void test_buildInto() { FxOptionSensitivity @base = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); MutablePointSensitivities combo = new MutablePointSensitivities(); MutablePointSensitivities test = @base.buildInto(combo); assertSame(test, combo); assertEquals(test.Sensitivities, ImmutableList.of(@base)); }
public virtual void coverage() { FxOptionSensitivity test1 = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); coverImmutableBean(test1); FxOptionSensitivity test2 = FxOptionSensitivity.of(NAME2, CurrencyPair.of(EUR, USD), EXPIRY, 0.8, 0.9, EUR, 1.1); coverBeanEquals(test1, test2); }
public virtual void test_of() { FxOptionSensitivity test = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); assertEquals(test.Currency, GBP); assertEquals(test.Expiry, EXPIRY); assertEquals(test.Forward, FORWARD); assertEquals(test.CurrencyPair, PAIR); assertEquals(test.Sensitivity, SENSI_VALUE); assertEquals(test.Strike, STRIKE); }
public virtual void test_withSensitivity() { FxOptionSensitivity @base = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); double newSensi = 22.5; FxOptionSensitivity test = @base.withSensitivity(newSensi); assertEquals(test.Currency, GBP); assertEquals(test.Expiry, EXPIRY); assertEquals(test.Forward, FORWARD); assertEquals(test.CurrencyPair, PAIR); assertEquals(test.Sensitivity, newSensi); assertEquals(test.Strike, STRIKE); }
//----------------------------------------------------------------------- public override bool Equals(object obj) { if (obj == this) { return(true); } if (obj != null && obj.GetType() == this.GetType()) { FxOptionSensitivity other = (FxOptionSensitivity)obj; return(JodaBeanUtils.equal(volatilitiesName, other.volatilitiesName) && JodaBeanUtils.equal(currencyPair, other.currencyPair) && JodaBeanUtils.equal(expiry, other.expiry) && JodaBeanUtils.equal(strike, other.strike) && JodaBeanUtils.equal(forward, other.forward) && JodaBeanUtils.equal(currency, other.currency) && JodaBeanUtils.equal(sensitivity, other.sensitivity)); } return(false); }
/// <summary> /// Computes the present value sensitivity to the black volatility used in the pricing. /// <para> /// The result is a single sensitivity to the volatility used. /// /// </para> /// </summary> /// <param name="option"> the option product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the Black volatility provider </param> /// <returns> the present value sensitivity </returns> public virtual PointSensitivityBuilder presentValueSensitivityModelParamsVolatility(ResolvedFxVanillaOption option, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities) { if (volatilities.relativeTime(option.Expiry) <= 0d) { return(PointSensitivityBuilder.none()); } ResolvedFxSingle underlying = option.Underlying; FxRate forward = fxPricer.forwardFxRate(underlying, ratesProvider); CurrencyPair strikePair = underlying.CurrencyPair; CurrencyAmount valueVega = presentValueVega(option, ratesProvider, volatilities); return(FxOptionSensitivity.of(volatilities.Name, strikePair, volatilities.relativeTime(option.Expiry), option.Strike, forward.fxRate(strikePair), valueVega.Currency, valueVega.Amount)); }
//------------------------------------------------------------------------- public virtual void test_presentValueSensitivityBlackVolatility() { FxOptionSensitivity computedCall = (FxOptionSensitivity)PRICER.presentValueSensitivityModelParamsVolatility(CALL_OTM, RATES_PROVIDER, VOLS); FxOptionSensitivity computedPut = (FxOptionSensitivity)PRICER.presentValueSensitivityModelParamsVolatility(PUT_ITM, RATES_PROVIDER, VOLS); double timeToExpiry = VOLS.relativeTime(EXPIRY); double df = RATES_PROVIDER.discountFactor(USD, PAYMENT_DATE); double forward = PRICER.DiscountingFxSingleProductPricer.forwardFxRate(FX_PRODUCT_HIGH, RATES_PROVIDER).fxRate(CURRENCY_PAIR); double vol = SMILE_TERM.volatility(timeToExpiry, STRIKE_RATE_HIGH, forward); FxOptionSensitivity expected = FxOptionSensitivity.of(VOLS.Name, CURRENCY_PAIR, timeToExpiry, STRIKE_RATE_HIGH, forward, USD, -NOTIONAL * df * BlackFormulaRepository.vega(forward, STRIKE_RATE_HIGH, timeToExpiry, vol)); assertTrue(computedCall.build().equalWithTolerance(expected.build(), NOTIONAL * TOL)); assertTrue(computedPut.build().equalWithTolerance(expected.build().multipliedBy(-1d), NOTIONAL * TOL)); }
public virtual void test_withCurrency() { FxOptionSensitivity @base = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); FxOptionSensitivity test1 = @base.withCurrency(EUR); assertEquals(test1.Currency, EUR); assertEquals(test1.Expiry, EXPIRY); assertEquals(test1.Forward, FORWARD); assertEquals(test1.CurrencyPair, PAIR); assertEquals(test1.Sensitivity, SENSI_VALUE); assertEquals(test1.Strike, STRIKE); FxOptionSensitivity test2 = @base.withCurrency(GBP); assertEquals(test2, @base); }
public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities) { CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty(); foreach (PointSensitivity point in pointSensitivities.Sensitivities) { if (point is FxOptionSensitivity) { FxOptionSensitivity pt = (FxOptionSensitivity)point; if (pt.VolatilitiesName.Equals(Name)) { sens = sens.combinedWith(parameterSensitivity(pt)); } } } return(sens); }
public virtual void test_parameterSensitivity_inverse() { for (int i = 0; i < NB_EXPIRY; i++) { for (int j = 0; j < NB_STRIKE; ++j) { double timeToExpiry = VOLS.relativeTime(TEST_EXPIRY[i]); FxOptionSensitivity sensi = FxOptionSensitivity.of(VOLS.Name, CURRENCY_PAIR.inverse(), timeToExpiry, 1d / TEST_STRIKE[j], 1d / FORWARD[i], GBP, 1d); CurrencyParameterSensitivities computed = VOLS.parameterSensitivity(sensi); for (int k = 0; k < TIMES.size(); k++) { double value = computed.Sensitivities.get(0).Sensitivity.get(k); double nodeExpiry = TIMES.get(k); double expected = nodeSensitivity(VOLS, CURRENCY_PAIR.inverse(), TEST_EXPIRY[i], 1d / TEST_STRIKE[j], 1d / FORWARD[i], nodeExpiry); assertEquals(value, expected, EPS); } } } }
//------------------------------------------------------------------------- /// <summary> /// Computes the present value sensitivity to the black volatility used in the pricing. /// <para> /// The result is a single sensitivity to the volatility used. This is also called Black vega. /// /// </para> /// </summary> /// <param name="option"> the option product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the Black volatility provider </param> /// <returns> the present value sensitivity </returns> public virtual PointSensitivityBuilder presentValueSensitivityModelParamsVolatility(ResolvedFxSingleBarrierOption option, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities) { ResolvedFxVanillaOption underlyingOption = option.UnderlyingOption; if (volatilities.relativeTime(underlyingOption.Expiry) <= 0d) { return(PointSensitivityBuilder.none()); } ValueDerivatives priceDerivatives = this.priceDerivatives(option, ratesProvider, volatilities); ResolvedFxSingle underlyingFx = underlyingOption.Underlying; CurrencyPair currencyPair = underlyingFx.CurrencyPair; Currency ccyBase = currencyPair.Base; Currency ccyCounter = currencyPair.Counter; double dfBase = ratesProvider.discountFactor(ccyBase, underlyingFx.PaymentDate); double dfCounter = ratesProvider.discountFactor(ccyCounter, underlyingFx.PaymentDate); double todayFx = ratesProvider.fxRate(currencyPair); double forward = todayFx * dfBase / dfCounter; return(FxOptionSensitivity.of(volatilities.Name, currencyPair, volatilities.relativeTime(underlyingOption.Expiry), underlyingOption.Strike, forward, ccyCounter, priceDerivatives.getDerivative(4) * signedNotional(underlyingOption))); }
//------------------------------------------------------------------------- public virtual void test_nodeSensitivity() { for (int i = 0; i < NB_EXPIRY; i++) { for (int j = 0; j < NB_STRIKE; ++j) { double timeToExpiry = VOLS.relativeTime(TEST_EXPIRY[i]); FxOptionSensitivity sensi = FxOptionSensitivity.of(VOLS.Name, CURRENCY_PAIR, timeToExpiry, TEST_STRIKE[j], FORWARD[i], GBP, 1d); CurrencyParameterSensitivities computed = VOLS.parameterSensitivity(sensi); for (int k = 0; k < SURFACE.ParameterCount; k++) { double value = computed.Sensitivities.get(0).Sensitivity.get(k); double nodeExpiry = SURFACE.XValues.get(k); double nodeStrike = SURFACE.YValues.get(k); double expected = nodeSensitivity(VOLS, CURRENCY_PAIR, TEST_EXPIRY[i], TEST_STRIKE[j], FORWARD[i], nodeExpiry, nodeStrike); assertEquals(value, expected, EPS); } } } }
public virtual void test_surfaceParameterSensitivity_inverse() { for (int i = 0; i < NB_EXPIRY; i++) { for (int j = 0; j < NB_STRIKE; ++j) { double timeToExpiry = VOLS.relativeTime(TEST_EXPIRY[i]); FxOptionSensitivity sensi = FxOptionSensitivity.of(VOLS.Name, CURRENCY_PAIR.inverse(), timeToExpiry, 1d / TEST_STRIKE[j], 1d / FORWARD[i], GBP, 1d); CurrencyParameterSensitivity computed = VOLS.parameterSensitivity(sensi).Sensitivities.get(0); IEnumerator <ParameterMetadata> itr = computed.ParameterMetadata.GetEnumerator(); foreach (double value in computed.Sensitivity.toArray()) { //JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops: FxVolatilitySurfaceYearFractionParameterMetadata meta = ((FxVolatilitySurfaceYearFractionParameterMetadata)itr.next()); double nodeExpiry = meta.YearFraction; double nodeDelta = meta.Strike.Value; double expected = nodeSensitivity(VOLS, CURRENCY_PAIR.inverse(), TEST_EXPIRY[i], 1d / TEST_STRIKE[j], 1d / FORWARD[i], nodeExpiry, nodeDelta); assertEquals(value, expected, EPS); } } } }
/// <summary> /// Computes the present value sensitivity to the black volatilities used in the pricing. /// <para> /// The implied strikes and weights are fixed in this sensitivity computation. /// /// </para> /// </summary> /// <param name="option"> the option product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the Black volatility provider </param> /// <returns> the present value sensitivity </returns> public virtual PointSensitivityBuilder presentValueSensitivityModelParamsVolatility(ResolvedFxVanillaOption option, RatesProvider ratesProvider, BlackFxOptionSmileVolatilities volatilities) { validate(ratesProvider, volatilities); double timeToExpiry = volatilities.relativeTime(option.Expiry); if (timeToExpiry <= 0d) { return(PointSensitivityBuilder.none()); } ResolvedFxSingle underlyingFx = option.Underlying; Currency ccyCounter = option.CounterCurrency; double df = ratesProvider.discountFactor(ccyCounter, underlyingFx.PaymentDate); FxRate forward = fxPricer.forwardFxRate(underlyingFx, ratesProvider); CurrencyPair currencyPair = underlyingFx.CurrencyPair; double forwardRate = forward.fxRate(currencyPair); double strikeRate = option.Strike; SmileDeltaParameters smileAtTime = volatilities.Smile.smileForExpiry(timeToExpiry); double[] strikes = smileAtTime.strike(forwardRate).toArray(); double[] vols = smileAtTime.Volatility.toArray(); double volAtm = vols[1]; double[] x = vannaVolgaWeights(forwardRate, strikeRate, timeToExpiry, volAtm, strikes); double vegaAtm = BlackFormulaRepository.vega(forwardRate, strikeRate, timeToExpiry, volAtm); double signedNotional = this.signedNotional(option); PointSensitivityBuilder sensiSmile = PointSensitivityBuilder.none(); for (int i = 0; i < 3; i += 2) { double vegaFwdAtm = BlackFormulaRepository.vega(forwardRate, strikes[i], timeToExpiry, volAtm); vegaAtm -= x[i] * vegaFwdAtm; double vegaFwdSmile = BlackFormulaRepository.vega(forwardRate, strikes[i], timeToExpiry, vols[i]); sensiSmile = sensiSmile.combinedWith(FxOptionSensitivity.of(volatilities.Name, currencyPair, timeToExpiry, strikes[i], forwardRate, ccyCounter, df * signedNotional * x[i] * vegaFwdSmile)); } FxOptionSensitivity sensiAtm = FxOptionSensitivity.of(volatilities.Name, currencyPair, timeToExpiry, strikes[1], forwardRate, ccyCounter, df * signedNotional * vegaAtm); return(sensiAtm.combinedWith(sensiSmile)); }
//------------------------------------------------------------------------- public virtual void test_presentValueSensitivityVolatility() { for (int i = 0; i < NB_STRIKES; ++i) { PointSensitivities computedCall = PRICER.presentValueSensitivityModelParamsVolatility(CALLS[i], RATES_PROVIDER, VOLS).build(); double timeToExpiry = VOLS.relativeTime(EXPIRY); FxRate forward = FX_PRICER.forwardFxRate(UNDERLYING[i], RATES_PROVIDER); double forwardRate = forward.fxRate(CURRENCY_PAIR); double strikeRate = CALLS[i].Strike; SmileDeltaParameters smileAtTime = VOLS.Smile.smileForExpiry(timeToExpiry); double[] strikes = smileAtTime.strike(forwardRate).toArray(); double[] vols = smileAtTime.Volatility.toArray(); double df = RATES_PROVIDER.discountFactor(USD, PAY); double[] weights = this.weights(forwardRate, strikeRate, strikes, timeToExpiry, vols[1]); double[] vegas = new double[3]; vegas[2] = BlackFormulaRepository.vega(forwardRate, strikeRate, timeToExpiry, vols[1]) * df * NOTIONAL; for (int j = 0; j < 3; j += 2) { vegas[2] -= weights[j] * NOTIONAL *df *BlackFormulaRepository.vega(forwardRate, strikes[j], timeToExpiry, vols[1]); } vegas[0] = weights[0] * NOTIONAL *df *BlackFormulaRepository.vega(forwardRate, strikes[0], timeToExpiry, vols[0]); vegas[1] = weights[2] * NOTIONAL *df *BlackFormulaRepository.vega(forwardRate, strikes[2], timeToExpiry, vols[2]); double[] expStrikes = new double[] { strikes[0], strikes[2], strikes[1] }; for (int j = 0; j < 3; ++j) { FxOptionSensitivity sensi = (FxOptionSensitivity)computedCall.Sensitivities.get(j); assertEquals(sensi.Sensitivity, vegas[j], TOL * NOTIONAL); assertEquals(sensi.Strike, expStrikes[j], TOL); assertEquals(sensi.Forward, forwardRate, TOL); assertEquals(sensi.Currency, USD); assertEquals(sensi.CurrencyPair, CURRENCY_PAIR); assertEquals(sensi.Expiry, timeToExpiry); } } }
public virtual void test_serialization() { FxOptionSensitivity test = FxOptionSensitivity.of(NAME, PAIR, EXPIRY, STRIKE, FORWARD, GBP, SENSI_VALUE); assertSerialization(test); }