Browse Source

Merge branch 'financial'

v2
Christoph Ruegg 14 years ago
parent
commit
f98e92e981
  1. 102
      src/Numerics/Financial/AbsoluteReturnMeasures.cs
  2. 140
      src/Numerics/Financial/AbsoluteRiskMeasures.cs
  3. 2
      src/Numerics/Numerics.csproj
  4. 6
      src/Portable/Portable.csproj
  5. 75
      src/UnitTests/FinancialTests/CompoundMonthlyReturnTests.cs
  6. 114
      src/UnitTests/FinancialTests/DownsideDeviationTests.cs
  7. 123
      src/UnitTests/FinancialTests/GainLossRatioTests.cs
  8. 106
      src/UnitTests/FinancialTests/GainMeanTests.cs
  9. 120
      src/UnitTests/FinancialTests/GainStandardDeviationTests.cs
  10. 106
      src/UnitTests/FinancialTests/LossMeanTests.cs
  11. 118
      src/UnitTests/FinancialTests/LossStandardDeviationTests.cs
  12. 109
      src/UnitTests/FinancialTests/SemiDeviationTests.cs
  13. 8
      src/UnitTests/UnitTests.csproj

102
src/Numerics/Financial/AbsoluteReturnMeasures.cs

@ -0,0 +1,102 @@
// <copyright file="AbsoluteReturnMeasures.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.Financial
{
using System;
using System.Collections.Generic;
using System.Linq;
using Statistics;
public static class AbsoluteReturnMeasures
{
/// <summary>
/// Compound Monthly Return or Geometric Return or Annualized Return
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static double CompoundMonthlyReturn(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var samples = data.Count();
if (samples == 0)
return double.NaN;
double compoundReturn = 1.0;
foreach (var item in data)
{
compoundReturn *= (1 + item);
}
return Math.Pow(compoundReturn, 1.0 / (double)samples) - 1.0;
}
/// <summary>
/// Average Gain or Gain Mean
/// This is a simple average (arithmetic mean) of the periods with a gain. It is calculated by summing the returns for gain periods (return 0)
/// and then dividing the total by the number of gain periods.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
/// <remarks>http://www.offshore-library.com/kb/statistics.php</remarks>
public static double GainMean(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var gains = data.Where(x => x >= 0);
return gains.Mean();
}
/// <summary>
/// Average Loss or LossMean
/// This is a simple average (arithmetic mean) of the periods with a loss. It is calculated by summing the returns for loss periods (return < 0)
/// and then dividing the total by the number of loss periods.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
/// <remarks>http://www.offshore-library.com/kb/statistics.php</remarks>
public static double LossMean(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var losses = data.Where(x => x < 0);
return losses.Mean();
}
}
}

140
src/Numerics/Financial/AbsoluteRiskMeasures.cs

