com.opengamma.strata.measure.bond.DefaultLegalEntityDiscountingMarketDataLookup.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.strata.measure.bond.DefaultLegalEntityDiscountingMarketDataLookup.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.bond;

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

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

import org.joda.beans.BeanDefinition;
import org.joda.beans.ImmutableBean;
import org.joda.beans.ImmutableValidator;
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.StandardId;
import com.opengamma.strata.basics.currency.Currency;
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.collect.tuple.Pair;
import com.opengamma.strata.data.MarketData;
import com.opengamma.strata.data.ObservableSource;
import com.opengamma.strata.data.scenario.ScenarioMarketData;
import com.opengamma.strata.market.curve.CurveId;
import com.opengamma.strata.pricer.bond.LegalEntityDiscountingProvider;
import com.opengamma.strata.pricer.bond.LegalEntityGroup;
import com.opengamma.strata.pricer.bond.RepoGroup;
import com.opengamma.strata.product.SecurityId;

/**
 * The legal entity discounting lookup, used to select curves for pricing.
 * <p>
 * This provides access to repo and issuer 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 DefaultLegalEntityDiscountingMarketDataLookup
        implements LegalEntityDiscountingMarketDataLookup, ImmutableBean, Serializable {

    /**
     * The groups used to find a repo curve.
     * <p>
     * This maps either the security ID or the legal entity ID to a group.
     * The group is used to find the curve in {@code repoCurves}.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<StandardId, RepoGroup> repoCurveGroups;
    /**
     * The repo curves, keyed by group and currency.
     * The curve data, predicting the future, associated with each repo group and currency.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves;
    /**
     * The groups used to find an issuer curve.
     * <p>
     * This maps the legal entity ID to a group.
     * The group is used to find the curve in {@code issuerCurves}.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<StandardId, LegalEntityGroup> issuerCurveGroups;
    /**
     * The issuer curves, keyed by group and currency.
     * The curve data, predicting the future, associated with each legal entity group and currency.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves;
    /**
     * The source of market data for quotes and other observable market data.
     */
    @PropertyDefinition(validate = "notNull")
    private final ObservableSource observableSource;

    //-------------------------------------------------------------------------
    /**
     * Obtains an instance based on a maps for repo and issuer curves.
     * <p>
     * Both the repo and issuer curves are defined in two parts.
     * The first part maps the issuer ID to a group, and the second part maps the
     * group and currency to the identifier of the curve.
     * 
     * @param repoCurveGroups  the repo curve groups, mapping security or issuer ID to group
     * @param repoCurveIds  the repo curve identifiers, keyed by security ID or issuer ID and currency
     * @param issuerCurveGroups  the issuer curve groups, mapping issuer ID to group
     * @param issuerCurveIds  the issuer curves identifiers, keyed by issuer ID and currency
     * @param obsSource  the source of market data for quotes and other observable market data
     * @return the rates lookup containing the specified curves
     */
    public static DefaultLegalEntityDiscountingMarketDataLookup of(Map<StandardId, RepoGroup> repoCurveGroups,
            Map<Pair<RepoGroup, Currency>, CurveId> repoCurveIds,
            Map<StandardId, LegalEntityGroup> issuerCurveGroups,
            Map<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurveIds, ObservableSource obsSource) {

        return new DefaultLegalEntityDiscountingMarketDataLookup(repoCurveGroups, repoCurveIds, issuerCurveGroups,
                issuerCurveIds, obsSource);
    }

    @ImmutableValidator
    private void validate() {
        Set<RepoGroup> uniqueRepoGroups = new HashSet<>(repoCurveGroups.values());
        Set<RepoGroup> uniqueRepoCurves = repoCurves.keySet().stream().map(p -> p.getFirst())
                .collect(toImmutableSet());
        if (!uniqueRepoCurves.containsAll(uniqueRepoGroups)) {
            throw new IllegalArgumentException("Repo curve groups defined without matching curve mappings: "
                    + Sets.difference(uniqueRepoGroups, uniqueRepoCurves));
        }
        Set<LegalEntityGroup> uniqueIssuerGroups = new HashSet<>(issuerCurveGroups.values());
        Set<LegalEntityGroup> uniqueIssuerCurves = issuerCurves.keySet().stream().map(p -> p.getFirst())
                .collect(toImmutableSet());
        if (!uniqueIssuerCurves.containsAll(uniqueIssuerGroups)) {
            throw new IllegalArgumentException("Issuer curve groups defined without matching curve mappings: "
                    + Sets.difference(uniqueIssuerGroups, uniqueIssuerCurves));
        }
    }

    //-------------------------------------------------------------------------
    @Override
    public FunctionRequirements requirements(SecurityId securityId, StandardId issuerId, Currency currency) {
        // repo
        RepoGroup repoKey = repoCurveGroups.get(securityId.getStandardId());
        if (repoKey == null) {
            repoKey = repoCurveGroups.get(issuerId);
        }
        if (repoKey == null) {
            throw new IllegalArgumentException(
                    Messages.format("Legal entity discounting lookup has no repo curve defined for '{}' and '{}'",
                            securityId, issuerId));
        }
        CurveId repoCurveId = repoCurves.get(Pair.of(repoKey, currency));
        if (repoCurveId == null) {
            throw new IllegalArgumentException(
                    Messages.format("Legal entity discounting lookup has no repo curve defined for '{}' and '{}'",
                            securityId, issuerId));
        }
        // issuer
        LegalEntityGroup issuerKey = issuerCurveGroups.get(issuerId);
        if (issuerKey == null) {
            throw new IllegalArgumentException(Messages
                    .format("Legal entity discounting lookup has no issuer curve defined for '{}'", issuerId));
        }
        CurveId issuerCurveId = issuerCurves.get(Pair.of(issuerKey, currency));
        if (issuerCurveId == null) {
            throw new IllegalArgumentException(Messages
                    .format("Legal entity discounting lookup has no issuer curve defined for '{}'", issuerId));
        }
        // result
        return FunctionRequirements.builder().valueRequirements(ImmutableSet.of(repoCurveId, issuerCurveId))
                .outputCurrencies(currency).observableSource(observableSource).build();
    }

    //-------------------------------------------------------------------------
    @Override
    public LegalEntityDiscountingProvider discountingProvider(MarketData marketData) {
        return DefaultLookupLegalEntityDiscountingProvider.of(this, marketData);
    }

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

    /**
     * The meta-bean for {@code DefaultLegalEntityDiscountingMarketDataLookup}.
     * @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 DefaultLegalEntityDiscountingMarketDataLookup(Map<StandardId, RepoGroup> repoCurveGroups,
            Map<Pair<RepoGroup, Currency>, CurveId> repoCurves, Map<StandardId, LegalEntityGroup> issuerCurveGroups,
            Map<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves, ObservableSource observableSource) {
        JodaBeanUtils.notNull(repoCurveGroups, "repoCurveGroups");
        JodaBeanUtils.notNull(repoCurves, "repoCurves");
        JodaBeanUtils.notNull(issuerCurveGroups, "issuerCurveGroups");
        JodaBeanUtils.notNull(issuerCurves, "issuerCurves");
        JodaBeanUtils.notNull(observableSource, "observableSource");
        this.repoCurveGroups = ImmutableMap.copyOf(repoCurveGroups);
        this.repoCurves = ImmutableMap.copyOf(repoCurves);
        this.issuerCurveGroups = ImmutableMap.copyOf(issuerCurveGroups);
        this.issuerCurves = ImmutableMap.copyOf(issuerCurves);
        this.observableSource = observableSource;
        validate();
    }

    @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 groups used to find a repo curve.
     * <p>
     * This maps either the security ID or the legal entity ID to a group.
     * The group is used to find the curve in {@code repoCurves}.
     * @return the value of the property, not null
     */
    public ImmutableMap<StandardId, RepoGroup> getRepoCurveGroups() {
        return repoCurveGroups;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the repo curves, keyed by group and currency.
     * The curve data, predicting the future, associated with each repo group and currency.
     * @return the value of the property, not null
     */
    public ImmutableMap<Pair<RepoGroup, Currency>, CurveId> getRepoCurves() {
        return repoCurves;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the groups used to find an issuer curve.
     * <p>
     * This maps the legal entity ID to a group.
     * The group is used to find the curve in {@code issuerCurves}.
     * @return the value of the property, not null
     */
    public ImmutableMap<StandardId, LegalEntityGroup> getIssuerCurveGroups() {
        return issuerCurveGroups;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the issuer curves, keyed by group and currency.
     * The curve data, predicting the future, associated with each legal entity group and currency.
     * @return the value of the property, not null
     */
    public ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> getIssuerCurves() {
        return issuerCurves;
    }

    //-----------------------------------------------------------------------
    /**
     * 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;
    }

    //-----------------------------------------------------------------------
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj != null && obj.getClass() == this.getClass()) {
            DefaultLegalEntityDiscountingMarketDataLookup other = (DefaultLegalEntityDiscountingMarketDataLookup) obj;
            return JodaBeanUtils.equal(repoCurveGroups, other.repoCurveGroups)
                    && JodaBeanUtils.equal(repoCurves, other.repoCurves)
                    && JodaBeanUtils.equal(issuerCurveGroups, other.issuerCurveGroups)
                    && JodaBeanUtils.equal(issuerCurves, other.issuerCurves)
                    && JodaBeanUtils.equal(observableSource, other.observableSource);
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = getClass().hashCode();
        hash = hash * 31 + JodaBeanUtils.hashCode(repoCurveGroups);
        hash = hash * 31 + JodaBeanUtils.hashCode(repoCurves);
        hash = hash * 31 + JodaBeanUtils.hashCode(issuerCurveGroups);
        hash = hash * 31 + JodaBeanUtils.hashCode(issuerCurves);
        hash = hash * 31 + JodaBeanUtils.hashCode(observableSource);
        return hash;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder(192);
        buf.append("DefaultLegalEntityDiscountingMarketDataLookup{");
        buf.append("repoCurveGroups").append('=').append(repoCurveGroups).append(',').append(' ');
        buf.append("repoCurves").append('=').append(repoCurves).append(',').append(' ');
        buf.append("issuerCurveGroups").append('=').append(issuerCurveGroups).append(',').append(' ');
        buf.append("issuerCurves").append('=').append(issuerCurves).append(',').append(' ');
        buf.append("observableSource").append('=').append(JodaBeanUtils.toString(observableSource));
        buf.append('}');
        return buf.toString();
    }

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