/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.solutions.library.tool;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.opengamma.core.link.ConfigLink;
import com.opengamma.core.marketdatasnapshot.MarketDataSnapshotSource;
import com.opengamma.core.marketdatasnapshot.impl.ManageableMarketDataSnapshot;
import com.opengamma.engine.marketdata.spec.MarketDataSpecification;
import com.opengamma.engine.marketdata.spec.UserMarketDataSpecification;
import com.opengamma.financial.currency.CurrencyMatrix;
import com.opengamma.id.VersionCorrection;
import com.opengamma.master.region.RegionMaster;
import com.opengamma.master.region.impl.RegionFileReader;
import com.opengamma.service.ServiceContext;
import com.opengamma.service.ThreadLocalServiceContext;
import com.opengamma.service.VersionCorrectionProvider;
import com.opengamma.sesame.MulticurveBundle;
import com.opengamma.sesame.config.ViewConfig;
import com.opengamma.sesame.engine.CalculationArguments;
import com.opengamma.sesame.engine.ComponentMap;
import com.opengamma.sesame.engine.Engine;
import com.opengamma.sesame.engine.FixedInstantVersionCorrectionProvider;
import com.opengamma.sesame.marketdata.MarketDataEnvironment;
import com.opengamma.sesame.marketdata.MarketDataEnvironmentBuilder;
import com.opengamma.sesame.marketdata.MarketDataRequirement;
import com.opengamma.sesame.marketdata.MulticurveId;
import com.opengamma.sesame.marketdata.ScenarioMarketDataEnvironment;
import com.opengamma.sesame.marketdata.SingleValueRequirement;
import com.opengamma.sesame.marketdata.SnapshotMarketDataFactory;
import com.opengamma.sesame.marketdata.builders.MarketDataBuilder;
import com.opengamma.sesame.marketdata.builders.MarketDataBuilders;
import com.opengamma.sesame.marketdata.builders.MarketDataEnvironmentFactory;
import com.opengamma.sesame.marketdata.scenarios.ScenarioDefinition;
import com.opengamma.sesame.marketdata.scenarios.SingleScenarioDefinition;
import com.opengamma.solutions.library.storage.DataLoader;
import com.opengamma.util.ArgumentChecker;
import org.threeten.bp.Instant;
import org.threeten.bp.ZonedDateTime;
import java.util.List;
import java.util.Set;
/**
* Sample Curve Bundle Provider
*/
public class CurveBundleProvider {
private final DataLoader _dataload;
private final RegionMaster _regionMaster;
private final ComponentMap _componentMap;
private final MarketDataSnapshotSource _snapshotSource;
private final Engine _engine;
/**
* Create an instance of the Curve Bundle Provider
* @param dataload utility to populateMulticurveData data into the in memory masters
* @param regionMaster regions master
* @param snapshotSource market data snapshot source
* @param componentMap component map to build the MarketDataEnvironment
* @param engine awesome calculator
*/
@Inject
public CurveBundleProvider(DataLoader dataload,
RegionMaster regionMaster,
MarketDataSnapshotSource snapshotSource,
ComponentMap componentMap,
Engine engine) {
_dataload = ArgumentChecker.notNull(dataload, "dataload");
_regionMaster = ArgumentChecker.notNull(regionMaster, "regionMaster");
_componentMap = ArgumentChecker.notNull(componentMap, "componentMap");
_snapshotSource = ArgumentChecker.notNull(snapshotSource, "snapshotSource");
_engine = ArgumentChecker.notNull(engine, "engine");
}
/**
* Return a curve bundle
* @param bundleName the name of the curve construction configuration
* @param snapshotName the name of the data snapshot
* @param currencyMatrixName the name of the currency matrix
* @param valuationTime zone data time valuation time
* @return MulticurveBundle
*/
public MulticurveBundle buildMulticurve(String bundleName,
String snapshotName,
String currencyMatrixName,
ZonedDateTime valuationTime) {
_dataload.populateMulticurveData();
RegionFileReader.createPopulated(_regionMaster);
// This is needed to ensure that the version correction provided is after the population of the masters
ServiceContext serviceContext =
ThreadLocalServiceContext.getInstance().with(VersionCorrectionProvider.class,
new FixedInstantVersionCorrectionProvider(Instant.now()));
ThreadLocalServiceContext.init(serviceContext);
// Need to create another MarketDataEnvironmentFactory here, rather than using the one provided by Guice.
// This is because resolving the currency matrix link can only happen after the population of masters
ConfigLink<CurrencyMatrix> currencyMatrixLink = ConfigLink.resolvable(currencyMatrixName, CurrencyMatrix.class);
List<MarketDataBuilder> builders = ImmutableList.of(
MarketDataBuilders.raw(_componentMap, "DEFAULT"),
MarketDataBuilders.multicurve(_componentMap, currencyMatrixLink),
MarketDataBuilders.fxMatrix());
// Get the snapshot
SnapshotMarketDataFactory snapshotMarketDataFactory = new SnapshotMarketDataFactory(_snapshotSource);
MarketDataEnvironmentFactory environmentFactory = new MarketDataEnvironmentFactory(snapshotMarketDataFactory, builders);
ManageableMarketDataSnapshot snapshot = _snapshotSource.getSingle(ManageableMarketDataSnapshot.class,
snapshotName,
VersionCorrection.LATEST);
MarketDataSpecification marketDataSpec = UserMarketDataSpecification.of(snapshot.getUniqueId());
//Build the MarketDataEnvironment
MarketDataEnvironment suppliedData = MarketDataEnvironmentBuilder.empty();
MulticurveId multicurveId = MulticurveId.of(bundleName);
SingleValueRequirement requirement = SingleValueRequirement.of(multicurveId);
Set<MarketDataRequirement> requirements = ImmutableSet.<MarketDataRequirement>of(requirement);
SingleScenarioDefinition perturbations = SingleScenarioDefinition.base();
MarketDataEnvironment marketData =
environmentFactory.build(suppliedData, requirements, perturbations, marketDataSpec, valuationTime);
return (MulticurveBundle) marketData.getData().get(requirement);
}
/**
* Return a curve bundle for each scenario, as a ScenarioMarketDataEnvironment, derived from the scenario definition.
*
* @param snapshotName the name of the data snapshot
* @param valuationTime zone data time valuation time
* @param config view configuration of the engine that will run the curve calibration on each scenario
* @param scenarioDefinition scenario definition as a list of single scenarios for which the market data will be
* calibrated separately
* @param trades the list of relevant trades which drives the market data requirements
* @return ScenarioMarketDataEnvironment a container for the market data for each single scenario
*/
public ScenarioMarketDataEnvironment buildScenarioMarketDataEnvironment(String snapshotName,
ZonedDateTime valuationTime,
ViewConfig config,
ScenarioDefinition scenarioDefinition,
List<?> trades) {
_dataload.populateMulticurveData();
RegionFileReader.createPopulated(_regionMaster);
ServiceContext serviceContext =
ThreadLocalServiceContext.getInstance().with(VersionCorrectionProvider.class,
new FixedInstantVersionCorrectionProvider(Instant.now()));
ThreadLocalServiceContext.init(serviceContext);
ManageableMarketDataSnapshot snapshot = _snapshotSource.getSingle(ManageableMarketDataSnapshot.class,
snapshotName,
VersionCorrection.LATEST);
MarketDataSpecification marketDataSpec = UserMarketDataSpecification.of(snapshot.getUniqueId());
MarketDataEnvironment suppliedData =
MarketDataEnvironmentBuilder.empty().toBuilder().valuationTime(valuationTime).build();
CalculationArguments calculationArguments = CalculationArguments
.builder()
.marketDataSpecification(marketDataSpec)
.valuationTime(valuationTime)
.build();
return _engine.buildScenarioMarketData(
config,
suppliedData,
scenarioDefinition,
calculationArguments,
trades);
}
}