Пример #1
0
        /// <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));
        }
Пример #2
0
        /// <summary>
        /// Assumes returns are normally distributed.
        /// WARNING: Not very accurate. Intended for educational use and as a baseline for comparison to other models.
        /// </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>
        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));
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <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);
        }