@ -0,0 +1,140 @@
// <copyright file="AbsoluteRiskStatistics.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.Financial
{
using System;
using System.Collections.Generic;
using System.Linq;
using Statistics;
public static class AbsoluteRiskMeasures
{
//Note: The following statistics would be condidered an absolute risk statistic in the finance realm as well.
// Standard Deviation
// Annualized Standard Deviation = Math.Sqrt(Monthly Standard Deviation x ( 12 ))
// Skewness
// Kurtosis
/// <summary>
/// Calculation is similar to Standard Deviation , except it calculates an average (mean) return only for periods with a gain
/// and measures the variation of only the gain periods around the gain mean. Measures the volatility of upside performance.
/// © Copyright 1996, 1999 Gary L.Gastineau. First Edition. © 1992 Swiss Bank Corporation.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static double GainStandardDeviation(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var gains = data.Where(x => x >= 0);
return gains.StandardDeviation();
}
/// <summary>
/// Similar to standard deviation, except this statistic calculates an average (mean) return for only the periods with a loss and then
/// measures the variation of only the losing periods around this loss mean. This statistic measures the volatility of downside performance.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
/// <remarks>http://www.offshore-library.com/kb/statistics.php</remarks>
public static double LossStandardDeviation(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var losses = data.Where(x => x < 0);
return losses.StandardDeviation();
}
/// <summary>
/// This measure is similar to the loss standard deviation except the downside deviation
/// considers only returns that fall below a defined minimum acceptable return (MAR) rather than the arithmetic mean.
/// For example, if the MAR is 7%, the downside deviation would measure the variation of each period that falls below
/// 7%. (The loss standard deviation, on the other hand, would take only losing periods, calculate an average return for
/// the losing periods, and then measure the variation between each losing return and the losing return average).
/// </summary>
/// <param name="data"></param>
/// <param name="minimalAcceptableReturn"></param>
/// <returns></returns>
public static double DownsideDeviation(this IEnumerable<double> data, double minimalAcceptableReturn)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var belowMARData = data.Where(x => x < minimalAcceptableReturn);
return belowMARData.StandardDeviation();
}
/// <summary>
/// A measure of volatility in returns below the mean. It's similar to standard deviation, but it only
/// looks at periods where the investment return was less than average return.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static double SemiDeviation(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var mean = data.Mean();
var belowMeanData = data.Where(x => x < mean);
return belowMeanData.StandardDeviation();
}
/// <summary>
/// Measures a fund’s average gain in a gain period divided by the fund’s average loss in a losing
/// period. Periods can be monthly or quarterly depending on the data frequency.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static double GainLossRatio(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var gains = data.Where(x => x >= 0);
var losses = data.Where(x => x < 0);
return Math.Abs(gains.Mean() / losses.Mean());
}
}
}

2
src/Numerics/Numerics.csproj

@ -105,6 +105,8 @@
<Compile Include="Constants.cs" />
<Compile Include="Control.cs" />
<Compile Include="Complex32.cs" />
<Compile Include="Financial\AbsoluteReturnMeasures.cs" />
<Compile Include="Financial\AbsoluteRiskMeasures.cs" />
<Compile Include="LinearAlgebra\Generic\Matrix.BCL.cs" />
<Compile Include="LinearAlgebra\Generic\Vector.BCL.cs" />
<Compile Include="SpecialFunctions\Evaluate.cs" />

6
src/Portable/Portable.csproj

@ -192,6 +192,12 @@
<Compile Include="..\Numerics\Distributions\Multivariate\Wishart.cs">
<Link>Distributions\Multivariate\Wishart.cs</Link>
</Compile>
<Compile Include="..\Numerics\Financial\AbsoluteReturnMeasures.cs">
<Link>Financial\AbsoluteReturnMeasures.cs</Link>
</Compile>
<Compile Include="..\Numerics\Financial\AbsoluteRiskMeasures.cs">
<Link>Financial\AbsoluteRiskMeasures.cs</Link>
</Compile>
<Compile Include="..\Numerics\GlobalizationHelper.cs">
<Link>GlobalizationHelper.cs</Link>
</Compile>

75
src/UnitTests/FinancialTests/CompoundMonthlyReturnTests.cs

@ -0,0 +1,75 @@
// <copyright file="CompoundMonthlyReturnTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MathNet.Numerics.Financial;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class CompoundMonthlyReturnTests
{
[Test]
[ExpectedException(typeof(ArgumentNullException))] //assert
public void throws_when_input_data_is_null()
{
//arrange
List<double> inputData = null;
//act
inputData.CompoundMonthlyReturn();
}
[Test]
public void returns_undefined_with_empty_input_data()
{
//arrange
List<double> inputData = new List<double>();
//act
var cmpdReturn = inputData.CompoundMonthlyReturn();
//assert
Assert.AreEqual(double.NaN, cmpdReturn);
}
[Test]
public void calculates_the_compound_monthly_return()
{
//arrange
var inputData = new[] { 0.2, 0.06, 0.01 };
//act
var cmpdReturn = inputData.CompoundMonthlyReturn();
//assert
AssertHelpers.AlmostEqual(0.0870999982199265, cmpdReturn, 15);
}
//Definitly need more tests here. Would love to find test data for these stats similar to the .dat files used for other tests.
}
}

114
src/UnitTests/FinancialTests/DownsideDeviationTests.cs

