All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.opengamma.strata.pricer.fxopt.ImpliedTrinomialTreeFxOptionCalibrator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.strata.pricer.fxopt;

import java.util.function.Function;

import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyPair;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.tuple.DoublesPair;
import com.opengamma.strata.pricer.DiscountFactors;
import com.opengamma.strata.pricer.impl.volatility.local.ImpliedTrinomialTreeLocalVolatilityCalculator;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.product.fxopt.ResolvedFxVanillaOption;

/**
 * Utilities to calibrate implied trinomial tree to Black volatilities of FX options.
 */
public class ImpliedTrinomialTreeFxOptionCalibrator {

  /**
   * Number of time steps.
   */
  private final int nSteps;

  /**
   * Calibrator with the specified number of time steps.
   * 
   * @param nSteps  number of time steps
   */
  public ImpliedTrinomialTreeFxOptionCalibrator(int nSteps) {
    ArgChecker.isTrue(nSteps > 1, "the number of steps should be greater than 1");
    this.nSteps = nSteps;
  }

  //-------------------------------------------------------------------------
  /**
   * Obtains number of time steps.
   * 
   * @return number of time steps
   */
  public int getNumberOfSteps() {
    return nSteps;
  }

  //-------------------------------------------------------------------------
  /**
   * Calibrate trinomial tree to Black volatilities by using a vanilla option.
   * 

* {@code ResolvedFxVanillaOption} is typically the underlying option of an exotic instrument to price using the * calibrated tree, and is used to ensure that the grid points properly cover the lifetime of the target option. * * @param option the vanilla option * @param ratesProvider the rates provider * @param volatilities the Black volatility provider * @return the trinomial tree data */ public RecombiningTrinomialTreeData calibrateTrinomialTree( ResolvedFxVanillaOption option, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities) { double timeToExpiry = volatilities.relativeTime(option.getExpiry()); CurrencyPair currencyPair = option.getUnderlying().getCurrencyPair(); return calibrateTrinomialTree(timeToExpiry, currencyPair, ratesProvider, volatilities); } /** * Calibrate trinomial tree to Black volatilities. *

* {@code timeToExpiry} determines the coverage of the resulting trinomial tree. * Thus this should match the time to expiry of the target instrument to price using the calibrated tree. * * @param timeToExpiry the time to expiry * @param currencyPair the currency pair * @param ratesProvider the rates provider * @param volatilities the Black volatility provider * @return the trinomial tree data */ public RecombiningTrinomialTreeData calibrateTrinomialTree( double timeToExpiry, CurrencyPair currencyPair, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities) { validate(ratesProvider, volatilities); if (timeToExpiry <= 0d) { throw new IllegalArgumentException("option expired"); } Currency ccyBase = currencyPair.getBase(); Currency ccyCounter = currencyPair.getCounter(); double todayFx = ratesProvider.fxRate(currencyPair); DiscountFactors baseDiscountFactors = ratesProvider.discountFactors(ccyBase); DiscountFactors counterDiscountFactors = ratesProvider.discountFactors(ccyCounter); Function interestRate = new Function() { @Override public Double apply(Double t) { return counterDiscountFactors.zeroRate(t); } }; Function dividendRate = new Function() { @Override public Double apply(Double t) { return baseDiscountFactors.zeroRate(t); } }; Function impliedVolSurface = new Function() { @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); } }; ImpliedTrinomialTreeLocalVolatilityCalculator localVol = new ImpliedTrinomialTreeLocalVolatilityCalculator(nSteps, timeToExpiry); return localVol.calibrateImpliedVolatility(impliedVolSurface, todayFx, interestRate, dividendRate); } //------------------------------------------------------------------------- private void validate( RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities) { ArgChecker.isTrue( ratesProvider.getValuationDate().isEqual(volatilities.getValuationDateTime().toLocalDate()), "Volatility and rate data must be for the same date"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy