DrawdownCalculator extends Function1D<DateDoubleTimeSeries<?>, DateDoubleTimeSeries<?>> { @Override public DateDoubleTimeSeries<?> evaluate(final DateDoubleTimeSeries<?> ts) { Validate.notNull(ts, "time series"); Validate.isTrue(ts.size() > 0); final int n = ts.size(); final int[] t = ts.timesArrayFast(); final double[] drawdown = new double[n]; t[0] = ts.getEarliestTimeFast(); drawdown[0] = 0; double peak = ts.getEarliestValueFast(); double value; for (int i = 1; i < n; i++) { value = ts.getValueAtIndexFast(i); if (value > peak) { peak = value; drawdown[i] = 0; } else { drawdown[i] = (peak - value) / peak; } } return ImmutableLocalDateDoubleTimeSeries.of(t, drawdown); }  @Override DateDoubleTimeSeries<?> evaluate(final DateDoubleTimeSeries<?> ts);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullTS() { CALCULATOR.evaluate((DateDoubleTimeSeries<?>) null); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testEmptyTS() { CALCULATOR.evaluate(ImmutableLocalDateDoubleTimeSeries.EMPTY_SERIES); }
@Test public void test() { assertTimeSeriesEquals(CALCULATOR.evaluate(ImmutableLocalDateDoubleTimeSeries.of(T, FLAT)), ImmutableLocalDateDoubleTimeSeries.of(T, FLAT_DRAWDOWN)); assertTimeSeriesEquals(CALCULATOR.evaluate(ImmutableLocalDateDoubleTimeSeries.of(T, HIGH_FIRST)), ImmutableLocalDateDoubleTimeSeries.of(T, HIGH_FIRST_DRAWDOWN)); assertTimeSeriesEquals(CALCULATOR.evaluate(ImmutableLocalDateDoubleTimeSeries.of(T, X)), ImmutableLocalDateDoubleTimeSeries.of(T, X_DRAWDOWN)); }