/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.equity.variance.pricing; import java.util.Arrays; import com.opengamma.analytics.financial.varianceswap.VarianceSwap; import com.opengamma.analytics.math.FunctionUtils; import com.opengamma.analytics.math.function.Function1D; import com.opengamma.util.ArgumentChecker; /** * Model-independent realized variance result of the swap based upon observations already made.<p> * Notes on market-standard form :<p> * Computed as the average daily variance of log returns, scaled by an annualization factor, an estimate of the number of business days per year<p> * In this calculation, the average is taken over the actual number of observations provided. * In variance instruments, the number of actual observations may be less than number expected, * due to unforeseen market disruptions. To account for this, the sum is normalized by nObsExpected (>= nObsActual) * The realized variance calculated in this class do not perform this normalization. See {@link VarianceSwapStaticReplication#presentValue} * for an example of this normalization. */ public class RealizedVariance extends Function1D<VarianceSwap, Double> { @Override public Double evaluate(final VarianceSwap swap) { ArgumentChecker.notNull(swap, "swap"); final double[] obs = swap.getObservations(); final int nObs = obs.length; if (nObs < 2) { return 0.0; } final double[] weights = new double[obs.length - 1]; if (swap.getObservationWeights().length == 0) { Arrays.fill(weights, 1.0); } else if (swap.getObservationWeights().length == 1) { Arrays.fill(weights, swap.getObservationWeights()[0]); } else { final int nWeights = swap.getObservationWeights().length; ArgumentChecker.isTrue(nWeights == nObs - 1, "If provided, observationWeights must be of length one less than observations, as they weight returns log(obs[i]/obs[i-1])." + " Found {} weights and {} observations.", nWeights, nObs); } ArgumentChecker.isTrue(obs[0] != 0.0, "In VarianceSwap, the first observation is zero so the estimate of RealizedVariance is undefined. Check time series."); double logReturns = 0; for (int i = 1; i < nObs; i++) { ArgumentChecker.isTrue(Double.compare(obs[i], 0.0) != 0, "Encountered an invalid observation of zero in VarianceSwap at {}'th observation. " + "The estimate of RealizedVariance is undefined. Check time series.", i); logReturns += weights[i - 1] * FunctionUtils.square(Math.log(obs[i] / obs[i - 1])); } return logReturns / (nObs - 1) * swap.getAnnualizationFactor(); } }