@ -0,0 +1,114 @@
// <copyright file="DownsideDeviationTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using System.Linq;
using MathNet.Numerics.Financial;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class DownsideDeviationTests
{
[Test]
public void returns_undefined_with_no_input_data()
{
//arrange
const double minimumAcceptableReturn = 0.05;
var inputData = new List<double>();
//act
var dsDeviation = inputData.DownsideDeviation(minimumAcceptableReturn);
//assert
Assert.AreEqual(double.NaN, dsDeviation);
}
[Test]
public void returns_undefined_with_single_positive_input()
{
//arrange
const double minimumAcceptableReturn = 0.05;
var inputData = new[] { 1.0 };
//act
var dsDeviation = inputData.DownsideDeviation(minimumAcceptableReturn);
//assert
Assert.AreEqual(double.NaN, dsDeviation);
}
[Test]
public void returns_undefined_with_single_negative_input()
{
//arrange
const double minimumAcceptableReturn = 0.05;
var inputData = new[] { -1.0 };
//act
var dsDeviation = inputData.DownsideDeviation(minimumAcceptableReturn);
//assert
Assert.AreEqual(double.NaN, dsDeviation);
}
[Test]
public void only_uses_data_points_below_the_minimum_acceptable_return()
{
//arrange
const double minimumAcceptableReturn = 0.05;
var inputData = new[] { 0.0021, 0.02, 0.5, 0.12 };
var expectedSemiDeviation = inputData.Where(x => x < minimumAcceptableReturn).StandardDeviation();
//act
var semiDeviation = inputData.DownsideDeviation(minimumAcceptableReturn);
//assert
Assert.AreEqual(expectedSemiDeviation, semiDeviation);
}
[Test]
public void handles_negative_values()
{
//arrange
const double minimumAcceptableReturn = 0.05;
var inputData = new[] { -0.1, -0.02, 0.4, 0.12 };
var expectedSemiDeviation = inputData.Where(x => x < minimumAcceptableReturn).StandardDeviation();
//act
var semiDeviation = inputData.DownsideDeviation(minimumAcceptableReturn);
//assert
Assert.AreEqual(expectedSemiDeviation, semiDeviation);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))] //assert
public void throws_when_input_data_is_null()
{
//arrange
const double minimumAcceptableReturn = 0.05;
List<double> inputData = null;
//act
inputData.DownsideDeviation(minimumAcceptableReturn);
}
}
}

123
src/UnitTests/FinancialTests/GainLossRatioTests.cs

@ -0,0 +1,123 @@
// <copyright file="GainLossRatioTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using System.Linq;
using MathNet.Numerics.Financial;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class GainLossRatioTests
{
[Test]
[ExpectedException(typeof(ArgumentNullException))] //assert
public void throws_when_input_data_is_null()
{
//arrange
List<double> inputData = null;
//act
inputData.GainLossRatio();
}
[Test]
//Not sure this is correct. Undefined may be more correct.
public void returns_NaN_for_a_single_positive_input()
{
//arrange
var inputData = new[] { 1.0 };
//act
var gainLossRatio = inputData.GainLossRatio();
//assert
Assert.AreEqual(double.NaN, gainLossRatio);
}
[Test]
//Not sure this is correct. Undefined may be more correct.
public void returns_NaN_for_a_single_negative_input()
{
//arrange
var inputData = new[] { -1.0 };
//act
var gainLossRatio = inputData.GainLossRatio();
//assert
Assert.AreEqual(double.NaN, gainLossRatio);
}
[Test]
//Not sure this is correct. Undefined may be more correct.
public void returns_NaN_for_a_set_of_all_positive_numbers()
{
//arrange
var inputData = new[] { 1.0, 2.0, 3.0 };
//act
var gainLossRatio = inputData.GainLossRatio();
//assert
Assert.AreEqual(double.NaN, gainLossRatio);
}
[Test]
//Not sure this is correct. Undefined may be more correct.
public void returns_NaN_for_a_set_of_all_negative_numbers()
{
//arrange
var inputData = new[] { -1.0, -2.0, -3.0 };
//act
var gainLossRatio = inputData.GainLossRatio();
//assert
Assert.AreEqual(double.NaN, gainLossRatio);
}
[Test]
public void handles_a_value_of_zero_as_a_positive()
{
//arrange
var inputData = new[] { 0.0, -1.0 };
//act
var gainLossRatio = inputData.GainLossRatio();
//assert
Assert.AreEqual(0.0, gainLossRatio); //0.0 / -1.0 => 0.0
}
[Test]
public void calculates_the_correct_ratio_given_a_set_of_gains_and_losses()
{
//arrange
var inputData = new[] { -2.0, -1.0, 0.0, 1.0, 2.0 };
var meanOfGains = inputData.Where(x => x >= 0).Mean();
var meanOfLosses = inputData.Where(x => x < 0).Mean();
var expectedRatio = Math.Abs(meanOfGains / meanOfLosses);
//act
var gainLossRatio = inputData.GainLossRatio();
//assert
Assert.AreEqual(expectedRatio, gainLossRatio);
}
}
}

