/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.var; /** * */ public class OptionPortfolioParametricVaRFunction { /* extends AbstractFunction.NonCompiledInvoker { private final String _resolutionKey; private final LocalDate _startDate; private final Set<ValueGreek> _valueGreeks; private final Set<String> _valueGreekRequirementNames; private final TimeSeriesReturnCalculator _returnCalculator; private final Schedule _scheduleCalculator; private final TimeSeriesSamplingFunction _samplingCalculator; private final int _maxOrder; //TODO none of this should be hard-coded private final NormalLinearVaRCalculator<Map<Integer, ParametricVaRDataBundle>> _normalVaRCalculator; private final VaRCovarianceMatrixCalculator _covarianceMatrixCalculator; private final MatrixAlgebra _algebra = new ColtMatrixAlgebra(); private final DeltaMeanCalculator _meanCalculator = new DeltaMeanCalculator(_algebra); private final DeltaCovarianceMatrixStandardDeviationCalculator _stdCalculator = new DeltaCovarianceMatrixStandardDeviationCalculator(_algebra); public OptionPortfolioParametricVaRFunction(final String dataSourceName, final String startDate, final String returnCalculatorName, final String scheduleName, final String samplingFunctionName, final String confidenceLevel, final String maxOrder, final String valueGreekRequirementNames) { this(dataSourceName, startDate, returnCalculatorName, scheduleName, samplingFunctionName, confidenceLevel, maxOrder, new String[] {valueGreekRequirementNames}); } public OptionPortfolioParametricVaRFunction(final String resolutionKey, final String startDate, final String returnCalculatorName, final String scheduleName, final String samplingFunctionName, final String confidenceLevel, final String maxOrder, final String... valueGreekRequirementNames) { Validate.notNull(resolutionKey, "resolution key"); Validate.notNull(startDate, "start date"); _resolutionKey = resolutionKey; _startDate = LocalDate.parse(startDate); _valueGreeks = new HashSet<ValueGreek>(); _valueGreekRequirementNames = new HashSet<String>(); for (final String valueGreekRequirementName : valueGreekRequirementNames) { _valueGreekRequirementNames.add(valueGreekRequirementName); _valueGreeks.add(AvailableValueGreeks.getValueGreekForValueRequirementName(valueGreekRequirementName)); } _maxOrder = Integer.parseInt(maxOrder); _returnCalculator = TimeSeriesReturnCalculatorFactory.getReturnCalculator(returnCalculatorName); final CovarianceCalculator covarianceCalculator = new HistoricalCovarianceCalculator(); _covarianceMatrixCalculator = new VaRCovarianceMatrixCalculator(new CovarianceMatrixCalculator(covarianceCalculator)); _scheduleCalculator = ScheduleCalculatorFactory.getScheduleCalculator(scheduleName); _samplingCalculator = TimeSeriesSamplingFunctionFactory.getFunction(samplingFunctionName); _normalVaRCalculator = new NormalLinearVaRCalculator<Map<Integer, ParametricVaRDataBundle>>(1, 1, Double.valueOf(confidenceLevel), _meanCalculator, _stdCalculator); //TODO } @Override public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final HbComputationTargetSpecification target, final Set<ValueRequirement> desiredValues) { final PortfolioNode portfolio = target.getPortfolioNode(); final Clock snapshotClock = executionContext.getValuationClock(); final LocalDate now = ZonedDateTime.now(snapshotClock).getDate(); final HistoricalTimeSeriesSource historicalSource = OpenGammaExecutionContext.getHistoricalTimeSeriesSource(executionContext); final SecuritySource securitySource = executionContext.getSecuritySource(); final ValueSpecification resultSpecification = new ValueSpecification(new ValueRequirement(ValueRequirementNames.PARAMETRIC_VAR, portfolio), getUniqueId()); final List<Position> positions = getAllPositions(new ArrayList<Position>(), portfolio); final SensitivityAndReturnDataBundle[] dataBundleArray = new SensitivityAndReturnDataBundle[positions.size() * _valueGreekRequirementNames.size()]; int i = 0; for (final Position position : positions) { for (final String valueGreekRequirementName : _valueGreekRequirementNames) { final Object valueObj = inputs.getValue(valueGreekRequirementName); if (valueObj instanceof Double) { final Double value = (Double) valueObj; final ValueGreek valueGreek = AvailableValueGreeks.getValueGreekForValueRequirementName(valueGreekRequirementName); final Sensitivity<?> sensitivity = new ValueGreekSensitivity(valueGreek, position.getUniqueId().toString()); if (sensitivity.getUnderlying().getOrder() <= _maxOrder) { final Map<UnderlyingType, DoubleTimeSeries<?>> tsReturns = new HashMap<UnderlyingType, DoubleTimeSeries<?>>(); for (final UnderlyingType underlyingType : valueGreek.getUnderlyingGreek().getUnderlying().getUnderlyings()) { final DoubleTimeSeries<?> timeSeries = UnderlyingTimeSeriesProvider.getSeries(historicalSource, _resolutionKey, securitySource, underlyingType, position.getSecurity()); final LocalDate[] schedule = _scheduleCalculator.getSchedule(_startDate, now, true, false); final DoubleTimeSeries<?> sampledTS = _samplingCalculator.getSampledTimeSeries(timeSeries, schedule); tsReturns.put(underlyingType, _returnCalculator.evaluate(sampledTS)); } dataBundleArray[i++] = new SensitivityAndReturnDataBundle(sensitivity, value, tsReturns); } } else { throw new IllegalArgumentException("Got a value for greek " + valueObj + " that wasn't a Double"); } } } final Map<Integer, ParametricVaRDataBundle> data = _covarianceMatrixCalculator.evaluate(dataBundleArray); @SuppressWarnings("unchecked") final Double result = _normalVaRCalculator.evaluate(data); final ComputedValue resultValue = new ComputedValue(resultSpecification, result); return Collections.singleton(resultValue); } @Override public ComputationTargetType getTargetType() { return ComputationTargetType.PORTFOLIO_NODE; } @Override public boolean canApplyTo(final FunctionCompilationContext context, final HbComputationTargetSpecification target) { final PortfolioNode node = target.getPortfolioNode(); final List<Position> allPositions = getAllPositions(new ArrayList<Position>(), node); for (final Position p : allPositions) { if (!(p.getSecurity() instanceof EquityOptionSecurity)) { return false; } } return true; } private List<Position> getAllPositions(final List<Position> positions, final PortfolioNode node) { if (node.getChildNodes().isEmpty()) { positions.addAll(node.getPositions()); return positions; } for (final PortfolioNode child : node.getChildNodes()) { positions.addAll(child.getPositions()); } return positions; } @Override public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context, final HbComputationTargetSpecification target, final ValueRequirement desiredValue) { if (canApplyTo(context, target)) { final Set<ValueRequirement> requirements = new HashSet<ValueRequirement>(); for (final String valueGreekRequirementName : _valueGreekRequirementNames) { requirements.add(new ValueRequirement(valueGreekRequirementName, target.getPortfolioNode())); } return requirements; } return null; } @Override public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final HbComputationTargetSpecification target) { if (canApplyTo(context, target)) { return Sets.newHashSet(new ValueSpecification(new ValueRequirement(ValueRequirementNames.PARAMETRIC_VAR, target.getPortfolioNode()), getUniqueId())); } return null; } @Override public String getShortName() { return "PortfolioParametricVaRCalculatorFunction"; } */ }