Skip to content

Commit

Permalink
Added PriceToUse defaluts to most indicators
Browse files Browse the repository at this point in the history
  • Loading branch information
squideyes committed Jun 2, 2023
1 parent bf3afde commit 13ace04
Show file tree
Hide file tree
Showing 36 changed files with 2,508 additions and 2,541 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/squideyes/techanalysis/Deploy%20to%20NuGet?label=build)
![NuGet Version](https://img.shields.io/nuget/v/SquidEyes.TechAnalysis)
![Downloads](https://img.shields.io/nuget/dt/squideyes.techanalysis)
![License](https://img.shields.io/github/license/squideyes/TechAnalysis)

**SquidEyes.TechAnalysis** is a collection of high-performance C#/.NET 5.0 technical indicators with a hand-curated set of matching unit-tests.
**SquidEyes.TechAnalysis** is a collection of high-performance C#/.NET 7.0 technical indicators with a hand-curated set of matching unit-tests.

|Code|Name|Indicator|Kind|
|---|---|---|---|
Expand Down
16 changes: 16 additions & 0 deletions TechAnalysis/Common/Enums/MaKind.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// ********************************************************
// The use of this source code is licensed under the terms
// of the MIT License (https://opensource.org/licenses/MIT)
// ********************************************************

namespace SquidEyes.TechAnalysis;

public enum MaKind
{
Dema = 1,
Ema,
Sma,
Smma,
Tema,
Wma
}
15 changes: 7 additions & 8 deletions TechAnalysis/Common/Enums/PriceToUse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
// of the MIT License (https://opensource.org/licenses/MIT)
// ********************************************************

namespace SquidEyes.TechAnalysis
namespace SquidEyes.TechAnalysis;

public enum PriceToUse
{
public enum PriceToUse
{
Open = 1,
High,
Low,
Close
}
Open = 1,
High,
Low,
Close
}
37 changes: 17 additions & 20 deletions TechAnalysis/Common/Helpers/Internal/DataExtenders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,24 @@
// of the MIT License (https://opensource.org/licenses/MIT)
// ********************************************************

using System;
namespace SquidEyes.TechAnalysis;

namespace SquidEyes.TechAnalysis
public static class DataExtenders
{
public static class DataExtenders
{
public static float GetPrice(this ICandle candle, PriceToUse priceToUse) =>
priceToUse switch
{
PriceToUse.Open => candle.Open,
PriceToUse.High => candle.High,
PriceToUse.Low => candle.Low,
PriceToUse.Close => candle.Close,
_ => throw new ArgumentOutOfRangeException(nameof(priceToUse))
};
public static float GetPrice(this ICandle candle, PriceToUse priceToUse) =>
priceToUse switch
{
PriceToUse.Open => candle.Open,
PriceToUse.High => candle.High,
PriceToUse.Low => candle.Low,
PriceToUse.Close => candle.Close,
_ => throw new ArgumentOutOfRangeException(nameof(priceToUse))
};

public static BasicResult ToBasicResult(this ICandle candle, PriceToUse priceToUse) =>
new()
{
OpenOn = candle.OpenOn,
Value = candle.GetPrice(priceToUse)
};
}
public static BasicResult ToBasicResult(this ICandle candle, PriceToUse priceToUse) =>
new()
{
OpenOn = candle.OpenOn,
Value = candle.GetPrice(priceToUse)
};
}
110 changes: 53 additions & 57 deletions TechAnalysis/Common/Helpers/Internal/MiscExtenders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,80 @@
// of the MIT License (https://opensource.org/licenses/MIT)
// ********************************************************

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace SquidEyes.TechAnalysis
namespace SquidEyes.TechAnalysis;

internal static class MiscExtenders
{
internal static class MiscExtenders
private const double DOUBLE_EPSILON = 0.00000001;

public static bool Approximates(this double a, double b) =>
Math.Abs(a - b) < DOUBLE_EPSILON;

public static int ToDecimalDigits(this double value)
{
private const double DOUBLE_EPSILON = 0.00000001;
var digits = 0;

public static bool Approximates(this double a, double b) =>
Math.Abs(a - b) < DOUBLE_EPSILON;
while (Math.Round(value, digits) != value)
digits++;

public static int ToDecimalDigits(this double value)
{
var digits = 0;
return digits;
}

while (Math.Round(value, digits) != value)
digits++;
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
action(item);
}

return digits;
}
public static Stream ToStream(this string value)
{
var stream = new MemoryStream();

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
action(item);
}
var writer = new StreamWriter(stream, Encoding.UTF8, -1, true);

public static Stream ToStream(this string value)
{
var stream = new MemoryStream();
writer.Write(value);

var writer = new StreamWriter(stream, Encoding.UTF8, -1, true);
writer.Flush();

writer.Write(value);
stream.Position = 0;

writer.Flush();
return stream;
}

stream.Position = 0;
public static bool IsEnumValue<T>(this T value) where T : struct, Enum =>
Enum.IsDefined(value);

return stream;
}
public static T Validated<T>(
this T value, string fieldName, Func<T, bool> isValid)
{
if (string.IsNullOrWhiteSpace(fieldName))
throw new ArgumentNullException(nameof(fieldName));

public static bool IsEnumValue<T>(this T value) where T : struct, Enum =>
Enum.IsDefined(value);
if (isValid(value))
return value;
else
throw new ArgumentOutOfRangeException(fieldName);
}

public static T Validated<T>(
this T value, string fieldName, Func<T, bool> isValid)
public static bool InRange<T>(
this T value, T minValue, T maxValue, bool inclusive = true)
where T : IComparable<T>
{
if (inclusive)
{
if (string.IsNullOrWhiteSpace(fieldName))
throw new ArgumentNullException(nameof(fieldName));

if (isValid(value))
return value;
else
throw new ArgumentOutOfRangeException(fieldName);
if (value.CompareTo(minValue) < 0 || value.CompareTo(maxValue) > 0)
return false;
}

public static bool InRange<T>(
this T value, T minValue, T maxValue, bool inclusive = true)
where T : IComparable<T>
else
{
if (inclusive)
{
if (value.CompareTo(minValue) < 0 || value.CompareTo(maxValue) > 0)
return false;
}
else
{
if (value.CompareTo(minValue) <= 0 || value.CompareTo(maxValue) >= 0)
return false;
}

return true;
if (value.CompareTo(minValue) <= 0 || value.CompareTo(maxValue) >= 0)
return false;
}

public static R Funcify<T, R>(this T value, Func<T, R> func) => func(value);
return true;
}

public static R Funcify<T, R>(this T value, Func<T, R> func) => func(value);
}
110 changes: 53 additions & 57 deletions TechAnalysis/Common/Helpers/Public/CsvEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,80 @@
// of the MIT License (https://opensource.org/licenses/MIT)
// ********************************************************

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace SquidEyes.TechAnalysis
namespace SquidEyes.TechAnalysis;

public class CsvEnumerator : IEnumerable<string[]>, IDisposable
{
public class CsvEnumerator : IEnumerable<string[]>, IDisposable
{
private readonly StreamReader reader;
private readonly int expectedFields;
private readonly StreamReader reader;
private readonly int expectedFields;

private bool disposed = false;
private bool disposed = false;

private bool skipFirst;
private bool skipFirst;

public CsvEnumerator(StreamReader reader, int expectedFields, bool skipFirst = false)
{
if (expectedFields <= 0)
throw new ArgumentOutOfRangeException(nameof(expectedFields));
public CsvEnumerator(StreamReader reader, int expectedFields, bool skipFirst = false)
{
if (expectedFields <= 0)
throw new ArgumentOutOfRangeException(nameof(expectedFields));

this.reader = reader ?? throw new ArgumentNullException(nameof(reader));
this.expectedFields = expectedFields;
this.skipFirst = skipFirst;
}
this.reader = reader ?? throw new ArgumentNullException(nameof(reader));
this.expectedFields = expectedFields;
this.skipFirst = skipFirst;
}

public CsvEnumerator(Stream stream, int expectedFields, bool skipFirst = false)
: this(new StreamReader(stream), expectedFields, skipFirst)
{
}
public CsvEnumerator(Stream stream, int expectedFields, bool skipFirst = false)
: this(new StreamReader(stream), expectedFields, skipFirst)
{
}

public CsvEnumerator(string fileName, int expectedFields, bool skipFirst = false)
: this(File.OpenRead(fileName), expectedFields, skipFirst)
{
}
public CsvEnumerator(string fileName, int expectedFields, bool skipFirst = false)
: this(File.OpenRead(fileName), expectedFields, skipFirst)
{
}

~CsvEnumerator() => Dispose(false);
~CsvEnumerator() => Dispose(false);

public void Dispose()
{
Dispose(true);
public void Dispose()
{
Dispose(true);

GC.SuppressFinalize(this);
}
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if (disposing && !disposed && reader != null)
reader.Dispose();
private void Dispose(bool disposing)
{
if (disposing && !disposed && reader != null)
reader.Dispose();

disposed = true;
}
disposed = true;
}

public IEnumerator<string[]> GetEnumerator()
{
string line;
public IEnumerator<string[]> GetEnumerator()
{
string line;

while ((line = reader.ReadLine()) != null)
while ((line = reader.ReadLine()!) != null)
{
if (skipFirst)
{
if (skipFirst)
{
skipFirst = false;

continue;
}
skipFirst = false;

var fields = line.Split(',');
continue;
}

if (fields.Length != expectedFields)
{
throw new InvalidDataException(
$"{expectedFields} expected; {fields.Length} found");
}
var fields = line.Split(',');

yield return fields;
if (fields.Length != expectedFields)
{
throw new InvalidDataException(
$"{expectedFields} expected; {fields.Length} found");
}
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
yield return fields;
}
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

0 comments on commit 13ace04

Please sign in to comment.