com.opengamma.analytics.financial.riskfactor.TaylorExpansionMultiplierCalculator.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.riskfactor.TaylorExpansionMultiplierCalculator.java

Source

/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.analytics.financial.riskfactor;

import java.util.Map;

import org.apache.commons.lang.Validate;
import org.apache.commons.math.util.MathUtils;

import com.opengamma.analytics.financial.greeks.MixedOrderUnderlying;
import com.opengamma.analytics.financial.greeks.NthOrderUnderlying;
import com.opengamma.analytics.financial.greeks.Underlying;
import com.opengamma.analytics.financial.pnl.UnderlyingType;
import com.opengamma.timeseries.DoubleTimeSeries;

/**
 * 
 */
public class TaylorExpansionMultiplierCalculator {

    public static double getMultiplier(final Underlying underlying) {
        Validate.notNull(underlying, "underlying");
        if (underlying instanceof NthOrderUnderlying) {
            final NthOrderUnderlying nthOrder = (NthOrderUnderlying) underlying;
            final int n = nthOrder.getOrder();
            if (n == 0) {
                return 1;
            }
            return 1. / MathUtils.factorial(n);
        } else if (underlying instanceof MixedOrderUnderlying) {
            final MixedOrderUnderlying mixedOrder = (MixedOrderUnderlying) underlying;
            double result = 1;
            for (final NthOrderUnderlying underlyingOrder : mixedOrder.getUnderlyingOrders()) {
                result *= getMultiplier(underlyingOrder);
            }
            return result;
        }
        throw new IllegalArgumentException(
                "Order was neither NthOrderUnderlying nor MixedOrderUnderlying: have " + underlying.getClass());
    }

    public static double getValue(final Map<UnderlyingType, Double> underlyingData, final Underlying underlying) {
        Validate.notNull(underlying, "underlying");
        Validate.notNull(underlyingData, "underlying data");
        Validate.notEmpty(underlyingData, "underlying data");
        Validate.noNullElements(underlyingData.keySet(), "underlying data keys");
        Validate.noNullElements(underlyingData.values(), "underlying data values");
        if (underlying instanceof NthOrderUnderlying) {
            final NthOrderUnderlying nthOrder = (NthOrderUnderlying) underlying;
            final int n = nthOrder.getOrder();
            if (n == 0) {
                return 1;
            }
            final UnderlyingType type = nthOrder.getUnderlying();
            Validate.isTrue(underlyingData.containsKey(type));
            final double value = Math.pow(underlyingData.get(type), n);
            return value * getMultiplier(underlying);
        } else if (underlying instanceof MixedOrderUnderlying) {
            final MixedOrderUnderlying mixedOrder = (MixedOrderUnderlying) underlying;
            Double result = null;
            double multiplier;
            for (final NthOrderUnderlying underlyingOrder : mixedOrder.getUnderlyingOrders()) {
                if (result == null) {
                    result = getValue(underlyingData, underlyingOrder);
                } else {
                    multiplier = getValue(underlyingData, underlyingOrder);
                    result = result * multiplier;
                }
            }
            if (result != null) {
                return result;
            }
        }
        throw new IllegalArgumentException(
                "Order was neither NthOrderUnderlying nor MixedOrderUnderlying: have " + underlying.getClass());
    }

    public static DoubleTimeSeries<?> getTimeSeries(final Map<UnderlyingType, DoubleTimeSeries<?>> underlyingData,
            final Underlying underlying) {
        Validate.notNull(underlying, "underlying");
        Validate.notNull(underlyingData, "underlying data");
        Validate.notEmpty(underlyingData, "underlying data");
        Validate.noNullElements(underlyingData.keySet(), "underlying data keys");
        Validate.noNullElements(underlyingData.values(), "underlying data values");
        if (underlying instanceof NthOrderUnderlying) {
            final NthOrderUnderlying nthOrder = (NthOrderUnderlying) underlying;
            final int n = nthOrder.getOrder();
            if (n == 0) {
                throw new UnsupportedOperationException();
            }
            final UnderlyingType type = nthOrder.getUnderlying();
            Validate.isTrue(underlyingData.containsKey(type));
            DoubleTimeSeries<?> ts = underlyingData.get(type);
            ts = ts.power(n);
            return ts.multiply(getMultiplier(underlying));
        } else if (underlying instanceof MixedOrderUnderlying) {
            final MixedOrderUnderlying mixedOrder = (MixedOrderUnderlying) underlying;
            DoubleTimeSeries<?> result = null;
            DoubleTimeSeries<?> multiplier = null;
            int size = 0;
            for (final NthOrderUnderlying underlyingOrder : mixedOrder.getUnderlyingOrders()) {
                if (result == null) {
                    result = getTimeSeries(underlyingData, underlyingOrder);
                    size = result.size();
                } else {
                    multiplier = getTimeSeries(underlyingData, underlyingOrder);
                    if (multiplier.size() != size) {
                        throw new IllegalArgumentException("Time series in map were not the same length");
                    }
                    result = result.multiply(multiplier);
                    if (result.size() != size) {
                        throw new IllegalArgumentException("Time series in map did not contain the same times");
                    }
                }
            }
            return result;
        }
        throw new IllegalArgumentException(
                "Order was neither NthOrderUnderlying nor MixedOrderUnderlying: have " + underlying.getClass());
    }
}