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

com.opengamma.strata.pricer.option.RawOptionData 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.option;

import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.time.Period;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;

import org.joda.beans.ImmutableBean;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaBean;
import org.joda.beans.TypedMetaBean;
import org.joda.beans.gen.BeanDefinition;
import org.joda.beans.gen.PropertyDefinition;
import org.joda.beans.impl.light.LightMetaBean;

import com.google.common.collect.ImmutableList;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.collect.array.DoubleMatrix;
import com.opengamma.strata.collect.tuple.Pair;
import com.opengamma.strata.market.ValueType;

/**
 * Raw data from the volatility market.
 */
@BeanDefinition(style = "light")
public final class RawOptionData
    implements ImmutableBean, Serializable {

  /**
   * The expiry values.
   */
  @PropertyDefinition(validate = "notNull")
  private final ImmutableList expiries;
  /**
   * The strike values. Can be directly strike or moneyness (simple or log)
   */
  @PropertyDefinition(validate = "notNull")
  private final DoubleArray strikes;
  /**
   * The value type of the strike-like dimension.
   */
  @PropertyDefinition(validate = "notNull")
  private final ValueType strikeType;
  /**
   * The data. The values can be model parameters (like Black or normal volatilities) or direct 
   * option prices. The first (outer) dimension is the expiry, the second dimension is the strike.
   * A 'NaN' value indicates that the data is not available.
   */
  @PropertyDefinition(validate = "notNull")
  private final DoubleMatrix data;
  /**
   * The measurement error of the option data.
   * 

* These will be used if the option data is calibrated by a least square method. * {@code data} and {@code error} must have the same number of elements. */ @PropertyDefinition(get = "optional") private final DoubleMatrix error; /** * The type of the raw data. */ @PropertyDefinition(validate = "notNull") private final ValueType dataType; /** * The shift for which the raw data is valid. Used only if the dataType is 'BlackVolatility'. */ @PropertyDefinition(get = "optional") private final Double shift; //------------------------------------------------------------------------- /** * Obtains an instance of the raw volatility. *

* The data values can be model parameters (like Black or normal volatilities) or direct option prices. * * @param expiries the expiries * @param strikes the strikes-like data * @param strikeType the value type of the strike-like dimension * @param data the data * @param dataType the data type * @return the instance */ public static RawOptionData of( List expiries, DoubleArray strikes, ValueType strikeType, DoubleMatrix data, ValueType dataType) { ArgChecker.isTrue(expiries.size() == data.rowCount(), "expiries list should be of the same size as the external data dimension"); for (int i = 0; i < expiries.size(); i++) { ArgChecker.isTrue(strikes.size() == data.columnCount(), "strikes should be of the same size as the inner data dimension"); } return new RawOptionData(expiries, strikes, strikeType, data, null, dataType, 0.0); } /** * Obtains an instance of the raw volatility for shifted Black (log-normal) volatility. * * @param expiries the expiries * @param strikes the strikes-like data * @param strikeType the value type of the strike-like dimension * @param data the data * @param shift the shift * @return the instance */ public static RawOptionData ofBlackVolatility( List expiries, DoubleArray strikes, ValueType strikeType, DoubleMatrix data, Double shift) { ArgChecker.isTrue(expiries.size() == data.rowCount(), "expiries list should be of the same size as the external data dimension"); for (int i = 0; i < expiries.size(); i++) { ArgChecker.isTrue(strikes.size() == data.columnCount(), "strikes should be of the same size as the inner data dimension"); } return new RawOptionData(expiries, strikes, strikeType, data, null, ValueType.BLACK_VOLATILITY, shift); } /** * Obtains an instance of the raw data with error. *

* The data values can be model parameters (like Black or normal volatilities) or direct option prices. * * @param expiries the expiries * @param strikes the strikes-like data * @param strikeType the value type of the strike-like dimension * @param data the data * @param error the error * @param dataType the data type * @return the instance */ public static RawOptionData of( List expiries, DoubleArray strikes, ValueType strikeType, DoubleMatrix data, DoubleMatrix error, ValueType dataType) { ArgChecker.isTrue(expiries.size() == data.rowCount(), "expiries list should be of the same size as the external data dimension"); ArgChecker.isTrue(error.rowCount() == data.rowCount(), "the error row count should be the same as the data raw count"); ArgChecker.isTrue(error.columnCount() == data.columnCount(), "the error column count should the same as the data column count"); for (int i = 0; i < expiries.size(); i++) { ArgChecker.isTrue(strikes.size() == data.columnCount(), "strikes should be of the same size as the inner data dimension"); } return new RawOptionData(expiries, strikes, strikeType, data, error, dataType, 0.0); } /** * Obtains an instance of the raw data with error for shifted Black (log-normal) volatility. * * @param expiries the expiries * @param strikes the strikes-like data * @param strikeType the value type of the strike-like dimension * @param data the data * @param error the error * @param shift the shift * @return the instance */ public static RawOptionData ofBlackVolatility( List expiries, DoubleArray strikes, ValueType strikeType, DoubleMatrix data, DoubleMatrix error, Double shift) { ArgChecker.isTrue(expiries.size() == data.rowCount(), "expiries list should be of the same size as the external data dimension"); for (int i = 0; i < expiries.size(); i++) { ArgChecker.isTrue(strikes.size() == data.columnCount(), "strikes should be of the same size as the inner data dimension"); } return new RawOptionData(expiries, strikes, strikeType, data, error, ValueType.BLACK_VOLATILITY, shift); } //------------------------------------------------------------------------- /** * For a given expiration returns all the data available. * * @param expiry the expiration * @return the strikes and related volatilities for all available data at the given expiration */ public Pair availableSmileAtExpiry(Period expiry) { int index = expiries.indexOf(expiry); ArgChecker.isTrue(index >= 0, "expiry not available"); List strikesAvailable = new ArrayList<>(); List volatilitiesAvailable = new ArrayList<>(); for (int i = 0; i < strikes.size(); i++) { if (!Double.isNaN(data.get(index, i))) { strikesAvailable.add(strikes.get(i)); volatilitiesAvailable.add(data.get(index, i)); } } return Pair.of(DoubleArray.copyOf(strikesAvailable), DoubleArray.copyOf(volatilitiesAvailable)); } //------------------------- AUTOGENERATED START ------------------------- /** * The meta-bean for {@code RawOptionData}. */ private static final TypedMetaBean META_BEAN = LightMetaBean.of( RawOptionData.class, MethodHandles.lookup(), new String[] { "expiries", "strikes", "strikeType", "data", "error", "dataType", "shift"}, ImmutableList.of(), null, null, null, null, null, null); /** * The meta-bean for {@code RawOptionData}. * @return the meta-bean, not null */ public static TypedMetaBean meta() { return META_BEAN; } static { MetaBean.register(META_BEAN); } /** * The serialization version id. */ private static final long serialVersionUID = 1L; private RawOptionData( List expiries, DoubleArray strikes, ValueType strikeType, DoubleMatrix data, DoubleMatrix error, ValueType dataType, Double shift) { JodaBeanUtils.notNull(expiries, "expiries"); JodaBeanUtils.notNull(strikes, "strikes"); JodaBeanUtils.notNull(strikeType, "strikeType"); JodaBeanUtils.notNull(data, "data"); JodaBeanUtils.notNull(dataType, "dataType"); this.expiries = ImmutableList.copyOf(expiries); this.strikes = strikes; this.strikeType = strikeType; this.data = data; this.error = error; this.dataType = dataType; this.shift = shift; } @Override public TypedMetaBean metaBean() { return META_BEAN; } //----------------------------------------------------------------------- /** * Gets the expiry values. * @return the value of the property, not null */ public ImmutableList getExpiries() { return expiries; } //----------------------------------------------------------------------- /** * Gets the strike values. Can be directly strike or moneyness (simple or log) * @return the value of the property, not null */ public DoubleArray getStrikes() { return strikes; } //----------------------------------------------------------------------- /** * Gets the value type of the strike-like dimension. * @return the value of the property, not null */ public ValueType getStrikeType() { return strikeType; } //----------------------------------------------------------------------- /** * Gets the data. The values can be model parameters (like Black or normal volatilities) or direct * option prices. The first (outer) dimension is the expiry, the second dimension is the strike. * A 'NaN' value indicates that the data is not available. * @return the value of the property, not null */ public DoubleMatrix getData() { return data; } //----------------------------------------------------------------------- /** * Gets the measurement error of the option data. *

* These will be used if the option data is calibrated by a least square method. * {@code data} and {@code error} must have the same number of elements. * @return the optional value of the property, not null */ public Optional getError() { return Optional.ofNullable(error); } //----------------------------------------------------------------------- /** * Gets the type of the raw data. * @return the value of the property, not null */ public ValueType getDataType() { return dataType; } //----------------------------------------------------------------------- /** * Gets the shift for which the raw data is valid. Used only if the dataType is 'BlackVolatility'. * @return the optional value of the property, not null */ public OptionalDouble getShift() { return shift != null ? OptionalDouble.of(shift) : OptionalDouble.empty(); } //----------------------------------------------------------------------- @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj != null && obj.getClass() == this.getClass()) { RawOptionData other = (RawOptionData) obj; return JodaBeanUtils.equal(expiries, other.expiries) && JodaBeanUtils.equal(strikes, other.strikes) && JodaBeanUtils.equal(strikeType, other.strikeType) && JodaBeanUtils.equal(data, other.data) && JodaBeanUtils.equal(error, other.error) && JodaBeanUtils.equal(dataType, other.dataType) && JodaBeanUtils.equal(shift, other.shift); } return false; } @Override public int hashCode() { int hash = getClass().hashCode(); hash = hash * 31 + JodaBeanUtils.hashCode(expiries); hash = hash * 31 + JodaBeanUtils.hashCode(strikes); hash = hash * 31 + JodaBeanUtils.hashCode(strikeType); hash = hash * 31 + JodaBeanUtils.hashCode(data); hash = hash * 31 + JodaBeanUtils.hashCode(error); hash = hash * 31 + JodaBeanUtils.hashCode(dataType); hash = hash * 31 + JodaBeanUtils.hashCode(shift); return hash; } @Override public String toString() { StringBuilder buf = new StringBuilder(256); buf.append("RawOptionData{"); buf.append("expiries").append('=').append(JodaBeanUtils.toString(expiries)).append(',').append(' '); buf.append("strikes").append('=').append(JodaBeanUtils.toString(strikes)).append(',').append(' '); buf.append("strikeType").append('=').append(JodaBeanUtils.toString(strikeType)).append(',').append(' '); buf.append("data").append('=').append(JodaBeanUtils.toString(data)).append(',').append(' '); buf.append("error").append('=').append(JodaBeanUtils.toString(error)).append(',').append(' '); buf.append("dataType").append('=').append(JodaBeanUtils.toString(dataType)).append(',').append(' '); buf.append("shift").append('=').append(JodaBeanUtils.toString(shift)); buf.append('}'); return buf.toString(); } //-------------------------- AUTOGENERATED END -------------------------- }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy