Package com.opengamma.analytics.financial.forex.method

Source Code of com.opengamma.analytics.financial.forex.method.PresentValueForexBlackVolatilityNodeSensitivityDataBundle

/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.forex.method;

import org.apache.commons.lang.ObjectUtils;

import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.analytics.math.matrix.DoubleMatrix2D;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
import com.opengamma.util.tuple.ObjectsPair;
import com.opengamma.util.tuple.Pair;

/**
* Class describing the present value sensitivity to a Forex currency pair volatility grid.
*/
public class PresentValueForexBlackVolatilityNodeSensitivityDataBundle {

  /**
   * The currency pair.
   */
  private final Pair<Currency, Currency> _currencyPair;
  /**
   * The volatility sensitivity as a matrix with same dimension as the input. The sensitivity value is in second/domestic currency.
   */
  private final DoubleMatrix2D _vega;
  private final DoubleMatrix1D _expiries;
  private final DoubleMatrix1D _delta;

  /**
   * Constructor with empty sensitivities for a given currency pair.
   * @param ccy1 First currency, not null
   * @param ccy2 Second currency, not null
   * @param numberExpiry The number of expiries, not negative
   * @param numberDelta The number of deltas, not negative
   */
  public PresentValueForexBlackVolatilityNodeSensitivityDataBundle(final Currency ccy1, final Currency ccy2, final int numberExpiry, final int numberDelta) {
    ArgumentChecker.notNull(ccy1, "currency 1");
    ArgumentChecker.notNull(ccy2, "currency 2");
    ArgumentChecker.isTrue(numberExpiry >= 0, "number of expiries must be greater than or equal to zero");
    ArgumentChecker.isTrue(numberDelta >= 0, "number of deltas must be greater than or equal to zero");
    _currencyPair = ObjectsPair.of(ccy1, ccy2);
    _expiries = new DoubleMatrix1D(new double[numberExpiry]);
    _delta = new DoubleMatrix1D(new double[numberDelta]);
    _vega = new DoubleMatrix2D(numberExpiry, numberDelta);
  }

  /**
   * Constructor with initial sensitivities for a given currency pair.
   * @param ccy1 First currency, not null
   * @param ccy2 Second currency, not null
   * @param expiries The expiries for the vega matrix, not null
   * @param delta The deltas for the vega matrix, not null
   * @param vega The initial sensitivity, not null
   */
  public PresentValueForexBlackVolatilityNodeSensitivityDataBundle(final Currency ccy1, final Currency ccy2, final DoubleMatrix1D expiries, final DoubleMatrix1D delta, final DoubleMatrix2D vega) {
    ArgumentChecker.notNull(ccy1, "currency 1");
    ArgumentChecker.notNull(ccy2, "currency 2");
    ArgumentChecker.notNull(expiries, "expiries");
    ArgumentChecker.notNull(delta, "strikes");
    ArgumentChecker.notNull(vega, "Matrix");
    ArgumentChecker.isTrue(vega.getNumberOfRows() == expiries.getNumberOfElements(), "Number of rows did not match number of expiries");
    ArgumentChecker.isTrue(vega.getNumberOfColumns() == delta.getNumberOfElements(), "Number of columns did not match number of delta");
    _currencyPair = ObjectsPair.of(ccy1, ccy2);
    _expiries = expiries;
    _delta = delta;
    _vega = vega;
  }

  /**
   * Gets the currency pair.
   * @return The currency pair.
   */
  public Pair<Currency, Currency> getCurrencyPair() {
    return _currencyPair;
  }

  /**
   * Gets the volatility sensitivity (vega) map.
   * @return The sensitivity.
   */
  public DoubleMatrix2D getVega() {
    return _vega;
  }

  public DoubleMatrix1D getExpiries() {
    return _expiries;
  }

  public DoubleMatrix1D getDelta() {
    return _delta;
  }

  /**
   * Compare two sensitivities with a given tolerance. Return "true" if the currency pairs are the same and all the sensitivities are within the tolerance.
   * @param value1 The first sensitivity.
   * @param value2 The second sensitivity.
   * @param tolerance The tolerance.
   * @return The comparison flag.
   */
  public static boolean compare(final PresentValueForexBlackVolatilityNodeSensitivityDataBundle value1, final PresentValueForexBlackVolatilityNodeSensitivityDataBundle value2,
      final double tolerance) {
    if (!value1._currencyPair.equals(value2._currencyPair)) {
      return false;
    }
    if ((value1._expiries.getNumberOfElements() != value2._expiries.getNumberOfElements()) || (value1._delta.getNumberOfElements() != value2._delta.getNumberOfElements())) {
      return false;
    }
    for (int loopexp = 0; loopexp < value1._expiries.getNumberOfElements(); loopexp++) {
      for (int loopdel = 0; loopdel < value1._delta.getNumberOfElements(); loopdel++) {
        if (value1._vega.getEntry(loopexp, loopdel) - value2._vega.getEntry(loopexp, loopdel) > tolerance) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * Computes the volatility sensitivities with respect to quoted data (ATM, RR, strangle) related to the (strike) node sensitivity.
   * @return The volatility quote sensitivities. The sensitivity figures are in the same currency as the node sensitivity.
   * The first dimension is the expiration and the second dimension the quotes: ATM, Risk Reversal, Strangle.
   */
  public PresentValueForexBlackVolatilityQuoteSensitivityDataBundle quoteSensitivity() {
    final double[][] vegaStrike = getVega().getData();
    final int nbStrike = vegaStrike[0].length;
    final double[][] result = new double[vegaStrike.length][nbStrike];
    final int nbQuote = (vegaStrike[0].length - 1) / 2;
    for (int loopexp = 0; loopexp < vegaStrike.length; loopexp++) {
      result[loopexp][0] = vegaStrike[loopexp][nbQuote]; // ATM
      for (int loopstrike = 0; loopstrike < nbQuote; loopstrike++) {
        result[loopexp][loopstrike + 1] = -vegaStrike[loopexp][loopstrike] / 2.0 + vegaStrike[loopexp][nbStrike - 1 - loopstrike] / 2.0; // Risk Reversal
        result[loopexp][loopstrike + nbQuote + 1] = vegaStrike[loopexp][loopstrike] + vegaStrike[loopexp][nbStrike - 1 - loopstrike]; // Strangle
        result[loopexp][0] += vegaStrike[loopexp][loopstrike] + vegaStrike[loopexp][nbStrike - 1 - loopstrike];
      }
    }
    return new PresentValueForexBlackVolatilityQuoteSensitivityDataBundle(_currencyPair.getFirst(), _currencyPair.getSecond(), _expiries.getData(), _delta.getData(), result);
  }

  //TODO Add possibility to add a sensitivity?

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + _currencyPair.hashCode();
    result = prime * result + _expiries.hashCode();
    result = prime * result + _delta.hashCode();
    result = prime * result + _vega.hashCode();
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final PresentValueForexBlackVolatilityNodeSensitivityDataBundle other = (PresentValueForexBlackVolatilityNodeSensitivityDataBundle) obj;
    if (!ObjectUtils.equals(_currencyPair, other._currencyPair)) {
      return false;
    }
    if (!ObjectUtils.equals(_vega, other._vega)) {
      return false;
    }
    if (!ObjectUtils.equals(_expiries, other._expiries)) {
      return false;
    }
    if (!ObjectUtils.equals(_delta, other._delta)) {
      return false;
    }
    return true;
  }

}
TOP

Related Classes of com.opengamma.analytics.financial.forex.method.PresentValueForexBlackVolatilityNodeSensitivityDataBundle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.