@Override public double expectedShortfallFromUnsorted(double level, DoubleArray sample) { return expectedShortfallResultFromUnsorted(level, sample).getValue(); }
@Override public QuantileResult quantileResultWithExtrapolationFromUnsorted(double level, DoubleArray sample) { return quantileDetails(level, sample, true, false); }
private QuantileResult quantileDetails( double level, DoubleArray sample, boolean isExtrapolated, boolean isEs) { int nbData = sample.size(); double[] w = weights(nbData); /* Sorting data and keeping weight information. The arrays are modified */ double[] s = sample.toArray(); DoubleArrayMath.sortPairs(s, w); double[] s2 = sample.toArray(); double[] order = new double[s2.length]; for (int i = 0; i < s2.length; i++) { order[i] = i; } DoubleArrayMath.sortPairs(s2, order); /* Find the index. */ double runningWeight = 0.0d; int index = nbData; while (runningWeight < 1.0d - level) { index--; runningWeight += w[index]; } if (isEs) { return esFromIndexRunningWeight(index, runningWeight, s2, w, order, level); } return quantileFromIndexRunningWeight(index, runningWeight, isExtrapolated, s2, w, order, level); }
public void es() { double level = 0.95; double es = METHOD.expectedShortfallFromUnsorted(level, DATA_123); double q = METHOD.quantileFromUnsorted(level, DATA_123); assertTrue(es > q); int nbPts = 20; double esExpected = 0.0d; for (int i = 0; i < nbPts; i++) { double qIntegral = level + i / (nbPts - 1.0d) * (1 - level); esExpected += ((i == 0 || i == nbPts - 1) ? 0.5 : 1.0d) * METHOD.quantileWithExtrapolationFromUnsorted(qIntegral, DATA_123); // Trapezoid method } esExpected /= (nbPts - 1); assertEquals(es, esExpected, TOLERANCE_ES_NI); }
private void check_quantile(double level) { double[] w = METHOD.weights(DATA_123.size()); double qComputed = METHOD.quantileFromUnsorted(level, DATA_123); double WI1 = 0.0d; int nbW = 0; for (int i = 0; i < DATA_123.size(); i++) { if (DATA_123.get(i) > qComputed) { WI1 += w[i]; nbW++; } } assertTrue(WI1 < 1.0d - level, "Weight of tail lower than level"); double[] w2 = w.clone(); double[] data = DATA_123.toArray(); DoubleArrayMath.sortPairs(data, w2); double WI = WI1 + w2[w.length - 1 - nbW]; assertTrue(WI > 1.0d - level, "Weight of tail+1 larger than level"); double alpha = (WI - (1 - level)) / (WI - WI1); double qExpected = (1 - alpha) * data[w.length - 1 - nbW] + alpha * data[w.length - 1 - nbW + 1]; assertEquals(qComputed, qExpected, TOLERANCE_WEIGHT, "Quantile."); }
public void es_extreme() { double level = 0.999; double es = METHOD.expectedShortfallFromUnsorted(level, DATA_123); double q = METHOD.quantileWithExtrapolationFromUnsorted(level, DATA_123); assertEquals(es, q, TOLERANCE_QUANTILE); }
public void weights() { double[] wComputed = METHOD.weights(DATA_123.size()); assertEquals(wComputed.length, DATA_123.size(), "Weight size is same as sample size"); double wTotal = 0.0d; for (int i = 0; i < wComputed.length; i++) { wTotal += wComputed[i]; } assertEquals(wTotal, 1.0, TOLERANCE_WEIGHT, "Total weight should be 1."); for (int i = 0; i < wComputed.length - 1; i++) { assertEquals(wComputed[i + 1], wComputed[i] / LAMBDA, TOLERANCE_WEIGHT, "Ratio between weights."); } }
public void quantile_details() { double[] level = {0.98, 0.981, 0.9811, 0.97}; for (int i = 0; i < level.length; i++) { double q = METHOD.quantileFromUnsorted(level[i], DATA_123); QuantileResult r = METHOD.quantileDetailsFromUnsorted(level[i], DATA_123); assertEquals(r.getValue(), q, TOLERANCE_QUANTILE); assertEquals(r.getIndices().length, r.getWeights().size()); double qExpected = 0.0; for (int j = 0; j < r.getIndices().length; j++) { // Recompute quantile from details qExpected += DATA_123.get(r.getIndices()[j]) * r.getWeights().get(j); } assertEquals(qExpected, q, TOLERANCE_QUANTILE); } }
public void es_details() { double[] level = {0.98, 0.981, 0.9811, 0.97}; for (int i = 0; i < level.length; i++) { double es = METHOD.expectedShortfallFromUnsorted(level[i], DATA_123); QuantileResult r = METHOD.expectedShortfallDetailsFromUnsorted(level[i], DATA_123); assertEquals(r.getValue(), es, TOLERANCE_QUANTILE); assertEquals(r.getIndices().length, r.getWeights().size()); double qExpected = 0.0; for (int j = 0; j < r.getIndices().length; j++) { // Recompute ES from details qExpected += DATA_123.get(r.getIndices()[j]) * r.getWeights().get(j); } assertEquals(qExpected, es, TOLERANCE_QUANTILE); } }
public void lambda_zero() { assertThrowsIllegalArg(() -> new ExponentiallyWeightedInterpolationQuantileMethod(0.0d)); }
public void quantile_not_extrapolated() { double level = 0.999; assertThrowsIllegalArg(() -> METHOD.quantileFromUnsorted(level, DATA_123)); }
public void lambda_negative() { assertThrowsIllegalArg(() -> new ExponentiallyWeightedInterpolationQuantileMethod(-0.10d)); }
@Override public QuantileResult expectedShortfallResultFromUnsorted(double level, DoubleArray sample) { return quantileDetails(level, sample, true, true); }
public void lambda_above_1() { assertThrowsIllegalArg(() -> new ExponentiallyWeightedInterpolationQuantileMethod(1.10d)); }
@Override public QuantileResult quantileResultFromUnsorted(double level, DoubleArray sample) { return quantileDetails(level, sample, false, false); }
/** * Compute the quantile estimation and the details used in the result. * <p> * The quantile level is in decimal, i.e. 99% = 0.99 and 0 < level < 1 should be satisfied. * This is measured from the bottom, that is, Thus the quantile estimation with the level 99% corresponds to * the smallest 99% observations. * <p> * The details consists on the indices of the samples actually used in the quantile computation - indices in the * input sample - and the weights for each of those samples. The details are sufficient to recompute the * quantile directly from the input sample. * <p> * The sample observations are supposed to be unsorted, the first step is to sort the data. * * @param level the quantile level * @param sample the sample observations * @return The quantile estimation and its details */ public QuantileResult quantileDetailsFromUnsorted(double level, DoubleArray sample) { return quantileDetails(level, sample, true, false); }
/** * Compute the expected shortfall and the details used in the result. * <p> * The quantile level is in decimal, i.e. 99% = 0.99 and 0 < level < 1 should be satisfied. * This is measured from the bottom, that is, Thus the expected shortfall with the level 99% corresponds to * the smallest 99% observations. * <p> * If index value computed from the level is outside of the sample data range, the nearest data point is used, i.e., * expected short fall is computed with flat extrapolation. * Thus this is coherent to {@link #quantileWithExtrapolationFromUnsorted(double, DoubleArray)}. * <p> * The details consists on the indices of the samples actually used in the expected shortfall computation - indices * in the input sample - and the weights for each of those samples. The details are sufficient to recompute the * expected shortfall directly from the input sample. * <p> * The sample observations are supposed to be unsorted, the first step is to sort the data. * * @param level the quantile level * @param sample the sample observations * @return The expected shortfall estimation and its detail */ public QuantileResult expectedShortfallDetailsFromUnsorted(double level, DoubleArray sample) { return quantileDetails(level, sample, true, true); }