using System;
namespace QuantRiskLib
{
///Source: www.risk256.com
///
///References:
///Miller, Michael B. 2012. Mathematics and Statistics for Financial Risk Management. New York: John Wiley & Sons.
///Chapters 4, 6, 9
public class MonteCarlo
{
public class RandomPlus : Random
{
public RandomPlus()
{
}
public RandomPlus(int seed) : base(seed)
{
}
///
/// Returns a random number from a standard normal distribution.
///
public double NextStandardNormal()
{
return NextNormal(0.0, 1.0);
}
///
/// Returns a random number from a normal distribution with the given mean and standard deviation.
///
public double NextNormal(double mean, double standardDeviation)
{
double U = NextDouble();
double N = Distributions.NormalCumulativeDistributionFunctionInverse(U, mean, standardDeviation);
return N;
}
///
/// Returns a random number from a Student's t distribution.
///
public double NextStudentsT(double degreesOfFreedom)
{
double U = NextDouble();
double S = Distributions.StudentsTCumulativeDistributionFunctionInverse(U, degreesOfFreedom);
return S;
}
///
/// Returns a random number from a Poisson distribution with the given mean.
///
public int NextPoisson(double mean)
{
double L = Math.Exp(-mean);
int k = 0;
double p = 1.0;
do
{
k++;
p *= NextDouble();
} while (p > L);
return k - 1;
}
}
///
/// Correlation is not preserved when transforming two normal variables to two uniform variables.
/// Returns the required correlation between the two normal variables needed to produce the desired correlation
/// between the two uniform variables.
///
/// The desired correlation between the two uniform variables
///
public static double UniformToNormalCorrelation(double uniformCorr)
{
//Without correction max error would be ~1.81% and mean absolute error would be ~1.17%.
//This approximation will reduce the max error to within ~0.06% and the mean absolute error to withing ~0.02%.
double uCorrPi = uniformCorr * Math.PI;
double normalCorr = uniformCorr + 0.01818 * Math.Sin(uCorrPi) - 0.00221 * Math.Sin(2 * uCorrPi) + 0.000647 * Math.Sin(3 * uCorrPi);
return normalCorr;
}
}
}
//Disclaimer
//This code is freeware. The methods are not proprietary. Feel free to use, modify and redistribute. That said, if you plan
//to use or redistribute give credit where credit is due and provide a link back to Risk256.com (or don't remove the link
//and references already in the code). The code is intended primarily as an educational tool. No warranty is made as to the
//code's accuracy. Use at your own risk.