/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.var;
import org.apache.commons.lang.ObjectUtils;
import com.opengamma.analytics.math.function.Function;
import com.opengamma.util.ArgumentChecker;
/**
*
* @param <T> The type of the data
*/
public class CornishFisherDeltaGammaVaRCalculator<T> implements VaRCalculator<NormalVaRParameters, T> {
private final Function<T, Double> _meanCalculator;
private final Function<T, Double> _stdCalculator;
private final Function<T, Double> _skewCalculator;
private final Function<T, Double> _kurtosisCalculator;
public CornishFisherDeltaGammaVaRCalculator(final Function<T, Double> meanCalculator, final Function<T, Double> stdCalculator,
final Function<T, Double> skewCalculator, final Function<T, Double> kurtosisCalculator) {
ArgumentChecker.notNull(meanCalculator, "mean calculator");
ArgumentChecker.notNull(stdCalculator, "standard deviation calculator");
ArgumentChecker.notNull(skewCalculator, "skew calculator");
ArgumentChecker.notNull(kurtosisCalculator, "kurtosis calculator");
_meanCalculator = meanCalculator;
_stdCalculator = stdCalculator;
_skewCalculator = skewCalculator;
_kurtosisCalculator = kurtosisCalculator;
}
public Function<T, Double> getMeanCalculator() {
return _meanCalculator;
}
public Function<T, Double> getStandardDeviationCalculator() {
return _stdCalculator;
}
public Function<T, Double> getSkewCalculator() {
return _skewCalculator;
}
public Function<T, Double> getKurtosisCalculator() {
return _kurtosisCalculator;
}
@SuppressWarnings("unchecked")
@Override
public VaRCalculationResult evaluate(final NormalVaRParameters parameters, final T... data) {
ArgumentChecker.notNull(parameters, "parameters");
ArgumentChecker.notNull(data, "data");
final double z = parameters.getZ();
final double mult = parameters.getTimeScaling();
final double zSq = z * z;
final double mean = _meanCalculator.evaluate(data);
final double std = _stdCalculator.evaluate(data);
final double skew = _skewCalculator.evaluate(data);
final double kurtosis = _kurtosisCalculator.evaluate(data);
final double x = z + skew * (zSq - 1) / 6. + kurtosis * z * (zSq - 3) / 24. - skew * skew * z * (2 * zSq - 5) / 36.;
final double value = x * std * mult + mean * mult * mult;
// REVIEW kirk 2012-06-22 -- Can we use "std" as the standard deviation?
return new VaRCalculationResult(value, null);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + _kurtosisCalculator.hashCode();
result = prime * result + _meanCalculator.hashCode();
result = prime * result + _skewCalculator.hashCode();
result = prime * result + _stdCalculator.hashCode();
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CornishFisherDeltaGammaVaRCalculator<?> other = (CornishFisherDeltaGammaVaRCalculator<?>) obj;
if (!ObjectUtils.equals(_kurtosisCalculator, other._kurtosisCalculator)) {
return false;
}
if (!ObjectUtils.equals(_meanCalculator, other._meanCalculator)) {
return false;
}
if (!ObjectUtils.equals(_skewCalculator, other._skewCalculator)) {
return false;
}
return ObjectUtils.equals(_stdCalculator, other._stdCalculator);
}
}