com.opengamma.strata.measure.rate.DefaultRatesMarketDataLookup.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.strata.measure.rate.DefaultRatesMarketDataLookup.java

Source

/**
 * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.strata.measure.rate;

import static com.opengamma.strata.collect.Guavate.toImmutableSet;

import java.io.Serializable;
import java.util.Map;
import java.util.Set;

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

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.FxRateProvider;
import com.opengamma.strata.basics.index.Index;
import com.opengamma.strata.calc.CalculationRules;
import com.opengamma.strata.calc.runner.CalculationParameter;
import com.opengamma.strata.calc.runner.FunctionRequirements;
import com.opengamma.strata.collect.Messages;
import com.opengamma.strata.data.MarketData;
import com.opengamma.strata.data.MarketDataId;
import com.opengamma.strata.data.ObservableId;
import com.opengamma.strata.data.ObservableSource;
import com.opengamma.strata.data.scenario.ScenarioMarketData;
import com.opengamma.strata.market.curve.CurveId;
import com.opengamma.strata.market.observable.IndexQuoteId;
import com.opengamma.strata.pricer.rate.RatesProvider;

/**
 * The rates lookup, used to select curves for pricing.
 * <p>
 * This provides access to discount curves and forward curves.
 * <p>
 * The lookup implements {@link CalculationParameter} and is used by passing it
 * as an argument to {@link CalculationRules}. It provides the link between the
 * data that the function needs and the data that is available in {@link ScenarioMarketData}.
 */
@BeanDefinition(style = "light")
final class DefaultRatesMarketDataLookup implements RatesMarketDataLookup, ImmutableBean, Serializable {

    /**
     * The discount curves in the group, keyed by currency.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<Currency, CurveId> discountCurves;
    /**
     * The forward curves in the group, keyed by index.
     */
    @PropertyDefinition(validate = "notNull", builderType = "Map<? extends Index, CurveId>")
    private final ImmutableMap<Index, CurveId> forwardCurves;
    /**
     * The source of market data for quotes and other observable market data.
     */
    @PropertyDefinition(validate = "notNull")
    private final ObservableSource observableSource;
    /**
     * The lookup used to obtain {@code FxRateProvider}.
     */
    @PropertyDefinition(validate = "notNull")
    private final FxRateLookup fxLookup;

    //-------------------------------------------------------------------------
    /**
     * Obtains an instance based on a map of discount and forward curve identifiers.
     * <p>
     * The discount and forward curves refer to the curve identifier.
     * The curves themselves are provided in {@link ScenarioMarketData}
     * using {@link CurveId} as the identifier.
     * 
     * @param discountCurveIds  the discount curve identifiers, keyed by currency
     * @param forwardCurveIds  the forward curves identifiers, keyed by index
     * @param obsSource  the source of market data for FX, quotes and other observable market data
     * @param fxLookup  the lookup used to obtain FX rates
     * @return the rates lookup containing the specified curves
     */
    public static DefaultRatesMarketDataLookup of(Map<Currency, CurveId> discountCurveIds,
            Map<? extends Index, CurveId> forwardCurveIds, ObservableSource obsSource, FxRateLookup fxLookup) {

        return new DefaultRatesMarketDataLookup(discountCurveIds, forwardCurveIds, obsSource, fxLookup);
    }

    //-------------------------------------------------------------------------
    @Override
    public ImmutableSet<Currency> getDiscountCurrencies() {
        return discountCurves.keySet();
    }

    @Override
    public ImmutableSet<MarketDataId<?>> getDiscountMarketDataIds(Currency currency) {
        CurveId id = discountCurves.get(currency);
        if (id == null) {
            throw new IllegalArgumentException(msgCurrencyNotFound(currency));
        }
        return ImmutableSet.of(id);
    }

    @Override
    public ImmutableSet<Index> getForwardIndices() {
        return forwardCurves.keySet();
    }

    @Override
    public ImmutableSet<MarketDataId<?>> getForwardMarketDataIds(Index index) {
        CurveId id = forwardCurves.get(index);
        if (id == null) {
            throw new IllegalArgumentException(msgIndexNotFound(index));
        }
        return ImmutableSet.of(id);
    }

    //-------------------------------------------------------------------------
    @Override
    public FunctionRequirements requirements(Set<Currency> currencies, Set<? extends Index> indices) {
        for (Currency currency : currencies) {
            if (!discountCurves.keySet().contains(currency)) {
                throw new IllegalArgumentException(msgCurrencyNotFound(currency));
            }
        }
        for (Index index : indices) {
            if (!forwardCurves.keySet().contains(index)) {
                throw new IllegalArgumentException(msgIndexNotFound(index));
            }
        }

        // keys for time-series
        Set<ObservableId> indexQuoteIds = indices.stream().map(IndexQuoteId::of).collect(toImmutableSet());

        // keys for forward curves
        Set<MarketDataId<?>> indexCurveIds = indices.stream().map(idx -> forwardCurves.get(idx))
                .collect(toImmutableSet());

        // keys for discount factors
        Set<MarketDataId<?>> discountFactorsIds = currencies.stream().map(ccy -> discountCurves.get(ccy))
                .collect(toImmutableSet());

        return FunctionRequirements.builder().valueRequirements(Sets.union(indexCurveIds, discountFactorsIds))
                .timeSeriesRequirements(indexQuoteIds).outputCurrencies(currencies)
                .observableSource(observableSource).build();
    }

