@Override public Double apply(DoublesPair tk) { double dfBase = baseDiscountFactors.discountFactor(tk.getFirst()); double dfCounter = counterDiscountFactors.discountFactor(tk.getFirst()); double forward = todayFx * dfBase / dfCounter; return volatilities.volatility(currencyPair, tk.getFirst(), tk.getSecond(), forward); } };
@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case 97440432: // first return ((DoublesPair) bean).getFirst(); case -906279820: // second return ((DoublesPair) bean).getSecond(); } return super.propertyGet(bean, propertyName, quiet); }
/** * Computes the z-value for the specified pair of x-value and y-value. * * @param xyPair the pair of x-value and y-value to find the z-value for * @return the value at the x/y point */ public default double zValue(DoublesPair xyPair) { return zValue(xyPair.getFirst(), xyPair.getSecond()); }
/** * Computes the sensitivity of the z-value with respect to the surface parameters. * <p> * This returns an array with one element for each x-y parameter of the surface. * The array contains one sensitivity value for each parameter used to create the surface. * * @param xyPair the pair of x-value and y-value at which the parameter sensitivity is computed * @return the sensitivity at the x/y/ point * @throws RuntimeException if the sensitivity cannot be calculated */ public default UnitParameterSensitivity zValueParameterSensitivity(DoublesPair xyPair) { return zValueParameterSensitivity(xyPair.getFirst(), xyPair.getSecond()); }
@Test(dataProvider = "parseGood") public void test_parse_good(String text, double first, double second) { DoublesPair test = DoublesPair.parse(text); assertEquals(test.getFirst(), first, TOLERANCE); assertEquals(test.getSecond(), second, TOLERANCE); }
@Test(dataProvider = "factory") public void test_of_getters(double first, double second) { DoublesPair test = DoublesPair.of(first, second); assertEquals(test.getFirst(), first, TOLERANCE); assertEquals(test.getSecond(), second, TOLERANCE); }
@Override public DoubleArray evaluate(final DoublesPair xy, final DoubleArray parameters) { double a = parameters.get(0); double b = parameters.get(1); double c = parameters.get(2); DoubleArray res = DoubleArray.of( Math.sin(b * xy.getFirst() + c * xy.getSecond()), xy.getFirst() * a * Math.cos(b * xy.getFirst() + c * xy.getSecond()), xy.getSecond() * a * Math.cos(b * xy.getFirst() + c * xy.getSecond())); return res; }
@Test(dataProvider = "factory") public void test_ofPair(double first, double second) { Pair<Double, Double> pair = Pair.of(first, second); DoublesPair test = DoublesPair.ofPair(pair); assertEquals(test.getFirst(), first, TOLERANCE); assertEquals(test.getSecond(), second, TOLERANCE); }
static SecurityPosition parseSecurityPosition(CsvRow row, PositionInfo info, PositionCsvInfoResolver resolver) { String securityIdScheme = row.findValue(SECURITY_ID_SCHEME_FIELD).orElse(DEFAULT_SECURITY_SCHEME); String securityIdValue = row.getValue(SECURITY_ID_FIELD); SecurityId securityId = SecurityId.of(securityIdScheme, securityIdValue); DoublesPair quantity = CsvLoaderUtils.parseQuantity(row); SecurityPosition position = SecurityPosition.ofLongShort(info, securityId, quantity.getFirst(), quantity.getSecond()); return resolver.completePosition(row, position); }
@Override public double rate( IborInterpolatedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider) { IborIndexObservation obs1 = computation.getShortObservation(); IborIndexObservation obs2 = computation.getLongObservation(); IborIndexRates rates1 = provider.iborIndexRates(obs1.getIndex()); IborIndexRates rates2 = provider.iborIndexRates(obs2.getIndex()); double rate1 = rates1.rate(obs1); double rate2 = rates2.rate(obs2); DoublesPair weights = weights(obs1, obs2, endDate); return ((rate1 * weights.getFirst()) + (rate2 * weights.getSecond())) / (weights.getFirst() + weights.getSecond()); }
@Override public ValueDerivatives apply(DoublesPair x) { double price = BlackFormulaRepository.price(spot, x.getSecond(), x.getFirst(), constantVol, true); return ValueDerivatives.of(price, DoubleArray.EMPTY); } };
/** * Parses an ETD future position from the CSV row. * <p> * This is intended to use reference data to find the ETD future security, * returning it as an instance of {@link EtdOptionPosition}. * The reference data lookup uses {@link #parseEtdContractSpec(CsvRow, EtdType)} by default, * however it could be overridden to lookup the security directly in reference data. * * @param row the CSV row * @param info the position info * @return the parsed position * @throws IllegalArgumentException if the row cannot be parsed */ public default Position parseEtdOptionPosition(CsvRow row, PositionInfo info) { EtdContractSpec contract = parseEtdContractSpec(row, EtdType.OPTION); Pair<YearMonth, EtdVariant> variant = CsvLoaderUtils.parseEtdVariant(row, EtdType.OPTION); int version = row.findValue(VERSION_FIELD).map(Integer::parseInt).orElse(DEFAULT_OPTION_VERSION_NUMBER); PutCall putCall = LoaderUtils.parsePutCall(row.getValue(PUT_CALL_FIELD)); double strikePrice = Double.parseDouble(row.getValue(EXERCISE_PRICE_FIELD)); YearMonth underlyingExpiry = row.findValue(UNDERLYING_EXPIRY_FIELD) .map(str -> LoaderUtils.parseYearMonth(str)) .orElse(null); EtdOptionSecurity security = contract.createOption( variant.getFirst(), variant.getSecond(), version, putCall, strikePrice, underlyingExpiry); DoublesPair quantity = CsvLoaderUtils.parseQuantity(row); EtdOptionPosition position = EtdOptionPosition.ofLongShort(info, security, quantity.getFirst(), quantity.getSecond()); return completePosition(row, position, contract); }
@Override public ValueDerivatives apply(DoublesPair x) { double value = 1.5 * SURFACE_ORG.zValue(x) * x.getFirst() * x.getSecond(); DoubleArray derivatives = SURFACE_ORG.zValueParameterSensitivity(x).multipliedBy(1.5 * x.getFirst() * x.getSecond()).getSensitivity(); return ValueDerivatives.of(value, derivatives); } };
/** * Parses an ETD option position from the CSV row without using reference data. * <p> * This returns a {@link SecurityPosition} based on a standard ETD identifier from {@link EtdIdUtils}. * * @param row the CSV row to parse * @param info the position information * @return the loaded positions, position-level errors are captured in the result * @throws IllegalArgumentException if the row cannot be parsed */ public default SecurityPosition parseEtdOptionSecurityPosition(CsvRow row, PositionInfo info) { ExchangeId exchangeId = ExchangeId.of(row.getValue(EXCHANGE_FIELD)); EtdContractCode contractCode = EtdContractCode.of(row.getValue(CONTRACT_CODE_FIELD)); Pair<YearMonth, EtdVariant> variant = CsvLoaderUtils.parseEtdVariant(row, EtdType.OPTION); int version = row.findValue(VERSION_FIELD).map(Integer::parseInt).orElse(DEFAULT_OPTION_VERSION_NUMBER); PutCall putCall = LoaderUtils.parsePutCall(row.getValue(PUT_CALL_FIELD)); double strikePrice = Double.parseDouble(row.getValue(EXERCISE_PRICE_FIELD)); YearMonth underlyingExpiry = row.findValue(UNDERLYING_EXPIRY_FIELD) .map(str -> LoaderUtils.parseYearMonth(str)) .orElse(null); SecurityId securityId = EtdIdUtils.optionId( exchangeId, contractCode, variant.getFirst(), variant.getSecond(), version, putCall, strikePrice, underlyingExpiry); DoublesPair quantity = CsvLoaderUtils.parseQuantity(row); SecurityPosition position = SecurityPosition.ofLongShort(info, securityId, quantity.getFirst(), quantity.getSecond()); return completePosition(row, position); }
@Override public PointSensitivityBuilder rateSensitivity( IborInterpolatedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider) { // computes the dates related to the underlying deposits associated to the indices IborIndexObservation obs1 = computation.getShortObservation(); IborIndexObservation obs2 = computation.getLongObservation(); DoublesPair weights = weights(obs1, obs2, endDate); double totalWeight = weights.getFirst() + weights.getSecond(); IborIndexRates ratesIndex1 = provider.iborIndexRates(obs1.getIndex()); PointSensitivityBuilder sens1 = ratesIndex1.ratePointSensitivity(obs1) .multipliedBy(weights.getFirst() / totalWeight); IborIndexRates ratesIndex2 = provider.iborIndexRates(obs2.getIndex()); PointSensitivityBuilder sens2 = ratesIndex2.ratePointSensitivity(obs2) .multipliedBy(weights.getSecond() / totalWeight); return sens1.combinedWith(sens2); }
@Override public Double evaluate(final DoublesPair xy, final DoubleArray parameters) { assertEquals(3, parameters.size()); final double a = parameters.get(0); final double b = parameters.get(1); final double c = parameters.get(2); return a * Math.sin(b * xy.getFirst() + c * xy.getSecond()) + Math.cos(xy.getSecond()); }
@Override public ValueDerivatives apply(DoublesPair x) { double t = x.getFirst(); double k = x.getSecond(); double r = interestRate.apply(t);
/** * Parses an ETD future position from the CSV row. * <p> * This is intended to use reference data to find the ETD future security, * returning it as an instance of {@link EtdFuturePosition}. * The reference data lookup uses {@link #parseEtdContractSpec(CsvRow, EtdType)} by default, * however it could be overridden to lookup the security directly in reference data. * * @param row the CSV row to parse * @param info the position information * @return the parsed position * @throws IllegalArgumentException if the row cannot be parsed */ public default Position parseEtdFuturePosition(CsvRow row, PositionInfo info) { EtdContractSpec contract = parseEtdContractSpec(row, EtdType.FUTURE); Pair<YearMonth, EtdVariant> variant = CsvLoaderUtils.parseEtdVariant(row, EtdType.FUTURE); EtdFutureSecurity security = contract.createFuture(variant.getFirst(), variant.getSecond()); DoublesPair quantity = CsvLoaderUtils.parseQuantity(row); EtdFuturePosition position = EtdFuturePosition.ofLongShort(info, security, quantity.getFirst(), quantity.getSecond()); return completePosition(row, position, contract); }
/** * Parses an ETD future position from the CSV row without using reference data. * <p> * This returns a {@link SecurityPosition} based on a standard ETD identifier from {@link EtdIdUtils}. * * @param row the CSV row to parse * @param info the position information * @return the loaded positions, position-level errors are captured in the result * @throws IllegalArgumentException if the row cannot be parsed */ public default SecurityPosition parseEtdFutureSecurityPosition(CsvRow row, PositionInfo info) { ExchangeId exchangeId = ExchangeId.of(row.getValue(EXCHANGE_FIELD)); EtdContractCode contractCode = EtdContractCode.of(row.getValue(CONTRACT_CODE_FIELD)); Pair<YearMonth, EtdVariant> variant = CsvLoaderUtils.parseEtdVariant(row, EtdType.FUTURE); SecurityId securityId = EtdIdUtils.futureId(exchangeId, contractCode, variant.getFirst(), variant.getSecond()); DoublesPair quantity = CsvLoaderUtils.parseQuantity(row); SecurityPosition position = SecurityPosition.ofLongShort(info, securityId, quantity.getFirst(), quantity.getSecond()); return completePosition(row, position); }
@Override public double explainRate( IborInterpolatedRateComputation computation, LocalDate startDate, LocalDate endDate, RatesProvider provider, ExplainMapBuilder builder) { IborIndexObservation obs1 = computation.getShortObservation(); IborIndexObservation obs2 = computation.getLongObservation(); DoublesPair weights = weights(obs1, obs2, endDate); IborIndexRates rates1 = provider.iborIndexRates(obs1.getIndex()); IborIndexRates rates2 = provider.iborIndexRates(obs2.getIndex()); rates1.explainRate(obs1, builder, child -> child.put(ExplainKey.WEIGHT, weights.getFirst())); rates2.explainRate(obs2, builder, child -> child.put(ExplainKey.WEIGHT, weights.getSecond())); double rate = rate(computation, startDate, endDate, provider); builder.put(ExplainKey.COMBINED_RATE, rate); return rate; }