Package com.opengamma.analytics.financial.covariance

Source Code of com.opengamma.analytics.financial.covariance.HistoricalVolatilityCalculator

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

import static com.opengamma.analytics.financial.timeseries.util.TimeSeriesDataTestUtils.testNotNullOrEmpty;
import static com.opengamma.analytics.financial.timeseries.util.TimeSeriesDataTestUtils.testTimeSeriesDates;
import static com.opengamma.analytics.financial.timeseries.util.TimeSeriesDataTestUtils.testTimeSeriesSize;

import java.util.Iterator;

import com.opengamma.timeseries.DoubleTimeSeries;
import com.opengamma.timeseries.TimeSeriesException;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.CalculationMode;

/**
* Base class for historical volatility calculators.
*/
public abstract class HistoricalVolatilityCalculator implements VolatilityCalculator {
  /** The default calculation mode */
  private static final CalculationMode DEFAULT_CALCULATION_MODE = CalculationMode.STRICT;
  /** The default percentage of bad data points allowed */
  private static final double DEFAULT_PERCENT_BAD_DATA_POINTS = 0.0;
  /** The calculation mode */
  private final CalculationMode _mode;
  /** The percentage of bad data points allowed */
  private final double _percentBadDataPoints;

  /**
   * Sets the calculation mode and acceptable percentage of bad data points to the default value (strict and 0 respectively)
   */
  public HistoricalVolatilityCalculator() {
    this(DEFAULT_CALCULATION_MODE, DEFAULT_PERCENT_BAD_DATA_POINTS);
  }

  /**
   * Sets the acceptable percentage of bad data points to the default value, 0
   * @param mode The calculation mode
   */
  public HistoricalVolatilityCalculator(final CalculationMode mode) {
    this(mode, DEFAULT_PERCENT_BAD_DATA_POINTS);
  }

  /**
   * @param mode The calculation mode, not null
   * @param percentBadDataPoints The acceptable percentage of bad data points, must be >= 0 and <= 1
   */
  public HistoricalVolatilityCalculator(final CalculationMode mode, final double percentBadDataPoints) {
    ArgumentChecker.notNull(mode, "mode");
    ArgumentChecker.isInRangeInclusive(0, 1, percentBadDataPoints);
    _mode = mode;
    _percentBadDataPoints = percentBadDataPoints;
  }

  /**
   * Checks that the time series array is not null, empty and that the first entry is not null
   * @param tsArray The time series array, not null or empty
   * @param minLength The minimum of entries in the time series
   */
  protected void testTimeSeries(final DoubleTimeSeries<?>[] tsArray, final int minLength) {
    ArgumentChecker.notEmpty(tsArray, "array of time series");
    testNotNullOrEmpty(tsArray[0]);
    final DoubleTimeSeries<?> ts = tsArray[0];
    testTimeSeriesSize(ts, minLength);
    for (int i = 1; i < tsArray.length; i++) {
      testTimeSeriesSize(tsArray[i], minLength);
      testTimeSeriesDates(ts, tsArray[i]);
    }
  }

  /**
   * Tests that the high price for a date is greater than the low value for the same date.
   * @param high The period high price time series
   * @param low The period low price time series
   * @throws IllegalArgumentException Strict calculation mode: if the low value for a date is greater than the high value. Lenient calculation mode: if the percentage of times
   * that the low value for a date is greater than the high value is greater than the maximum allowed
   */
  protected void testHighLow(final DoubleTimeSeries<?> high, final DoubleTimeSeries<?> low) {
    final double size = high.size();
    int count = 0;
    final Iterator<Double> highIter = high.valuesIterator();
    final Iterator<Double> lowIter = low.valuesIterator();
    boolean compare;
    while (highIter.hasNext()) {
      compare = highIter.next() < lowIter.next();
      if (compare) {
        if (_mode == CalculationMode.STRICT) {
          throw new TimeSeriesException("Not all values in the high series were greater than the values in the low series");
        }
        count++;
      }
    }
    final double percent = count / size;
    if (percent > _percentBadDataPoints) {
      throw new TimeSeriesException("Percent " + percent + " of bad data points is greater than " + _percentBadDataPoints);
    }
  }

  /**
   * Tests that the high price for a date is greater than the low value for the same date and that the close price falls in this (inclusive) range
   * @param high The period high price time series
   * @param low The period low price time series
   * @param close The period close price time series
   * @throws IllegalArgumentException Strict calculation mode: if the low value for a date is greater than the high value or if the close value is not in the range bounded
   * by the high and low prices. Lenient calculation mode: if the percentage of times that the low value for a date is greater than the high value or that the close value is
   * not in the range bounded by the high and low values is greater than the maximum allowed
   */
  protected void testHighLowClose(final DoubleTimeSeries<?> high, final DoubleTimeSeries<?> low, final DoubleTimeSeries<?> close) {
    final double size = high.size();
    int count = 0;
    final Iterator<Double> highIter = high.valuesIterator();
    final Iterator<Double> lowIter = low.valuesIterator();
    final Iterator<Double> closeIter = close.valuesIterator();
    boolean compare;
    double highValue, lowValue, closeValue;
    while (highIter.hasNext()) {
      highValue = highIter.next();
      lowValue = lowIter.next();
      closeValue = closeIter.next();
      compare = highValue < lowValue || closeValue > highValue || closeValue < lowValue;
      if (compare) {
        if (_mode == CalculationMode.STRICT) {
          throw new TimeSeriesException("Not all values in the high series were greater than the values in the low series");
        }
        count++;
      }
    }
    final double percent = count / size;
    if (percent > _percentBadDataPoints) {
      throw new TimeSeriesException("Percent " + percent + " of bad data points is greater than " + _percentBadDataPoints);
    }
  }

  /**
   *
   * @return The default calculation mode
   */
  protected static CalculationMode getDefaultCalculationMode() {
    return DEFAULT_CALCULATION_MODE;
  }

  /**
   *
   * @return The default percentage of bad data points
   */
  protected static double getDefaultBadDataPoints() {
    return DEFAULT_PERCENT_BAD_DATA_POINTS;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((_mode == null) ? 0 : _mode.hashCode());
    long temp;
    temp = Double.doubleToLongBits(_percentBadDataPoints);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final HistoricalVolatilityCalculator other = (HistoricalVolatilityCalculator) obj;
    if (_mode != other._mode) {
      return false;
    }
    if (Double.doubleToLongBits(_percentBadDataPoints) != Double.doubleToLongBits(other._percentBadDataPoints)) {
      return false;
    }
    return true;
  }
}
TOP

Related Classes of com.opengamma.analytics.financial.covariance.HistoricalVolatilityCalculator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.