    //-------------------------------------------------------------------------
    @Override
    public RatesProvider ratesProvider(MarketData marketData) {
        return DefaultLookupRatesProvider.of(this, marketData);
    }

    @Override
    public FxRateProvider fxRateProvider(MarketData marketData) {
        return fxLookup.fxRateProvider(marketData);
    }

    //-------------------------------------------------------------------------
    String msgCurrencyNotFound(Currency currency) {
        return Messages.format("Rates lookup has no discount curve defined for currency '{}'", currency);
    }

    String msgIndexNotFound(Index index) {
        return Messages.format("Rates lookup has no forward curve defined for index '{}'", index);
    }

    //------------------------- AUTOGENERATED START -------------------------
    ///CLOVER:OFF
    /**
     * The meta-bean for {@code DefaultRatesMarketDataLookup}.
     */
    private static MetaBean META_BEAN = LightMetaBean.of(DefaultRatesMarketDataLookup.class);

    /**
     * The meta-bean for {@code DefaultRatesMarketDataLookup}.
     * @return the meta-bean, not null
     */
    public static MetaBean meta() {
        return META_BEAN;
    }

    static {
        JodaBeanUtils.registerMetaBean(META_BEAN);
    }

    /**
     * The serialization version id.
     */
    private static final long serialVersionUID = 1L;

    private DefaultRatesMarketDataLookup(Map<Currency, CurveId> discountCurves,
            Map<? extends Index, CurveId> forwardCurves, ObservableSource observableSource, FxRateLookup fxLookup) {
        JodaBeanUtils.notNull(discountCurves, "discountCurves");
        JodaBeanUtils.notNull(forwardCurves, "forwardCurves");
        JodaBeanUtils.notNull(observableSource, "observableSource");
        JodaBeanUtils.notNull(fxLookup, "fxLookup");
        this.discountCurves = ImmutableMap.copyOf(discountCurves);
        this.forwardCurves = ImmutableMap.copyOf(forwardCurves);
        this.observableSource = observableSource;
        this.fxLookup = fxLookup;
    }

    @Override
    public MetaBean metaBean() {
        return META_BEAN;
    }

    @Override
    public <R> Property<R> property(String propertyName) {
        return metaBean().<R>metaProperty(propertyName).createProperty(this);
    }

    @Override
    public Set<String> propertyNames() {
        return metaBean().metaPropertyMap().keySet();
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the discount curves in the group, keyed by currency.
     * @return the value of the property, not null
     */
    public ImmutableMap<Currency, CurveId> getDiscountCurves() {
        return discountCurves;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the forward curves in the group, keyed by index.
     * @return the value of the property, not null
     */
    public ImmutableMap<Index, CurveId> getForwardCurves() {
        return forwardCurves;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the source of market data for quotes and other observable market data.
     * @return the value of the property, not null
     */
    public ObservableSource getObservableSource() {
        return observableSource;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the lookup used to obtain {@code FxRateProvider}.
     * @return the value of the property, not null
     */
    public FxRateLookup getFxLookup() {
        return fxLookup;
    }

    //-----------------------------------------------------------------------
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj != null && obj.getClass() == this.getClass()) {
            DefaultRatesMarketDataLookup other = (DefaultRatesMarketDataLookup) obj;
            return JodaBeanUtils.equal(discountCurves, other.discountCurves)
                    && JodaBeanUtils.equal(forwardCurves, other.forwardCurves)
                    && JodaBeanUtils.equal(observableSource, other.observableSource)
                    && JodaBeanUtils.equal(fxLookup, other.fxLookup);
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = getClass().hashCode();
        hash = hash * 31 + JodaBeanUtils.hashCode(discountCurves);
        hash = hash * 31 + JodaBeanUtils.hashCode(forwardCurves);
        hash = hash * 31 + JodaBeanUtils.hashCode(observableSource);
        hash = hash * 31 + JodaBeanUtils.hashCode(fxLookup);
        return hash;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder(160);
        buf.append("DefaultRatesMarketDataLookup{");
        buf.append("discountCurves").append('=').append(discountCurves).append(',').append(' ');
        buf.append("forwardCurves").append('=').append(forwardCurves).append(',').append(' ');
        buf.append("observableSource").append('=').append(observableSource).append(',').append(' ');
        buf.append("fxLookup").append('=').append(JodaBeanUtils.toString(fxLookup));
        buf.append('}');
        return buf.toString();
    }

    ///CLOVER:ON
    //-------------------------- AUTOGENERATED END --------------------------
}