/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.security;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.fudgemsg.FudgeMsgEnvelope;
import org.joda.beans.impl.flexi.FlexiBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeries;
import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.financial.security.index.IndexFamily;
import com.opengamma.financial.sensitivities.FactorExposureData;
import com.opengamma.financial.sensitivities.SecurityEntryData;
import com.opengamma.id.ExternalId;
import com.opengamma.id.UniqueId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesInfoSearchRequest;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesInfoSearchResult;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesMaster;
import com.opengamma.master.legalentity.LegalEntityMaster;
import com.opengamma.master.security.ManageableSecurity;
import com.opengamma.master.security.RawSecurity;
import com.opengamma.master.security.SecurityLoader;
import com.opengamma.master.security.SecurityMaster;
import com.opengamma.master.security.SecuritySearchRequest;
import com.opengamma.master.security.SecuritySearchResult;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.fudgemsg.OpenGammaFudgeContext;
import com.opengamma.util.time.Tenor;
import com.opengamma.web.AbstractPerRequestWebResource;
/**
* Abstract base class for RESTful security resources.
*/
public abstract class AbstractWebSecurityResource
extends AbstractPerRequestWebResource<WebSecuritiesData> {
/** Logger. */
private static final Logger s_logger = LoggerFactory.getLogger(AbstractWebSecurityResource.class);
/**
* Security XML parameter name
*/
protected static final String SECURITY_XML = "securityXml";
/**
* HTML ftl directory
*/
protected static final String HTML_DIR = "securities/html/";
/**
* JSON ftl directory
*/
protected static final String JSON_DIR = "securities/json/";
/**
* The template name provider
*/
private final SecurityTemplateNameProvider _templateNameProvider = new SecurityTemplateNameProvider();
/**
* Creates the resource.
*
* @param securityMaster the security master, not null
* @param securityLoader the security loader, not null
* @param htsMaster the historical time series master, not null
* @param legalEntityMaster the organization master, not null
*/
protected AbstractWebSecurityResource(final SecurityMaster securityMaster, final SecurityLoader securityLoader, final HistoricalTimeSeriesMaster htsMaster,
final LegalEntityMaster legalEntityMaster) {
super(new WebSecuritiesData());
ArgumentChecker.notNull(securityMaster, "securityMaster");
ArgumentChecker.notNull(securityLoader, "securityLoader");
ArgumentChecker.notNull(htsMaster, "htsMaster");
ArgumentChecker.notNull(legalEntityMaster, "legalEntityMaster");
data().setSecurityMaster(securityMaster);
data().setSecurityLoader(securityLoader);
data().setHistoricalTimeSeriesMaster(htsMaster);
data().setLegalEntityMaster(legalEntityMaster);
data().setSecurityTypes(SecurityTypesDescriptionProvider.getInstance().getDescription2Type());
}
/**
* Creates the resource.
*
* @param parent the parent resource, not null
*/
protected AbstractWebSecurityResource(final AbstractWebSecurityResource parent) {
super(parent);
}
//-------------------------------------------------------------------------
/**
* Creates the output root data.
* @return the output root data, not null
*/
@Override
protected FlexiBean createRootData() {
FlexiBean out = super.createRootData();
out.put("uris", new WebSecuritiesUris(data()));
return out;
}
//-------------------------------------------------------------------------
/**
* Gets the security template provider.
*
* @return the template provider, not null
*/
protected SecurityTemplateNameProvider getTemplateProvider() {
return _templateNameProvider;
}
protected void addSecuritySpecificMetaData(ManageableSecurity security, FlexiBean out) {
if (security instanceof FinancialSecurity) {
FinancialSecurity financialSec = (FinancialSecurity) security;
financialSec.accept(new SecurityTemplateModelObjectBuilder(out, data().getSecurityMaster(), data().getLegalEntityMaster()));
} else {
if (security.getSecurityType().equals(SecurityEntryData.EXTERNAL_SENSITIVITIES_SECURITY_TYPE)) {
RawSecurity rawSecurity = (RawSecurity) security;
FudgeMsgEnvelope msg = OpenGammaFudgeContext.getInstance().deserialize(rawSecurity.getRawData());
SecurityEntryData securityEntryData = OpenGammaFudgeContext.getInstance().fromFudgeMsg(SecurityEntryData.class, msg.getMessage());
out.put("securityEntryData", securityEntryData);
RawSecurity underlyingRawSecurity = (RawSecurity) getSecurity(securityEntryData.getFactorSetId(), data().getSecurityMaster());
if (underlyingRawSecurity != null) {
FudgeMsgEnvelope factorIdMsg = OpenGammaFudgeContext.getInstance().deserialize(underlyingRawSecurity.getRawData());
@SuppressWarnings("unchecked")
List<FactorExposureData> factorExposureDataList = OpenGammaFudgeContext.getInstance().fromFudgeMsg(List.class, factorIdMsg.getMessage());
s_logger.error(factorExposureDataList.toString());
List<FactorExposure> factorExposuresList = convertToFactorExposure(factorExposureDataList);
out.put("factorExposuresList", factorExposuresList);
} else {
s_logger.error("Couldn't find security");
}
}
if (security.getSecurityType().equals(FactorExposureData.EXTERNAL_SENSITIVITIES_RISK_FACTORS_SECURITY_TYPE)) {
RawSecurity rawSecurity = (RawSecurity) security;
FudgeMsgEnvelope msg = OpenGammaFudgeContext.getInstance().deserialize(rawSecurity.getRawData());
@SuppressWarnings("unchecked")
List<FactorExposureData> factorExposureDataList = OpenGammaFudgeContext.getInstance().fromFudgeMsg(List.class, msg.getMessage());
List<FactorExposure> factorExposuresList = convertToFactorExposure(factorExposureDataList);
out.put("factorExposuresList", factorExposuresList);
}
if (security.getSecurityType().equals(IndexFamily.METADATA_TYPE)) {
Map<String, ExternalId> convertedMap = new LinkedHashMap<>();
IndexFamily indexFamily = (IndexFamily) security;
if (indexFamily.getMembers() != null) {
for (Map.Entry<Tenor, ExternalId> entry : indexFamily.getMembers().entrySet()) {
convertedMap.put(entry.getKey().toFormattedString(), entry.getValue());
}
}
out.put("members", convertedMap);
}
}
}
private List<FactorExposure> convertToFactorExposure(List<FactorExposureData> factorExposureDataList) {
List<FactorExposure> results = new ArrayList<FactorExposure>();
for (FactorExposureData exposure : factorExposureDataList) {
HistoricalTimeSeriesInfoSearchRequest exposureSearchRequest = new HistoricalTimeSeriesInfoSearchRequest();
exposureSearchRequest.addExternalId(exposure.getExposureExternalId());
exposureSearchRequest.setDataField("EXPOSURE");
HistoricalTimeSeriesInfoSearchResult exposureSearchResult = data().getHistoricalTimeSeriesMaster().search(exposureSearchRequest);
HistoricalTimeSeries exposureHTS = null;
if (exposureSearchResult.getFirstInfo() != null) {
exposureHTS = data().getHistoricalTimeSeriesMaster().getTimeSeries(exposureSearchResult.getFirstInfo().getTimeSeriesObjectId(), VersionCorrection.LATEST);
}
HistoricalTimeSeriesInfoSearchRequest convexitySearchRequest = new HistoricalTimeSeriesInfoSearchRequest();
convexitySearchRequest.addExternalId(exposure.getExposureExternalId());
convexitySearchRequest.setDataField("CONVEXITY");
HistoricalTimeSeriesInfoSearchResult convexitySearchResult = data().getHistoricalTimeSeriesMaster().search(convexitySearchRequest);
HistoricalTimeSeries convexityHTS = null;
if (convexitySearchResult.getFirstInfo() != null) {
convexityHTS = data().getHistoricalTimeSeriesMaster().getTimeSeries(convexitySearchResult.getFirstInfo().getTimeSeriesObjectId(), VersionCorrection.LATEST);
}
HistoricalTimeSeriesInfoSearchRequest priceSearchRequest = new HistoricalTimeSeriesInfoSearchRequest();
priceSearchRequest.addExternalId(exposure.getExposureExternalId());
priceSearchRequest.setDataField("PX_LAST");
HistoricalTimeSeriesInfoSearchResult priceSearchResult = data().getHistoricalTimeSeriesMaster().search(priceSearchRequest);
HistoricalTimeSeries priceHTS = null;
if (priceSearchResult.getFirstInfo() != null) {
priceHTS = data().getHistoricalTimeSeriesMaster().getTimeSeries(priceSearchResult.getFirstInfo().getTimeSeriesObjectId(), VersionCorrection.LATEST);
}
results.add(new FactorExposure(exposure.getFactorType().getFactorType(),
exposure.getFactorName(),
exposure.getNode(),
priceHTS != null ? priceHTS.getUniqueId() : null,
priceHTS != null ? priceHTS.getTimeSeries().getLatestValue() : null,
exposureHTS != null ? exposureHTS.getUniqueId() : null,
exposureHTS != null ? exposureHTS.getTimeSeries().getLatestValue() : null,
convexityHTS != null ? convexityHTS.getUniqueId() : null,
convexityHTS != null ? convexityHTS.getTimeSeries().getLatestValue() : null));
}
return results;
}
/**
* Container for a row of a displayed factor.
*/
public class FactorExposure {
private final String _factorType;
private final String _factorName;
private final String _node;
private final UniqueId _priceTsId;
private final Double _lastPrice;
private final UniqueId _exposureTsId;
private final Double _lastExposure;
private final UniqueId _convexityTsId;
private final Double _lastConvexity;
public FactorExposure(String factorType, String factorName, String node,
UniqueId priceTsId, Double lastPrice,
UniqueId exposureTsId, Double lastExposure,
UniqueId convexityTsId, Double lastConvexity) {
_factorType = factorType;
_factorName = factorName;
_node = node;
_priceTsId = priceTsId;
_lastPrice = lastPrice;
_exposureTsId = exposureTsId;
_lastExposure = lastExposure;
_convexityTsId = convexityTsId;
_lastConvexity = lastConvexity;
}
public String getFactorType() {
return _factorType;
}
public String getFactorName() {
return _factorName;
}
public String getNode() {
return _node;
}
public UniqueId getPriceTsId() {
return _priceTsId;
}
public Double getLastPrice() {
return _lastPrice;
}
public UniqueId getExposureTsId() {
return _exposureTsId;
}
public Double getLastExposure() {
return _lastExposure;
}
public UniqueId getConvexityTsId() {
return _convexityTsId;
}
public Double getLastConvexity() {
return _lastConvexity;
}
}
public static ManageableSecurity getSecurity(final ExternalId underlyingIdentifier, final SecurityMaster securityMaster) {
if (underlyingIdentifier == null) {
return null;
}
SecuritySearchRequest request = new SecuritySearchRequest();
request.addExternalId(underlyingIdentifier);
SecuritySearchResult search = securityMaster.search(request);
return search.getFirstSecurity();
}
}