/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.aggregation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.LocalDate;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesSource;
import com.opengamma.core.position.Position;
import com.opengamma.core.security.Security;
import com.opengamma.core.security.SecuritySource;
import com.opengamma.financial.security.option.EquityOptionSecurity;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.id.UniqueId;
import com.opengamma.util.CompareUtils;
import com.opengamma.util.tuple.Pair;
/**
* Function to classify positions by Currency.
*
*/
public class EquityBetaAggregationFunction implements AggregationFunction<String> {
private static final Logger s_logger = LoggerFactory.getLogger(EquityBetaAggregationFunction.class);
private final boolean _useAttributes;
private final boolean _includeEmptyCategories;
private static final String MORE_THAN_1_25 = "> 1.25";
private static final String FROM_0_9_TO_1_25 = "0.9 - 1.25";
private static final String FROM_0_75_TO_0_9 = "0.75 - 0.9";
private static final String FROM_0_5_TO_0_75 = "0.5 - 0.75";
private static final String LESS_THAN_0_5 = "< 0.5";
private static final String NAME = "Beta";
private static final String FIELD = "APPLIED_BETA";
private static final String RESOLUTION_KEY = "DEFAULT_TSS_CONFIG";
private static final String NO_BETA = "N/A";
private final boolean _caching = true;
private final Map<UniqueId, Double> _equityBetaCache = new HashMap<UniqueId, Double>();
private static final List<String> REQUIRED = Arrays.asList(MORE_THAN_1_25, FROM_0_9_TO_1_25, FROM_0_75_TO_0_9, FROM_0_5_TO_0_75, LESS_THAN_0_5, NO_BETA);
private final HistoricalTimeSeriesSource _htsSource;
private final SecuritySource _secSource;
public EquityBetaAggregationFunction(final SecuritySource secSource, final HistoricalTimeSeriesSource htsSource, final boolean useAttributes, final boolean includeEmptyCategories) {
_secSource = secSource;
_htsSource = htsSource;
_useAttributes = useAttributes;
_includeEmptyCategories = includeEmptyCategories;
}
public EquityBetaAggregationFunction(final SecuritySource secSource, final HistoricalTimeSeriesSource htsSource, final boolean useAttributes) {
this(secSource, htsSource, useAttributes, false);
}
public EquityBetaAggregationFunction(final SecuritySource secSource, final HistoricalTimeSeriesSource htsSource) {
this(secSource, htsSource, false);
}
@Override
public String classifyPosition(final Position position) {
if (_useAttributes) {
final Map<String, String> attributes = position.getAttributes();
if (attributes.containsKey(getName())) {
return attributes.get(getName());
}
return NO_BETA;
}
return classifyPositionWithTS(position);
}
/*package*/ Double getEquityBeta(final Security security) {
if (_caching && security != null && security.getUniqueId() != null) {
if (_equityBetaCache.containsKey(security.getUniqueId())) {
return _equityBetaCache.get(security.getUniqueId());
}
}
if (security == null) {
return null;
}
final ExternalIdBundle externalIdBundle = security.getExternalIdBundle();
final Pair<LocalDate, Double> results = _htsSource.getLatestDataPoint(FIELD, externalIdBundle, RESOLUTION_KEY);
if (results != null && results.getFirst() != null && results.getSecond() != null) {
final Double beta = results.getSecond();
return beta;
}
return null;
}
/*package*/ String classifyPositionWithTS(final Position position) {
final Security sec = resolveSecurity(position);
final Double beta = getEquityBeta(sec);
return classifyEquityBeta(beta);
}
/*package*/ Security resolveSecurity(final Position position) {
try {
Security sec = position.getSecurityLink().getTarget();
if (sec == null) {
sec = position.getSecurityLink().resolve(_secSource);
if (sec == null) {
s_logger.error("Position security is null");
return null;
}
}
if (sec.getSecurityType().equals(EquityOptionSecurity.SECURITY_TYPE)) {
final EquityOptionSecurity equityOption = (EquityOptionSecurity) sec;
sec = equityOption;
}
return sec;
} catch (final UnsupportedOperationException ex) {
return null;
}
}
/*package*/ String classifyEquityBeta(final Double beta) {
if (beta != null) {
if (beta < 0.5) {
return LESS_THAN_0_5;
} else if (beta < 0.75) {
return FROM_0_5_TO_0_75;
} else if (beta < 0.9) {
return FROM_0_75_TO_0_9;
} else if (beta < 1.25) {
return FROM_0_9_TO_1_25;
} else {
return MORE_THAN_1_25;
}
}
return NO_BETA;
}
@Override
public String getName() {
return NAME;
}
@Override
public Collection<String> getRequiredEntries() {
if (_includeEmptyCategories) {
return REQUIRED;
}
return Collections.emptyList();
}
@Override
public int compare(final String o1, final String o2) {
return CompareUtils.compareByList(REQUIRED, o1, o2);
}
private class PositionComparator implements Comparator<Position> {
@Override
public int compare(final Position position1, final Position position2) {
final Security security1 = resolveSecurity(position1);
final Security security2 = resolveSecurity(position2);
return CompareUtils.compareWithNullLow(getEquityBeta(security1), getEquityBeta(security2));
}
}
@Override
public Comparator<Position> getPositionComparator() {
return new PositionComparator();
}
}