106
src/UnitTests/FinancialTests/GainMeanTests.cs

@ -0,0 +1,106 @@
// <copyright file="GainMeanTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using MathNet.Numerics.Financial;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class GainMeanTests
{
[Test]
public void returns_zero_when_its_the_only_data()
{
//arrange
var inputData = new[] { 0.0 };
//act
var gainMean = inputData.GainMean();
//assert
Assert.AreEqual(0.0, gainMean);
}
[Test]
public void returns_NaN_when_all_input_is_negative()
{
//arrange
var inputData = new[] { -1.0, -2.0, -3.0 };
//act
var gainMean = inputData.GainMean();
//assert
Assert.AreEqual(double.NaN, gainMean);
}
[Test]
public void returns_same_as_mean_when_all_values_are_positive()
{
//arrange
var inputData = new[] { 1.0, 2.0, 3.0 };
var mean = inputData.Mean();
//act
var gainMean = inputData.GainMean();
//assert
Assert.AreEqual(mean, gainMean);
}
[Test]
public void does_not_use_negative_input_values()
{
//arrange
var inputData = new[] { 1.0, -1.0 };
//act
var gainMean = inputData.GainMean();
//assert
Assert.AreEqual(1.0, gainMean);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void throws_when_input_data_is_null() //assert
{
//arrange
var inputData = new[] { 1.0 };
inputData = null;
//act
inputData.GainMean();
}
[Test]
public void returns_NaN_with_no_input_data()
{
//arrange
var inputData = new List<double>();
//act
var gainMean = inputData.GainMean();
//assert
Assert.AreEqual(double.NaN, gainMean);
}
}
}

120
src/UnitTests/FinancialTests/GainStandardDeviationTests.cs

@ -0,0 +1,120 @@
// <copyright file="GainStandardDeviationTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using System.Linq;
using MathNet.Numerics.Financial;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class GainStandardDeviationTests
{
[Test]
public void returns_undefined_with_no_input_data()
{
//arrange
var inputData = new List<double>();
//act
var gainStdDev = inputData.GainStandardDeviation();
//assert
Assert.AreEqual(double.NaN, gainStdDev);
}
[Test]
public void returns_undefined_with_single_positive_input()
{
//arrange
var inputData = new[] { 1.0 };
//act
var gainStdDev = inputData.GainStandardDeviation();
//assert
Assert.AreEqual(double.NaN, gainStdDev);
}
[Test]
public void returns_undefined_with_single_negative_input()
{
//arrange
var inputData = new[] { -1.0 };
//act
var gainStdDev = inputData.GainStandardDeviation();
//assert
Assert.AreEqual(double.NaN, gainStdDev);
}
[Test]
public void does_not_use_negative_input_data()
{
//arrange
var inputData = new[] { -1.0, 1.0, -2.0, 2.0 };
var expectedGainStdDeviation = inputData.Where(x => x >= 0).StandardDeviation();
//act
var gainStdDev = inputData.GainStandardDeviation();
//assert
Assert.AreEqual(expectedGainStdDeviation, gainStdDev);
}
[Test]
public void returns_undefined_for_a_set_of_all_negative_numbers()
{
//arrange
var inputData = new[] { -1.0, -1.0, -2.0, -3.0 };
//act
var gainStdDev = inputData.GainStandardDeviation();
//assert
Assert.AreEqual(double.NaN, gainStdDev);
}
[Test]
public void handles_zero_in_the_data_input_as_a_positive_number()
{
//arrange
var inputData = new[] { -1.0, 0.0, 1.0, 2.0 };
var expectedGainStdDeviation = inputData.Where(x => x >= 0).StandardDeviation();
//act
var gainStdDev = inputData.GainStandardDeviation();
//assert
Assert.AreEqual(expectedGainStdDeviation, gainStdDev);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))] //assert
public void throws_when_input_data_is_null()
{
//arrange
List<double> inputData = null;
//act
inputData.GainStandardDeviation();
}
public double gainStdDev { get; set; }
}
}

