/*
 Copyright (C) 2009 Ueli Hofstetter
 Copyright (C) 2010 Richard Gomes

 This source code is release under the BSD License.

 This file is part of JQuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://jquantlib.org/

 JQuantLib is free software: you can redistribute it and/or modify it
 under the terms of the JQuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.

 JQuantLib is based on QuantLib. http://quantlib.org/
 When applicable, the original copyright notice follows this notice.
 */

/*
 Copyright (C) 2003 RiskMap srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

package org.jquantlib.math.statistics;

import java.util.ArrayList;
import java.util.List;

import org.jquantlib.QL;
import org.jquantlib.lang.annotation.QualityAssurance;
import org.jquantlib.lang.annotation.QualityAssurance.Quality;
import org.jquantlib.lang.annotation.QualityAssurance.Version;
import org.jquantlib.math.Ops;
import org.jquantlib.math.functions.Bind1st;
import org.jquantlib.math.functions.Bind1stPredicate;
import org.jquantlib.math.functions.Bind2nd;
import org.jquantlib.math.functions.Bind2ndPredicate;
import org.jquantlib.math.functions.Clipped;
import org.jquantlib.math.functions.Constant;
import org.jquantlib.math.functions.Expression;
import org.jquantlib.math.functions.Identity;
import org.jquantlib.math.functions.LessThanPredicate;
import org.jquantlib.math.functions.Minus;
import org.jquantlib.math.functions.Square;
import org.jquantlib.math.functions.TruePredicate;
import org.jquantlib.util.Pair;

/**
 * empirical-distribution risk measures
 * 

* This class wraps a somewhat generic statistic tool and adds * a number of risk measures (e.g.: value-at-risk, expected * shortfall, etc.) based on the data distribution as reported by * the underlying statistic tool. *

* @todo add historical annualized volatility * * @author Ueli Hofstetter * @author Richard Gomes */ @QualityAssurance(quality = Quality.Q4_UNIT, reviewers = { "Richard Gomes" }, version = Version.V097) public class GenericRiskStatistics extends GaussianStatistics { private static final String NO_DATA_BELOW_THE_TARGET = "no data below the target"; private static final String EMPTY_SAMPLE_SET = "empty sample set"; private static final String UNSUFFICIENT_SAMPLES_UNDER_TARGET = "samples under target <=1, unsufficient"; public GenericRiskStatistics() { super(); } // // public methods // /** * returns the variance of observations below the mean, * {@latex[ \frac{N}{N-1} * \mathrm{E}\left[ (x-\langle x \rangle)^2 \;|\; * x < \langle x \rangle \right]. } * * @see Markowitz (1959). */ public /*@Real*/ double semiVariance() /*@ReadOnly*/ { return regret(mean()); } /** * returns the semi deviation, defined as the * square root of the semi variance. */ public /*@Real*/ double semiDeviation() /*@ReadOnly*/ { return Math.sqrt(semiVariance()); } /** * returns the variance of observations below 0.0, * {@latex[ \frac{N}{N-1} * \mathrm{E}\left[ x^2 \;|\; x < 0\right]. } */ public /*@Real*/ double downsideVariance() /*@ReadOnly*/ { return regret(0.0); } /** * returns the downside deviation, defined as the * square root of the downside variance. */ public /*@Real*/ double downsideDeviation() /*@ReadOnly*/ { return Math.sqrt(downsideVariance()); } /** * returns the variance of observations below target, * {@latex[ \frac{N}{N-1} * \mathrm{E}\left[ (x-t)^2 \;|\; * x < t \right]. } * * @see Dembo and Freeman, "The Rules Of Risk", Wiley (2001). */ public /*@Real*/ double regret(final /*@Real*/ double target) /*@ReadOnly*/ { // average over the range below the target final List functions = new ArrayList(); functions.add(new Square()); functions.add(new Bind2nd(new Minus(), target)); final Expression comp = new Expression(functions); final Ops.DoublePredicate less = new Bind2ndPredicate(new LessThanPredicate(), target); final Pair result = expectationValue(comp, less); final double x = result.first(); final int n = result.second().intValue(); QL.require(n >= 2 , UNSUFFICIENT_SAMPLES_UNDER_TARGET); return (n/(n-1.0))*x; } /** * potential upside (the reciprocal of VaR) at a given percentile */ public /*@Real*/ double potentialUpside(final /*@Real*/ double centile) /*@ReadOnly*/ { QL.require(centile >= 0.9 && centile < 1.0 , "percentile out of range [0.9, 1.0)"); // potential upside must be a gain, i.e., floored at 0.0 return Math.max(percentile(centile), 0.0); } /** * value-at-risk at a given percentile */ public /*@Real*/ double valueAtRisk(final /*@Real*/ double centile) /*@ReadOnly*/ { QL.require(centile >= 0.9 && centile < 1.0 , "percentile out of range [0.9, 1.0)"); return - Math.min(percentile(1.0-centile), 0.0); } /** * expected shortfall at a given percentile *

* returns the expected loss in case that the loss exceeded * a VaR threshold, *

* {@latex[ \mathrm{E}\left[ x \;|\; x < \mathrm{VaR}(p) \right], } *

* that is the average of observations below the given percentile \f$ p \f$. * Also know as conditional value-at-risk. * * @see Artzner, Delbaen, Eber and Heath, "Coherent measures of risk", Mathematical Finance 9 (1999) */ public /*@Real*/ double expectedShortfall(final /*@Real*/ double centile) /*@ReadOnly*/ { QL.require(centile>=0.9 && centile<1.0, "percentile out of range [0.9, 1.0)"); QL.ensure(samples() != 0, EMPTY_SAMPLE_SET); final double target = -valueAtRisk(centile); final Ops.DoublePredicate less = new Bind2ndPredicate(new LessThanPredicate(), target); final Pair result = expectationValue(new Identity(), less); final double x = result.first(); final Integer N = result.second(); QL.ensure(N != 0, NO_DATA_BELOW_THE_TARGET); // must be a loss, i.e., capped at 0.0 and negated return -Math.min(x, 0.0); } /** * probability of missing the given target, defined as * {@latex[ \mathrm{E}\left[ \Theta \;|\; (-\infty,\infty) \right] } * where * {@latex[ \Theta(x) = \left\{ * \begin{array}{ll} * 1 & x < t \\ * 0 & x \geq t * \end{array} * \right. } */ public /*@Real*/ double shortfall(final /*@Real*/ double target) /*@ReadOnly*/ { QL.ensure(samples() != 0, EMPTY_SAMPLE_SET); final Ops.DoublePredicate less = new Bind2ndPredicate(new LessThanPredicate(), target); return expectationValue(new Clipped(less, new Constant(1.0)), new TruePredicate()).first(); } /** * averaged shortfallness, defined as * {@latex[ \mathrm{E}\left[ t-x \;|\; x result = expectationValue(minus, less); final double x = result.first(); final Integer N = result.second(); QL.ensure(N != 0, NO_DATA_BELOW_THE_TARGET); return x; } }

Ads help maintain this website.