/** * 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.Function2D; import com.opengamma.timeseries.date.DateDoubleTimeSeries; import com.opengamma.timeseries.date.localdate.ImmutableLocalDateDoubleTimeSeries; /** * Function taking a timeseries and a series of weightings, producing * a new timeseries where the entries in the timeseries are * weighted according to the values in the weighting series. */ public class TimeSeriesRelativeWeightedDifferenceOperator extends Function2D<DateDoubleTimeSeries<?>, DateDoubleTimeSeries<?>> { /** * Operator to compute difference between the entries in a timeseries. */ private static final TimeSeriesDifferenceOperator DIFFERENCE = new TimeSeriesDifferenceOperator(); /** * Function taking a timeseries and a series of weightings, producing * a new timeseries where the entries in the timeseries are * weighted according to the values in the weighting series. * <p> * The steps are as follows: * <ul> * <li>create a new series ds, containing the difference between each * element in the timeseries</li> * <li>validate that ds is the same size as the weights series</li> * <li>create a new series where each element is the corresponding * element in ds, divided by the corresponding weighting and * multiplied by the final weighting. If any weighting is zero * then a zero entry will be written (see PLT-426). * </ul> * * @param ts the timeseries to calculate weighted difference for * @param weights the series of weights to be used. This series * must be 1 element shorter than the timeseries. * @return a new weighted timeseries, equal in length to the weights * used */ @Override public DateDoubleTimeSeries<?> evaluate(DateDoubleTimeSeries<?> ts, DateDoubleTimeSeries<?> weights) { DateDoubleTimeSeries<?> differenceSeries = DIFFERENCE.evaluate(ts); if (differenceSeries.size() != weights.size()) { throw new IllegalArgumentException("Difference series has " + differenceSeries.size() + " points but weighting series has " + weights.size()); } int n = differenceSeries.size(); double endWeight = weights.getLatestValueFast(); double[] weightedDifferences = new double[n]; for (int i = 0; i < n; i++) { double weight = weights.getValueAtIndexFast(i); weightedDifferences[i] = weight == 0 ? 0 : differenceSeries.getValueAtIndexFast(i) * endWeight / weight; } return ImmutableLocalDateDoubleTimeSeries.of(differenceSeries.timesArrayFast(), weightedDifferences); } }