com.opengamma.analytics.math.statistics.descriptive.PartialMomentCalculator.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.math.statistics.descriptive.PartialMomentCalculator.java

Source

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

import java.util.Arrays;

import org.apache.commons.lang.Validate;

import com.opengamma.analytics.math.function.Function1D;

/**
 * The second moment of a series of asset return data can be used as a measure
 * of the risk of that asset. However, in many instances a large positive
 * return is not regarded as a risk. The partial moment can be used as an
 * alternative.
 * <p>
 * The lower (higher) partial moment considers only those values that are below
 * (above) a threshold. Given a series of data $x_1, x_2, \dots, x_n$ sorted
 * from lowest to highest, the first (last) $k$ values are below (above) the
 * threshold $x_0$. The partial moment is given by:
 * $$ 
 * \begin{align*}
 * \text{pm} = \sqrt{\frac{1}{k}\sum\limits_{i=1}^{k}(x_i - x_0)^2}
 * \end{align*}
 * $$
 */
public class PartialMomentCalculator extends Function1D<double[], Double> {
    private final double _threshold;
    private final boolean _useDownSide;

    /**
     * Creates calculator with default values: threshold = 0 and useDownSide = true
     */
    public PartialMomentCalculator() {
        this(0, true);
    }

    /**
     * 
     * @param threshold The threshold value for the data
     * @param useDownSide If true, all data below the threshold is used
     */
    public PartialMomentCalculator(final double threshold, final boolean useDownSide) {
        _threshold = threshold;
        _useDownSide = useDownSide;
    }

    /**
     * @param x The array of data, not null or empty
     * @return The partial moment
     */
    @Override
    public Double evaluate(final double[] x) {
        Validate.notNull(x, "x");
        Validate.isTrue(x.length > 0, "x cannot be empty");
        final int n = x.length;
        final double[] copyX = Arrays.copyOf(x, n);
        Arrays.sort(copyX);
        double sum = 0;
        if (_useDownSide) {
            int i = 0;
            if (copyX[i] > _threshold) {
                return 0.;
            }
            while (i < n && copyX[i] < _threshold) {
                sum += (copyX[i] - _threshold) * (copyX[i] - _threshold);
                i++;
            }
            return Math.sqrt(sum / i);
        }
        int i = n - 1;
        int count = 0;
        if (copyX[i] < _threshold) {
            return 0.;
        }
        while (i >= 0 && copyX[i] > _threshold) {
            sum += (copyX[i] - _threshold) * (copyX[i] - _threshold);
            count++;
            i--;
        }
        return Math.sqrt(sum / count);
    }

}