106
src/UnitTests/FinancialTests/LossMeanTests.cs

@ -0,0 +1,106 @@
// <copyright file="LossMeanTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using MathNet.Numerics.Financial;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class LossMeanTests
{
[Test]
public void returns_NaN_when_zero_is_the_only_input()
{
//arrange
var inputData = new[] { 0.0 };
//act
var lossMean = inputData.LossMean();
//assert
Assert.AreEqual(double.NaN, lossMean);
}
[Test]
public void returns_NaN_when_all_input_is_positive()
{
//arrange
var inputData = new[] { 0.0, 1.0 };
//act
var lossMean = inputData.LossMean();
//assert
Assert.AreEqual(double.NaN, lossMean);
}
[Test]
public void returns_the_same_as_mean_when_all_values_are_negative()
{
//arrange
var inputData = new[] { -1.0, -2.0 };
var mean = inputData.Mean();
//act
var lossMean = inputData.LossMean();
//assert
Assert.AreEqual(mean, lossMean);
}
[Test]
public void does_not_use_positive_input_values()
{
//arrange
var inputData = new[] { -1.0, 2.0 };
//act
var lossMean = inputData.LossMean();
//assert
Assert.AreEqual(-1.0, lossMean);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))] //assert
public void throws_when_input_data_is_null()
{
//arrange
List<double> inputData = null;
//act
inputData.LossMean();
}
[Test]
public void returns_NaN_with_no_input_data()
{
//arrange
var inputData = new List<double>();
//act
var lossMean = inputData.LossMean();
//assert
Assert.AreEqual(double.NaN, lossMean);
}
}
}

118
src/UnitTests/FinancialTests/LossStandardDeviationTests.cs

@ -0,0 +1,118 @@
// <copyright file="LossStandardDeviationTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using System.Linq;
using MathNet.Numerics.Financial;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class LossStandardDeviationTests
{
[Test]
public void returns_undefined_with_no_input_data()
{
//arrange
var inputData = new List<double>();
//act
var lossStdDev = inputData.LossStandardDeviation();
//assert
Assert.AreEqual(double.NaN, lossStdDev);
}
[Test]
public void returns_undefined_with_single_positive_input()
{
//arrange
var inputData = new[] { 1.0 };
//act
var lossStdDev = inputData.LossStandardDeviation();
//assert
Assert.AreEqual(double.NaN, lossStdDev);
}
[Test]
public void returns_undefined_with_single_negative_input()
{
//arrange
var inputData = new[] { -1.0 };
//act
var lossStdDev = inputData.LossStandardDeviation();
//assert
Assert.AreEqual(double.NaN, lossStdDev);
}
[Test]
public void does_not_use_positive_input_data()
{
//arrange
var inputData = new[] { -1.0, 1.0, -2.0, 2.0 };
var expectedLossStdDeviation = inputData.Where(x => x < 0).StandardDeviation();
//act
var lossStdDev = inputData.LossStandardDeviation();
//assert
Assert.AreEqual(expectedLossStdDeviation, lossStdDev);
}
[Test]
public void handles_zero_in_the_data_input_as_a_positive_number()
{
//arrange
var inputData = new[] { -1.0, 0.0, -6.0, 2.0 };
var expectedLossStdDeviation = inputData.Where(x => x < 0).StandardDeviation();
//act
var lossStdDev = inputData.LossStandardDeviation();
//assert
Assert.AreEqual(expectedLossStdDeviation, lossStdDev);
}
[Test]
public void returns_undefined_for_a_set_of_all_positive_numbers()
{
//arrange
var inputData = new[] { 1.0, 1.0, 2.0, 3.0 };
//act
var lossStdDev = inputData.LossStandardDeviation();
//assert
Assert.AreEqual(double.NaN, lossStdDev);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))] //assert
public void throws_when_input_data_is_null()
{
//arrange
List<double> inputData = null;
//act
inputData.LossStandardDeviation();
}
}
}

