/// <summary> /// Calculates Spearman's Rho. /// Correlation of ranks of array elements. /// </summary> public static double SpearmansRho(double[] array1, double[] array2) { if (array1.Length != array2.Length) { throw new ArgumentException("Arrays must be the same length"); } double[] rank1 = RankArray(array1); double[] rank2 = RankArray(array2); return(Moments.Correlation(rank1, rank2)); }
/// <summary> /// Assumes returns are normally distributed. /// <param name="returnArray">Historical returns from which VaR is to be calculated. The last value, with the highest index is assumed to be the most recent data point.</param> /// <param name="windowLength">Length of the VaR window. The number of historical returns that will be used to calculate the VaR.</param> /// <param name="confidenceLevel">VaR confidence level. 95% and 99% are typical values. If confidenceLevel is 95% then we expect 95% of days to be better (have a more positive return) than the VaR.</param> public static double NormalValueAtRisk(double[] returnArray, int windowLength, double confidenceLevel) { double[] da = new double[windowLength]; for (int i = 0; i < windowLength; i++) { da[i] = returnArray[returnArray.Length - windowLength + i]; } double mean = Moments.Mean(da); double standardDeviation = Moments.StandardDeviation(da); double var = Distributions.NormalCumulativeDistributionFunctionInverse(1 - confidenceLevel, mean, standardDeviation); return(-var); //By convention VaR is quoted as a positive value, even though it corresponds to a loss. }
/// <summary> /// Hybrid VaR is based on historical data, but weights more recent data more heavily. /// </summary> /// <param name="returnArray">Historical returns from which VaR is to be calculated. The last value, with the highest index is assumed to be the most recent data point.</param> /// <param name="windowLength">Length of the VaR window. The number of historical returns that will be used to calculate the VaR.</param> /// <param name="confidenceLevel">VaR confidence level. 95% and 99% are typical values. If confidenceLevel is 95% then we expect 95% of days to be better (have a more positive return) than the VaR.</param> /// <param name="decayFactor">For a decay factor d, the most recent data point has weight 1, the second d, the third d^2, ...</param> /// <param name="correctSerialCorrelation">If true, correction is for infinite return length.</param> public static double HybridValueAtRisk(double[] returnArray, int windowLength, double confidenceLevel, double decayFactor, bool correctSerialCorrelation) { double uncorrected = HybridValueAtRisk(returnArray, windowLength, confidenceLevel, decayFactor); if (!correctSerialCorrelation) { return(uncorrected); } double[] subArray = Tools.MostRecentValues(returnArray, windowLength); double serialCorrelation = Moments.SerialCorrelation(subArray, decayFactor); double varianceCorrectionFactor = SerialCorrelationCorrection.SerialCorrelationVarianceCorrection(serialCorrelation); //don't use version w/ windowLength. windowLenght != length. Length is how far back we go to get data for the calculation. windowLenght is the return lenght that we are correcting to (infinite, by default). return(uncorrected * Math.Sqrt(varianceCorrectionFactor)); }
/// <summary> /// Returns the incremental incremental VaR for the subportfolio relative to the portfolio. /// </summary> /// <param name="portfolioArray">Return array of portfolio. The last element (index = n-1), is the most recent.</param> /// <param name="subPortfolioArray">Return array of the sub-portfolio for which incremental VaR is being measured. The last element (index = n-1), is the most recent.</param> /// <param name="decayFactor">In most applications, the decay factor is between 0 and 1. Weigth on the last element in arrays is 1.0, the 2nd to last element d, 3rd to last d^2, ...</param> /// <param name="portfolioValutAtRisk">Value at risk of the portfolio.</param> /// <param name="length">Window length. Method uses the most recent n points, n = length.</param> public static double IncrementalValueAtRisk(double[] portfolioArray, double[] subPortfolioArray, double decayFactor, double portfolioValutAtRisk, int length) { double[] portfolioArrayLen = Tools.MostRecentValues(portfolioArray, length); double[] subPortfolioArrayLen = Tools.MostRecentValues(subPortfolioArray, length); double portfolioStandardDeviation = Moments.StandardDeviation(portfolioArray, decayFactor, length); if (Tools.ArrayAllEqual(subPortfolioArray)) { return(0.0); } double iStandardDeviation = Moments.IncrementalStandardDeviation(portfolioArrayLen, subPortfolioArrayLen, decayFactor); return((portfolioValutAtRisk / portfolioStandardDeviation) * iStandardDeviation); }
/// <summary> /// Returns the slope of an OLS regression analysis. /// </summary> /// <param name="yData">Data for the dependent variable, or regressand.</param> /// <param name="xData">Data for the independent variable, or regressor.</param> /// <param name="length">Window length. Method uses the most recent n points, n = length.</param> public static double Beta(double[] yData, double[] xData, int length) { double[] xDataSubSet = Tools.MostRecentValues(xData, length); double[] yDataSubSet = Tools.MostRecentValues(yData, length); double mX = Moments.Mean(xData); double mY = Moments.Mean(yData); double sumXY = 0, sumXX = 0; for (int i = 0; i < length; i++) { sumXY += xDataSubSet[i] * yDataSubSet[i]; sumXX += xDataSubSet[i] * xDataSubSet[i]; } return((sumXY - length * mY * mX) / (sumXX - length * mX * mX)); }
/// <summary> /// Returns the incremental incremental VaR for the subportfolio relative to the portfolio. /// </summary> /// <param name="portfolioArray">Return array of portfolio. The last element (index = n-1), is the most recent.</param> /// <param name="subPortfolioArray">Return array of the sub-portfolio for which incremental VaR is being measured. The last element (index = n-1), is the most recent.</param> /// <param name="decayFactor">In most applications, the decay factor is between 0 and 1. Weigth on the last element in arrays is 1.0, the 2nd to last element d, 3rd to last d^2, ...</param> /// <param name="portfolioValutAtRisk">Value at risk of the portfolio.</param> /// <param name="length">Window length. Method uses the most recent n points, n = length.</param> /// <param name="correctSerialCorrelation">If true, correction is for infinite return length.</param> public static double IncrementalValueAtRisk(double[] portfolioArray, double[] subPortfolioArray, double decayFactor, double portfolioValutAtRisk, int length, bool correctSerialCorrelation) { double uncorrected = IncrementalValueAtRisk(portfolioArray, subPortfolioArray, decayFactor, portfolioValutAtRisk, length); if (!correctSerialCorrelation || uncorrected == 0.0) { return(uncorrected); } int len = portfolioArray.Length; double[] otherArray = new double[len]; for (int i = 0; i < len; i++) { otherArray[i] = portfolioArray[i] - subPortfolioArray[i]; } Matrix CStar = Moments.CovarianceMatrixSerialCorrelationCorrected(portfolioArray, otherArray, decayFactor, length); double sdPort = Math.Sqrt(CStar[0, 0] + CStar[1, 1] + 2 * CStar[0, 1]); double iStandardDeviation = (CStar[0, 0] + CStar[0, 1]) / sdPort; return((portfolioValutAtRisk / sdPort) * iStandardDeviation); }