Browse Source

Financial: online indicator implementations

atr-indicator
Christoph Ruegg 11 years ago
parent
commit
e3b57532d1
  1. 92
      src/Numerics/Financial/Indicators.cs
  2. 3
      src/UnitTests/FinancialTests/IndicatorsTests.cs
  3. 5
      src/UnitTests/FinancialTests/StockDataReader.cs

92
src/Numerics/Financial/Indicators.cs

@ -40,71 +40,59 @@ namespace MathNet.Numerics.Financial
/// </summary>
public static class Indicators
{
private static IEnumerable<double> TrueRange(this IEnumerable<Bar> samples)
{
using (var enumerator = samples.GetEnumerator())
{
if (!enumerator.MoveNext())
{
yield break;
}
Bar last = enumerator.Current;
//yield return double.NaN;
yield return Math.Abs(last.High - last.Low);
while (enumerator.MoveNext())
{
var current = enumerator.Current;
var hl = Math.Abs(current.High - current.Low);
var pdch = Math.Abs(last.Close - current.High);
var pdcl = Math.Abs(last.Close - current.Low);
last = current;
yield return Math.Max(hl, Math.Max(pdch, pdcl));
}
}
}
/// <summary>
/// Calculate the Simple Moving Average (SMA).
/// Calculate the Simple Moving Average (SMA) based on Close. Online/Streaming.
/// </summary>
/// <param name="samples">Input samples</param>
/// <param name="period">Period of calculation</param>
public static IEnumerable<double> SMA(this IEnumerable<double> samples, int period)
public static IEnumerable<double> SMA(this IEnumerable<Bar> samples, int period)
{
return samples.MovingAverage(period);
return samples.Select(bar => bar.Close).MovingAverage(period).Select(x => Math.Round(x, 2));
}
/// <summary>
/// Calculate the Average True Range (ATR).
/// Calculate the True Range (TR). Online/Streaming.
/// </summary>
/// <param name="samples">Input samples</param>
public static IEnumerable<double> TR(this IEnumerable<Bar> samples)
{
return samples.TrueRange().Select(x => Math.Round(x, 2));
}
/// <summary>
/// Calculate the Average True Range (ATR). Online/Streaming.
/// </summary>
/// <param name="samples">Input samples</param>
/// <param name="period">Period of calculation</param>
public static IEnumerable<double> ATR(this IEnumerable<Bar> samples, int period)
{
if (period <= 0)
throw new ArgumentException("period should be greater than 0", "period");
if (samples == null)
throw new ArgumentNullException("samples", "samples should not be null");
if (period > (samples.Count()))
throw new ArgumentException("samples", "samples should be greater than period");
var trList = new List<double>();
var enumerator = samples.GetEnumerator();
enumerator.MoveNext();
var lastBar = enumerator.Current;
trList.Add(double.NaN);
while (enumerator.MoveNext())
{
var currentBar = enumerator.Current;
var hl = Math.Round(currentBar.High - currentBar.Low, 10);
hl = Math.Abs(hl);
var pdch = Math.Round(lastBar.Close - currentBar.High, 10);
pdch = Math.Abs(pdch);
var pdcl = Math.Round(lastBar.Close - currentBar.Low, 10);
pdcl = Math.Abs(pdcl);
double tr = Math.Max(hl, Math.Max(pdch, pdcl));
trList.Add(tr);
lastBar = currentBar;
}
var atrList = new List<double>();
for (int i = 0; i < period; i++)
atrList.Add(Double.NaN);
//remove first tr, this is not valid
trList.RemoveAt(0);
while (trList.Count >= period)
{
var mean = trList.Take(period).Mean();
var meanRounded = Math.Round(mean, 2);
atrList.Add(meanRounded);
trList.RemoveAt(0);
}
return atrList;
return samples.TrueRange().MovingAverage(period).Select(x => Math.Round(x, 2));
}
}
}

3
src/UnitTests/FinancialTests/IndicatorsTests.cs

@ -55,7 +55,6 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
var expectedValueAtBar20 = 132.33;
var actual = atr.ElementAt(20);
Assert.AreEqual(expectedValueAtBar20, actual);
}
[Test]
@ -67,7 +66,7 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
Assert.That(() => inputBars.ATR(period), Throws.Exception.TypeOf<ArgumentException>());
}
[Test]
[Test, Ignore("Unclear why this should be enforced")]
public void Atr_ShouldRaiseException_IfPeriodIsGreaterThanBarCount()
{
var inputBars = GenerateValidBars();

5
src/UnitTests/FinancialTests/StockDataReader.cs

@ -8,7 +8,7 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
/// <summary>
/// Class reads a file with stock data
/// </summary>
internal class StockDataReader
public class StockDataReader
{
/// <summary>
/// Reads a file with stock quotes
@ -55,10 +55,11 @@ namespace MathNet.Numerics.UnitTests.FinancialTests
return resultList;
}
}
/// <summary>
/// Entity class for holding stock data
/// </summary>
internal class StockData
public class StockData
{
/// <param name="dateTime">Date</param>
/// <param name="open">Open quote</param>

Loading…
Cancel
Save