/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.timeseries.util;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.timeseries.date.DateDoubleTimeSeries;
import com.opengamma.timeseries.date.localdate.ImmutableLocalDateDoubleTimeSeries;
import com.opengamma.util.ArgumentChecker;
/**
* Operator to calculate the ratio or relative return of a time series: ratio = (V(end) - V(start)) / V(start)
* The ratio is taken between elements in the time series with a certain lag.
* The default lag is 1 element, which means that the difference is between consecutive entries in the series.
* The series returned has less element than the input series by the lag.
* The dates of the returned time series are the dates of the end of the period on which the difference is computed.
*/
public class TimeSeriesPercentageChangeOperator extends Function1D<DateDoubleTimeSeries<?>, DateDoubleTimeSeries<?>> {
/** The default lag: 1 time series element. */
private static final int DEFAULT_LAG = 1;
/** The lag between the element of the times series on which the difference is taken. */
private final int _lag;
/**
* Constructor with the default lag of 1 element.
*/
public TimeSeriesPercentageChangeOperator() {
this._lag = DEFAULT_LAG;
}
/**
* Constructor with a specified lag.
* @param lag The lag between element to compute the difference.
*/
public TimeSeriesPercentageChangeOperator(int lag) {
this._lag = lag;
}
@Override
public DateDoubleTimeSeries<?> evaluate(DateDoubleTimeSeries<?> ts) {
ArgumentChecker.notNull(ts, "time series");
ArgumentChecker.isTrue(ts.size() > _lag, "time series length must be > lag");
final int[] times = ts.timesArrayFast();
final double[] values = ts.valuesArrayFast();
final int n = times.length;
final int[] resultTimes = new int[n - _lag];
final double[] percentageChanges = new double[n - _lag];
for (int i = _lag; i < n; i++) {
ArgumentChecker.isTrue(values[i - _lag] != 0.0d,
"value equal to 0 at date {}, no relative change can be computed", times[i - _lag]);
resultTimes[i - _lag] = times[i];
percentageChanges[i - _lag] = (values[i] - values[i - _lag]) / values[i - _lag];
}
return ImmutableLocalDateDoubleTimeSeries.of(resultTimes, percentageChanges);
}
}