/// <summary> /// Log normal OU process upper bound /// </summary> /// <param name="spot"></param> /// <param name="confidence"></param> /// <param name="kappa"></param> /// <param name="theta"></param> /// <param name="sigma"></param> /// <param name="time"></param> /// <returns></returns> public static double LNOUUpperBound(double spot, double confidence, double kappa, double theta, double sigma, double time) { double mu = OUMean(kappa, theta, spot, time); double z = InvCumulativeNormalDistribution.Function(confidence); double lhs = Math.Exp(mu + z * sigma * Math.Sqrt((1 - Math.Exp(-2 * kappa * time)) / 2 / kappa)); return(lhs); }
/// <summary> /// Potential upside. /// </summary> /// <param name="percentile">Percentile must be in range 90%-100%.</param> /// <param name="mean"></param> /// <param name="std"></param> /// <returns></returns> public static double PotentialUpside(double percentile, double mean, double std) { if (percentile >= 1.0 || percentile < 0.9) { throw new ArgumentOutOfRangeException(nameof(percentile)); } // Percentile (={0}) out of range 90%<=p<100%.// var gInverse = new InvCumulativeNormalDistribution(mean, std); // PotenzialUpSide must be a gain // this means that it has to be MAX(dist(percentile), 0.0) return(Math.Max(gInverse.Value(percentile), 0.0)); }
/// <summary> /// Value at Risk (VaR). /// </summary> /// <param name="percentile">Percentile must be in range 90%-100%.</param> /// <param name="mean"></param> /// <param name="std"></param> /// <returns></returns> public static double ValueAtRisk(double percentile, double mean, double std) { if (percentile >= 1.0 || percentile < 0.9) { throw new ArgumentOutOfRangeException(nameof(percentile)); } // Percentile (={0}) out of range 90%<=p<100%. var gInverse = new InvCumulativeNormalDistribution(mean, std); // VAR must be a loss // this means that it has to be MIN(dist(1.0-percentile), 0.0) // VAR must also be a positive quantity, so -MIN(*) return(-Math.Min(gInverse.Value(1.0 - percentile), 0.0)); }
/// <summary> /// Expected shortfall. /// </summary> /// <param name="percentile">Percentile must be in range 90%-100%.</param> /// <param name="mean"></param> /// <param name="std"></param> /// <returns></returns> public static double ExpectedShortfall(double percentile, double mean, double std) { if (percentile >= 1.0 || percentile < 0.9) { throw new ArgumentOutOfRangeException(nameof(percentile)); } // Percentile (={0}) out of range 90%<=p<100%. var gInverse = new InvCumulativeNormalDistribution(mean, std); double var = gInverse.Value(1.0 - percentile); var g = new NormalDistribution(mean, std); double result = mean - std * std * g.Value(var) / (1.0 - percentile); // expectedShortfall must be a loss // this means that it has to be MIN(result, 0.0) // expectedShortfall must also be a positive quantity, so -MIN(*) return(-Math.Min(result, 0.0)); }
public void SmallSampleCheck() { InvCumulativeNormalDistribution invCnd = new InvCumulativeNormalDistribution(); Assert.AreEqual(0.0, invCnd.ValueOf(0.5)); // values obtained with Maple 9.01 Assert.AreEqual(0.5, invCnd.ValueOf(.6914624613), 1e-6); Assert.AreEqual(-0.5, invCnd.ValueOf(0.3085375387), 1e-6); Assert.AreEqual(1.5, invCnd.ValueOf(.9331927987), 1e-6); Assert.AreEqual(-1.5, invCnd.ValueOf(0.06680720127), 1e-6); invCnd = new InvCumulativeNormalDistribution(1.0, 2.0); Assert.AreEqual(1.0, invCnd.ValueOf(0.5), 1e-6); // values obtained with Maple 9.01 Assert.AreEqual(0.5, invCnd.ValueOf(.4012936743), 1e-6); Assert.AreEqual(-0.5, invCnd.ValueOf(.2266273524), 1e-6); Assert.AreEqual(1.5, invCnd.ValueOf(.5987063257), 1e-6); Assert.AreEqual(-1.5, invCnd.ValueOf(.1056497737), 1e-6); }
///// <summary> ///// The zscore of a variable in a normal distribution. ///// </summary> ///// <param name="x"></param> ///// <returns>the z score.</returns> //public Double ZScore(Double x) //{ // var distribution = new NormalDistribution(); // return distribution.ZScore(x); //} /// <summary> /// The InverseDistributionFunction of a probability in a normal distribution. /// </summary> /// <param name="probability"></param> /// <returns>The x value.</returns> public Double InverseDistributionFunction(Double probability) { return(InvCumulativeNormalDistribution.Function(probability)); }