109
src/UnitTests/FinancialTests/SemiDeviationTests.cs

@ -0,0 +1,109 @@
// <copyright file="SemiDeviationTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.FinancialTests
{
using System;
using System.Collections.Generic;
using System.Linq;
using MathNet.Numerics.Financial;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
[TestFixture]
[Category("FinancialTests")]
public class SemiDeviationTests
{
[Test]
public void returns_undefined_with_no_input_data()
{
//arrange
var inputData = new List<double>();
//act
var semiDeviation = inputData.SemiDeviation();
//assert
Assert.AreEqual(double.NaN, semiDeviation);
}
[Test]
public void returns_undefined_with_single_positive_input()
{
//arrange
var inputData = new[] { 1.0 };
//act
var semiDeviation = inputData.SemiDeviation();
//assert
Assert.AreEqual(double.NaN, semiDeviation);
}
[Test]
public void returns_undefined_with_single_negative_input()
{
//arrange
var inputData = new[] { -1.0 };
//act
var semiDeviation = inputData.SemiDeviation();
//assert
Assert.AreEqual(double.NaN, semiDeviation);
}
[Test]
public void only_uses_data_points_below_the_mean_of_all_data()
{
//arrange
var inputData = new[] { 1.0, 2.0, 3.0, 4.0 };
var mean = inputData.Mean();
var expectedSemiDeviation = inputData.Where(x => x < mean).StandardDeviation();
//act
var semiDeviation = inputData.SemiDeviation();
//assert
Assert.AreEqual(expectedSemiDeviation, semiDeviation);
}
[Test]
public void handles_negative_values()
{
//arrange
var inputData = new[] { -1.0, 2.0, 3.0, 4.0 };
var mean = inputData.Mean();
var expectedSemiDeviation = inputData.Where(x => x < mean).StandardDeviation();
//act
var semiDeviation = inputData.SemiDeviation();
//assert
Assert.AreEqual(expectedSemiDeviation, semiDeviation);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))] //assert
public void throws_when_input_data_is_null()
{
//arrange
List<double> inputData = null;
//act
inputData.SemiDeviation();
}
}
}

8
src/UnitTests/UnitTests.csproj

@ -122,6 +122,14 @@
<Compile Include="DistributionTests\Multivariate\MultinomialTests.cs" />
<Compile Include="DistributionTests\Multivariate\NormalGammaTests.cs" />
<Compile Include="DistributionTests\Multivariate\WishartTests.cs" />
<Compile Include="FinancialTests\CompoundMonthlyReturnTests.cs" />
<Compile Include="FinancialTests\DownsideDeviationTests.cs" />
<Compile Include="FinancialTests\GainLossRatioTests.cs" />
<Compile Include="FinancialTests\GainStandardDeviationTests.cs" />
<Compile Include="FinancialTests\LossMeanTests.cs" />
<Compile Include="FinancialTests\GainMeanTests.cs" />
<Compile Include="FinancialTests\LossStandardDeviationTests.cs" />
<Compile Include="FinancialTests\SemiDeviationTests.cs" />
<Compile Include="IntegralTransformsTests\FourierTest.cs" />
<Compile Include="IntegralTransformsTests\HartleyTest.cs" />
<Compile Include="IntegralTransformsTests\InverseTransformTest.cs" />

Loading…
Cancel
Save