mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-03 03:47:42 +00:00
tests
This commit is contained in:
@@ -215,7 +215,7 @@ jobs:
|
|||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|
||||||
build_publish:
|
build_publish:
|
||||||
needs: [SonarCloud, Code_Coverage, CodeQL, Codacy_Scan]
|
needs: [SonarCloud, Code_Coverage, CodeQL, Codacy_Scan, SecurityCodeScan]
|
||||||
if: success()
|
if: success()
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
|
<NoWarn>$(NoWarn);NU1903;NU5104</NoWarn>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
@@ -49,6 +49,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(IsLocalBuild)' == 'true'">
|
<PropertyGroup Condition="'$(IsLocalBuild)' == 'true'">
|
||||||
|
|
||||||
|
<!-- Set the correct path to Quantower here -->
|
||||||
<QuantowerRoot>D:\Quantower</QuantowerRoot>
|
<QuantowerRoot>D:\Quantower</QuantowerRoot>
|
||||||
<QuantowerPath>$([System.IO.Directory]::GetDirectories("$(QuantowerRoot)\TradingPlatform", "v1*")[0])</QuantowerPath>
|
<QuantowerPath>$([System.IO.Directory]::GetDirectories("$(QuantowerRoot)\TradingPlatform", "v1*")[0])</QuantowerPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
+13
-7
@@ -3,16 +3,16 @@ using Trady.Analysis.Indicator;
|
|||||||
using Trady.Core;
|
using Trady.Core;
|
||||||
using Trady.Core.Infrastructure;
|
using Trady.Core.Infrastructure;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
||||||
|
|
||||||
public class TradyTests
|
public class TradyTests
|
||||||
{
|
{
|
||||||
private readonly TBarSeries bars;
|
private readonly TBarSeries bars;
|
||||||
private readonly GbmFeed feed;
|
private readonly GbmFeed feed;
|
||||||
private readonly Random rnd;
|
private readonly RandomNumberGenerator rng;
|
||||||
private readonly double range;
|
private readonly double range;
|
||||||
private readonly int iterations;
|
private readonly int iterations;
|
||||||
private readonly int skip;
|
private readonly int skip;
|
||||||
@@ -20,7 +20,7 @@ public class TradyTests
|
|||||||
|
|
||||||
public TradyTests()
|
public TradyTests()
|
||||||
{
|
{
|
||||||
rnd = new((int)DateTime.Now.Ticks);
|
rng = RandomNumberGenerator.Create();
|
||||||
feed = new(sigma: 0.5, mu: 0.0);
|
feed = new(sigma: 0.5, mu: 0.0);
|
||||||
bars = new(feed);
|
bars = new(feed);
|
||||||
range = 1e-9;
|
range = 1e-9;
|
||||||
@@ -37,12 +37,20 @@ public class TradyTests
|
|||||||
)).ToList();
|
)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetRandomNumber(int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
byte[] randomBytes = new byte[4];
|
||||||
|
rng.GetBytes(randomBytes);
|
||||||
|
int randomInt = BitConverter.ToInt32(randomBytes, 0);
|
||||||
|
return Math.Abs(randomInt % (maxValue - minValue)) + minValue;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SMA()
|
public void SMA()
|
||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
Sma ma = new(period);
|
Sma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -72,7 +80,7 @@ public class TradyTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
Ema ma = new(period);
|
Ema ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -96,6 +104,4 @@ public class TradyTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+13
-6
@@ -1,15 +1,15 @@
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
using Tulip;
|
using Tulip;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
||||||
public class TulipTests
|
public class TulipTests
|
||||||
{
|
{
|
||||||
private readonly TBarSeries bars;
|
|
||||||
private readonly GbmFeed feed;
|
private readonly GbmFeed feed;
|
||||||
private readonly Random rnd;
|
private readonly RandomNumberGenerator rng;
|
||||||
private readonly double range;
|
private readonly double range;
|
||||||
private readonly int iterations;
|
private readonly int iterations;
|
||||||
private readonly double[] data;
|
private readonly double[] data;
|
||||||
@@ -18,9 +18,8 @@ public class TulipTests
|
|||||||
|
|
||||||
public TulipTests()
|
public TulipTests()
|
||||||
{
|
{
|
||||||
rnd = new((int)DateTime.Now.Ticks);
|
rng = RandomNumberGenerator.Create();
|
||||||
feed = new(sigma: 0.5, mu: 0.0);
|
feed = new(sigma: 0.5, mu: 0.0);
|
||||||
bars = new(feed);
|
|
||||||
range = 1e-9;
|
range = 1e-9;
|
||||||
feed.Add(10000);
|
feed.Add(10000);
|
||||||
iterations = 3;
|
iterations = 3;
|
||||||
@@ -29,12 +28,20 @@ public class TulipTests
|
|||||||
outdata = new double[data.Count()];
|
outdata = new double[data.Count()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetRandomNumber(int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
byte[] randomBytes = new byte[4];
|
||||||
|
rng.GetBytes(randomBytes);
|
||||||
|
int randomInt = BitConverter.ToInt32(randomBytes, 0);
|
||||||
|
return Math.Abs(randomInt % (maxValue - minValue)) + minValue;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SMA()
|
public void SMA()
|
||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
Sma ma = new(period);
|
Sma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -58,7 +65,7 @@ public class TulipTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(30) + 5;
|
int period = GetRandomNumber(5, 35);
|
||||||
Ema ma = new(period, useSma: false);
|
Ema ma = new(period, useSma: false);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
|
|||||||
+51
-46
@@ -1,4 +1,5 @@
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
@@ -7,8 +8,8 @@ public class EventingTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void VerifyEventBasedCalculations()
|
public void VerifyEventBasedCalculations()
|
||||||
{
|
{
|
||||||
// Create a random number generator with a fixed seed for reproducibility
|
// Create a cryptographically secure random number generator
|
||||||
var random = new Random(42);
|
using var rng = RandomNumberGenerator.Create();
|
||||||
|
|
||||||
// Create an input series to hold our random values
|
// Create an input series to hold our random values
|
||||||
var input = new TSeries();
|
var input = new TSeries();
|
||||||
@@ -16,59 +17,63 @@ public class EventingTests
|
|||||||
|
|
||||||
// Create a list of indicator pairs (direct calculation and event-based)
|
// Create a list of indicator pairs (direct calculation and event-based)
|
||||||
var indicators = new List<(AbstractBase Direct, AbstractBase EventBased)>
|
var indicators = new List<(AbstractBase Direct, AbstractBase EventBased)>
|
||||||
{
|
{
|
||||||
(new Afirma(p,p,Afirma.WindowType.BlackmanHarris), new Afirma(input, p,p,Afirma.WindowType.BlackmanHarris)),
|
(new Afirma(p,p,Afirma.WindowType.BlackmanHarris), new Afirma(input, p,p,Afirma.WindowType.BlackmanHarris)),
|
||||||
(new Alma(p), new Alma(input, p)),
|
(new Alma(p), new Alma(input, p)),
|
||||||
(new Convolution([1,2,3,2,1]), new Convolution(input, [1,2,3,2,1])),
|
(new Convolution([1,2,3,2,1]), new Convolution(input, [1,2,3,2,1])),
|
||||||
(new Dema(p), new Dema(input, p)),
|
(new Dema(p), new Dema(input, p)),
|
||||||
(new Dsma(p), new Dsma(input, p)),
|
(new Dsma(p), new Dsma(input, p)),
|
||||||
(new Dwma(p), new Dwma(input, p)),
|
(new Dwma(p), new Dwma(input, p)),
|
||||||
(new Ema(p), new Ema(input, p)),
|
(new Ema(p), new Ema(input, p)),
|
||||||
(new Epma(p), new Epma(input, p)),
|
(new Epma(p), new Epma(input, p)),
|
||||||
(new Frama(p), new Frama(input, p)),
|
(new Frama(p), new Frama(input, p)),
|
||||||
(new Fwma(p), new Fwma(input, p)),
|
(new Fwma(p), new Fwma(input, p)),
|
||||||
(new Gma(p), new Gma(input, p)),
|
(new Gma(p), new Gma(input, p)),
|
||||||
(new Hma(p), new Hma(input, p)),
|
(new Hma(p), new Hma(input, p)),
|
||||||
(new Htit(), new Htit(input)),
|
(new Htit(), new Htit(input)),
|
||||||
(new Hwma(p), new Hwma(input, p)),
|
(new Hwma(p), new Hwma(input, p)),
|
||||||
(new Jma(p), new Jma(input, p)),
|
(new Jma(p), new Jma(input, p)),
|
||||||
(new Kama(p), new Kama(input, p)),
|
(new Kama(p), new Kama(input, p)),
|
||||||
(new Ltma(gamma: 0.2), new Ltma(input, gamma: 0.2)),
|
(new Ltma(gamma: 0.2), new Ltma(input, gamma: 0.2)),
|
||||||
(new Maaf(p), new Maaf(input, p)),
|
(new Maaf(p), new Maaf(input, p)),
|
||||||
(new Mama(p), new Mama(input, p)),
|
(new Mama(p), new Mama(input, p)),
|
||||||
(new Mgdi(p), new Mgdi(input, p)),
|
(new Mgdi(p), new Mgdi(input, p)),
|
||||||
(new Mma(p), new Mma(input, p)),
|
(new Mma(p), new Mma(input, p)),
|
||||||
(new Qema(k1: 0.2, k2: 0.2, k3: 0.2, k4: 0.2), new Qema(input, k1: 0.2, k2: 0.2, k3: 0.2, k4: 0.2)),
|
(new Qema(k1: 0.2, k2: 0.2, k3: 0.2, k4: 0.2), new Qema(input, k1: 0.2, k2: 0.2, k3: 0.2, k4: 0.2)),
|
||||||
(new Rema(p), new Rema(input, p)),
|
(new Rema(p), new Rema(input, p)),
|
||||||
(new Rma(p), new Rma(input, p)),
|
(new Rma(p), new Rma(input, p)),
|
||||||
|
(new Sma(p), new Sma(input, p)),
|
||||||
(new Sma(p), new Sma(input, p)),
|
(new Wma(p), new Wma(input, p)),
|
||||||
(new Wma(p), new Wma(input, p)),
|
(new Rma(p), new Rma(input, p)),
|
||||||
(new Rma(p), new Rma(input, p)),
|
(new Tema(p), new Tema(input, p)),
|
||||||
|
(new Kama(2, 30, 6), new Kama(input, 2, 30, 6)),
|
||||||
(new Tema(p), new Tema(input, p)),
|
(new Zlema(p), new Zlema(input, p))
|
||||||
(new Kama(2, 30, 6), new Kama(input, 2, 30, 6)),
|
};
|
||||||
|
|
||||||
(new Zlema(p), new Zlema(input, p))
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate 200 random values and feed them to both direct and event-based indicators
|
// Generate 200 random values and feed them to both direct and event-based indicators
|
||||||
for (int i = 0; i< 200; i++)
|
for (int i = 0; i < 200; i++)
|
||||||
{
|
{
|
||||||
double randomValue = random.NextDouble() * 100;
|
double randomValue = GetRandomDouble(rng) * 100;
|
||||||
input.Add(randomValue);
|
input.Add(randomValue);
|
||||||
|
|
||||||
// Calculate direct indicators
|
// Calculate direct indicators
|
||||||
foreach (var (direct, _) in indicators)
|
foreach (var (direct, _) in indicators)
|
||||||
{
|
{
|
||||||
direct.Calc(randomValue);
|
direct.Calc(randomValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare the results of direct and event-based calculations
|
// Compare the results of direct and event-based calculations
|
||||||
foreach (var (direct, eventBased) in indicators)
|
foreach (var (direct, eventBased) in indicators)
|
||||||
{
|
{
|
||||||
Assert.Equal(direct.Value, eventBased.Value, 9);
|
Assert.Equal(direct.Value, eventBased.Value, 9);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double GetRandomDouble(RandomNumberGenerator rng)
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[8];
|
||||||
|
rng.GetBytes(bytes);
|
||||||
|
return (double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-8
@@ -1,16 +1,16 @@
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains unit tests for bar-based indicators in QuanTAlib.
|
/// Contains unit tests for bar-based indicators in QuanTAlib.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
|
||||||
public class BarIndicatorTests
|
public class BarIndicatorTests
|
||||||
{
|
{
|
||||||
private readonly Random rnd;
|
private readonly RandomNumberGenerator rng;
|
||||||
private const int SeriesLen = 1000;
|
private const int SeriesLen = 1000;
|
||||||
private const int Corrections = 100;
|
private const int Corrections = 100;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ public class BarIndicatorTests
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public BarIndicatorTests()
|
public BarIndicatorTests()
|
||||||
{
|
{
|
||||||
rnd = new Random((int)DateTime.Now.Ticks);
|
rng = RandomNumberGenerator.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly ITValue[] indicators = new ITValue[]
|
private static readonly ITValue[] indicators = new ITValue[]
|
||||||
@@ -124,15 +124,40 @@ public class BarIndicatorTests
|
|||||||
/// <returns>A randomly generated TBar.</returns>
|
/// <returns>A randomly generated TBar.</returns>
|
||||||
private TBar GenerateRandomBar(bool isNew)
|
private TBar GenerateRandomBar(bool isNew)
|
||||||
{
|
{
|
||||||
double open = rnd.NextDouble() * 200 - 100;
|
double open = GetRandomDouble() * 200 - 100;
|
||||||
double close = rnd.NextDouble() * 200 - 100;
|
double close = GetRandomDouble() * 200 - 100;
|
||||||
double high = Math.Max(open, close) + rnd.NextDouble() * 10;
|
double high = Math.Max(open, close) + GetRandomDouble() * 10;
|
||||||
double low = Math.Min(open, close) - rnd.NextDouble() * 10;
|
double low = Math.Min(open, close) - GetRandomDouble() * 10;
|
||||||
long volume = rnd.Next(0, 10000);
|
long volume = GetRandomNumber(0, 10000);
|
||||||
|
|
||||||
return new TBar(Time: DateTime.Now, Open: open, High: high, Low: low, Close: close, Volume: volume, IsNew: isNew);
|
return new TBar(Time: DateTime.Now, Open: open, High: high, Low: low, Close: close, Volume: volume, IsNew: isNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a random double between 0 and 1.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A random double between 0 and 1.</returns>
|
||||||
|
private double GetRandomDouble()
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[8];
|
||||||
|
rng.GetBytes(bytes);
|
||||||
|
return (double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a random integer between minValue (inclusive) and maxValue (exclusive).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minValue">The minimum value (inclusive).</param>
|
||||||
|
/// <param name="maxValue">The maximum value (exclusive).</param>
|
||||||
|
/// <returns>A random integer between minValue and maxValue.</returns>
|
||||||
|
private int GetRandomNumber(int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
byte[] randomBytes = new byte[4];
|
||||||
|
rng.GetBytes(randomBytes);
|
||||||
|
int randomInt = BitConverter.ToInt32(randomBytes, 0);
|
||||||
|
return Math.Abs(randomInt % (maxValue - minValue)) + minValue;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the list of indicators for parameterized tests.
|
/// Provides the list of indicators for parameterized tests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
+13
-5
@@ -1,19 +1,27 @@
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
|
||||||
public class IndicatorTests
|
public class IndicatorTests
|
||||||
{
|
{
|
||||||
private readonly Random rnd;
|
private readonly RandomNumberGenerator rng;
|
||||||
private const int SeriesLen = 1000;
|
private const int SeriesLen = 1000;
|
||||||
private const int Corrections = 100;
|
private const int Corrections = 100;
|
||||||
|
|
||||||
public IndicatorTests()
|
public IndicatorTests()
|
||||||
{
|
{
|
||||||
rnd = new Random((int)DateTime.Now.Ticks);
|
rng = RandomNumberGenerator.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetRandomNumber(int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
byte[] randomBytes = new byte[4];
|
||||||
|
rng.GetBytes(randomBytes);
|
||||||
|
int randomInt = BitConverter.ToInt32(randomBytes, 0);
|
||||||
|
return Math.Abs(randomInt % (maxValue - minValue)) + minValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skipcq: CS-R1055
|
// skipcq: CS-R1055
|
||||||
@@ -83,12 +91,12 @@ public class IndicatorTests
|
|||||||
|
|
||||||
for (int i = 0; i < SeriesLen; i++)
|
for (int i = 0; i < SeriesLen; i++)
|
||||||
{
|
{
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
TValue item1 = new(Time: DateTime.Now, Value: GetRandomNumber(-100, 100), IsNew: true);
|
||||||
InvokeCalc(indicator1, calcMethod, item1);
|
InvokeCalc(indicator1, calcMethod, item1);
|
||||||
|
|
||||||
for (int j = 0; j < Corrections; j++)
|
for (int j = 0; j < Corrections; j++)
|
||||||
{
|
{
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
item1 = new(Time: DateTime.Now, Value: GetRandomNumber(-100, 100), IsNew: false);
|
||||||
InvokeCalc(indicator1, calcMethod, item1);
|
InvokeCalc(indicator1, calcMethod, item1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-20
@@ -1,16 +1,15 @@
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
using Skender.Stock.Indicators;
|
using Skender.Stock.Indicators;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
|
||||||
|
|
||||||
public class SkenderTests
|
public class SkenderTests
|
||||||
{
|
{
|
||||||
private readonly TBarSeries bars;
|
private readonly TBarSeries bars;
|
||||||
private readonly GbmFeed feed;
|
private readonly GbmFeed feed;
|
||||||
private readonly Random rnd;
|
private readonly RandomNumberGenerator rng;
|
||||||
private readonly double range;
|
private readonly double range;
|
||||||
private int period;
|
private int period;
|
||||||
private readonly int iterations = 3; // Initialized directly at declaration
|
private readonly int iterations = 3; // Initialized directly at declaration
|
||||||
@@ -18,7 +17,7 @@ public class SkenderTests
|
|||||||
|
|
||||||
public SkenderTests()
|
public SkenderTests()
|
||||||
{
|
{
|
||||||
rnd = new((int)DateTime.Now.Ticks);
|
rng = RandomNumberGenerator.Create();
|
||||||
feed = new(sigma: 0.5, mu: 0.0);
|
feed = new(sigma: 0.5, mu: 0.0);
|
||||||
bars = new(feed);
|
bars = new(feed);
|
||||||
range = 1e-9;
|
range = 1e-9;
|
||||||
@@ -34,12 +33,20 @@ public class SkenderTests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetRandomNumber(int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
byte[] randomBytes = new byte[4];
|
||||||
|
rng.GetBytes(randomBytes);
|
||||||
|
int randomInt = BitConverter.ToInt32(randomBytes, 0);
|
||||||
|
return Math.Abs(randomInt % (maxValue - minValue)) + minValue;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SMA()
|
public void SMA()
|
||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Sma ma = new(period);
|
Sma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -58,7 +65,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Ema ma = new(period, useSma: true);
|
Ema ma = new(period, useSma: true);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -77,7 +84,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Ema ma = new(period, useSma: false);
|
Ema ma = new(period, useSma: false);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -96,7 +103,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Dema ma = new(period);
|
Dema ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -115,7 +122,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Tema ma = new(period);
|
Tema ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -134,7 +141,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
double[] kernel = Enumerable.Repeat(1.0, period).ToArray();
|
double[] kernel = Enumerable.Repeat(1.0, period).ToArray();
|
||||||
Convolution ma = new(kernel);
|
Convolution ma = new(kernel);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
@@ -154,7 +161,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Wma ma = new(period);
|
Wma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -173,7 +180,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Hma ma = new(period);
|
Hma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -192,7 +199,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Epma ma = new(period);
|
Epma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -211,7 +218,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Alma ma = new(period, offset: 0.85, sigma: 6);
|
Alma ma = new(period, offset: 0.85, sigma: 6);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -230,7 +237,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
T3 ma = new(period, vfactor: 0.7, useSma: false);
|
T3 ma = new(period, vfactor: 0.7, useSma: false);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -249,7 +256,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Smma ma = new(period);
|
Smma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -268,7 +275,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Kama ma = new(period);
|
Kama ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -307,7 +314,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Mgdi ma = new(period: period);
|
Mgdi ma = new(period: period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -328,7 +335,7 @@ public class SkenderTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
period = GetRandomNumber(5, 55);
|
||||||
Atr ma = new(period: period);
|
Atr ma = new(period: period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in bars) { QL.Add(ma.Calc(item)); }
|
foreach (TBar item in bars) { QL.Add(ma.Calc(item)); }
|
||||||
@@ -342,5 +349,4 @@ public class SkenderTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-36
@@ -1,33 +1,36 @@
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
using TALib;
|
using TALib;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
[SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")]
|
|
||||||
|
|
||||||
public class TAlibTests
|
public class TAlibTests
|
||||||
{
|
{
|
||||||
private readonly TBarSeries bars;
|
|
||||||
private readonly GbmFeed feed;
|
private readonly GbmFeed feed;
|
||||||
private readonly Random rnd;
|
private readonly RandomNumberGenerator rng;
|
||||||
private readonly double range;
|
private readonly double range;
|
||||||
private readonly int iterations;
|
private readonly int iterations;
|
||||||
private readonly double[] data;
|
private readonly double[] data;
|
||||||
private readonly double[] TALIB;
|
private readonly double[] TALIB;
|
||||||
|
|
||||||
|
|
||||||
public TAlibTests()
|
public TAlibTests()
|
||||||
{
|
{
|
||||||
rnd = new((int)DateTime.Now.Ticks);
|
rng = RandomNumberGenerator.Create();
|
||||||
feed = new(sigma: 0.5, mu: 0.0);
|
feed = new(sigma: 0.5, mu: 0.0);
|
||||||
bars = new(feed);
|
|
||||||
range = 1e-9;
|
range = 1e-9;
|
||||||
feed.Add(10000);
|
feed.Add(10000);
|
||||||
iterations = 3;
|
iterations = 3;
|
||||||
data = feed.Close.v.ToArray();
|
data = feed.Close.v.ToArray();
|
||||||
TALIB = new double[data.Count()];
|
TALIB = new double[data.Count()];
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetRandomNumber(int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
byte[] randomBytes = new byte[4];
|
||||||
|
rng.GetBytes(randomBytes);
|
||||||
|
int randomInt = BitConverter.ToInt32(randomBytes, 0);
|
||||||
|
return Math.Abs(randomInt % (maxValue - minValue)) + minValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -35,7 +38,7 @@ public class TAlibTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
Sma ma = new(period);
|
Sma ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -44,7 +47,6 @@ public class TAlibTests
|
|||||||
Assert.Equal(QL.Length, TALIB.Count());
|
Assert.Equal(QL.Length, TALIB.Count());
|
||||||
for (int i = QL.Length - 1; i > period; i--)
|
for (int i = QL.Length - 1; i > period; i--)
|
||||||
{
|
{
|
||||||
double TL = i < outBegIdx ? double.NaN : TALIB[i - outBegIdx];
|
|
||||||
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +57,7 @@ public class TAlibTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
Ema ma = new(period, useSma: true);
|
Ema ma = new(period, useSma: true);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -64,7 +66,6 @@ public class TAlibTests
|
|||||||
Assert.Equal(QL.Length, TALIB.Count());
|
Assert.Equal(QL.Length, TALIB.Count());
|
||||||
for (int i = QL.Length - 1; i > period; i--)
|
for (int i = QL.Length - 1; i > period; i--)
|
||||||
{
|
{
|
||||||
double TL = i < outBegIdx ? double.NaN : TALIB[i - outBegIdx];
|
|
||||||
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,7 @@ public class TAlibTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
Dema ma = new(period);
|
Dema ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -84,7 +85,6 @@ public class TAlibTests
|
|||||||
Assert.Equal(QL.Length, TALIB.Length);
|
Assert.Equal(QL.Length, TALIB.Length);
|
||||||
for (int i = QL.Length - 1; i > period * 20; i--)
|
for (int i = QL.Length - 1; i > period * 20; i--)
|
||||||
{
|
{
|
||||||
double TL = i < outBegIdx ? double.NaN : TALIB[i - outBegIdx];
|
|
||||||
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ public class TAlibTests
|
|||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
Tema ma = new(period);
|
Tema ma = new(period);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -104,41 +104,37 @@ public class TAlibTests
|
|||||||
Assert.Equal(QL.Length, TALIB.Length);
|
Assert.Equal(QL.Length, TALIB.Length);
|
||||||
for (int i = QL.Length - 1; i > period * 20; i--)
|
for (int i = QL.Length - 1; i > period * 20; i--)
|
||||||
{
|
{
|
||||||
double TL = i < outBegIdx ? double.NaN : TALIB[i - outBegIdx];
|
|
||||||
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO fix WMA
|
[Fact]
|
||||||
/*
|
public void WMA()
|
||||||
[Fact]
|
{
|
||||||
public void WMA()
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
int period = GetRandomNumber(5, 55);
|
||||||
|
Wma ma = new(period);
|
||||||
|
TSeries QL = new();
|
||||||
|
foreach (TBar item in feed)
|
||||||
|
{ QL.Add(ma.Calc(new TValue(item.Time, item.Close))); }
|
||||||
|
Core.Wma(data, 0, QL.Length - 1, TALIB, out int outBegIdx, out _, period);
|
||||||
|
Assert.Equal(QL.Length, TALIB.Count());
|
||||||
|
for (int i = QL.Length - 1; i > period * 10; i--)
|
||||||
{
|
{
|
||||||
period = rnd.Next(50) + 5;
|
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
||||||
Wma ma = new(period);
|
|
||||||
TSeries QL = new();
|
|
||||||
foreach (TBar item in feed)
|
|
||||||
{ QL.Add(ma.Calc(new TValue(item.Time, item.Close))); }
|
|
||||||
Core.Wma(data, 0, QL.Length - 1, TALIB, out int outBegIdx, out _, period);
|
|
||||||
Assert.Equal(QL.Length, TALIB.Count());
|
|
||||||
for (int i = QL.Length - 1; i > period*3; i--)
|
|
||||||
{
|
|
||||||
double TL = i < outBegIdx ? double.NaN : TALIB[i - outBegIdx];
|
|
||||||
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void T3()
|
public void T3()
|
||||||
{
|
{
|
||||||
for (int run = 0; run < iterations; run++)
|
for (int run = 0; run < iterations; run++)
|
||||||
{
|
{
|
||||||
int period = rnd.Next(50) + 5;
|
int period = GetRandomNumber(5, 55);
|
||||||
T3 ma = new(period, vfactor: 0.7, useSma: false);
|
T3 ma = new(period, vfactor: 0.7, useSma: false);
|
||||||
TSeries QL = new();
|
TSeries QL = new();
|
||||||
foreach (TBar item in feed)
|
foreach (TBar item in feed)
|
||||||
@@ -147,10 +143,8 @@ public class TAlibTests
|
|||||||
Assert.Equal(QL.Length, TALIB.Length);
|
Assert.Equal(QL.Length, TALIB.Length);
|
||||||
for (int i = QL.Length - 1; i > period * 20; i--)
|
for (int i = QL.Length - 1; i > period * 20; i--)
|
||||||
{
|
{
|
||||||
double TL = i < outBegIdx ? double.NaN : TALIB[i - outBegIdx];
|
|
||||||
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
Assert.InRange(TALIB[i - outBegIdx] - QL[i].Value, -range, range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+15
-8
@@ -1,11 +1,11 @@
|
|||||||
using System.CommandLine.Rendering.Views;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
public class GbmFeed : TBarSeries
|
public class GbmFeed : TBarSeries
|
||||||
{
|
{
|
||||||
private readonly double _mu, _sigma;
|
private readonly double _mu, _sigma;
|
||||||
private readonly Random _random;
|
private readonly RandomNumberGenerator _rng;
|
||||||
private double _lastClose, _lastHigh, _lastLow;
|
private double _lastClose, _lastHigh, _lastLow;
|
||||||
|
|
||||||
public GbmFeed(double initialPrice = 100.0, double mu = 0.05, double sigma = 0.2)
|
public GbmFeed(double initialPrice = 100.0, double mu = 0.05, double sigma = 0.2)
|
||||||
@@ -13,7 +13,7 @@ public class GbmFeed : TBarSeries
|
|||||||
_lastClose = _lastHigh = _lastLow = initialPrice;
|
_lastClose = _lastHigh = _lastLow = initialPrice;
|
||||||
_mu = mu;
|
_mu = mu;
|
||||||
_sigma = sigma;
|
_sigma = sigma;
|
||||||
_random = new Random((int)DateTime.Now.Ticks);
|
_rng = RandomNumberGenerator.Create();
|
||||||
this.Name = $"GBM({_sigma:F2})";
|
this.Name = $"GBM({_sigma:F2})";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,9 +39,9 @@ public class GbmFeed : TBarSeries
|
|||||||
double newClose = _lastClose * Math.Exp(drift + diffusion);
|
double newClose = _lastClose * Math.Exp(drift + diffusion);
|
||||||
|
|
||||||
double open = _lastClose;
|
double open = _lastClose;
|
||||||
double high = Math.Max(_lastHigh, Math.Max(open, newClose) * (1 + _random.NextDouble() * 0.01));
|
double high = Math.Max(_lastHigh, Math.Max(open, newClose) * (1 + GenerateRandomDouble() * 0.01));
|
||||||
double low = Math.Min(_lastLow, Math.Min(open, newClose) * (1 - _random.NextDouble() * 0.01));
|
double low = Math.Min(_lastLow, Math.Min(open, newClose) * (1 - GenerateRandomDouble() * 0.01));
|
||||||
double volume = 1000 + _random.NextDouble() * 1000;
|
double volume = 1000 + GenerateRandomDouble() * 1000;
|
||||||
|
|
||||||
if (isNew)
|
if (isNew)
|
||||||
{
|
{
|
||||||
@@ -62,8 +62,15 @@ public class GbmFeed : TBarSeries
|
|||||||
private double GenerateNormalRandom()
|
private double GenerateNormalRandom()
|
||||||
{
|
{
|
||||||
// Box-Muller transform to generate standard normal random variable
|
// Box-Muller transform to generate standard normal random variable
|
||||||
double u1 = 1.0 - _random.NextDouble(); // Uniform(0,1] random doubles
|
double u1 = 1.0 - GenerateRandomDouble(); // Uniform(0,1] random doubles
|
||||||
double u2 = 1.0 - _random.NextDouble();
|
double u2 = 1.0 - GenerateRandomDouble();
|
||||||
return Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
|
return Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double GenerateRandomDouble()
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[8];
|
||||||
|
_rng.GetBytes(bytes);
|
||||||
|
return (double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+6
-18
@@ -18,36 +18,24 @@
|
|||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<ProduceReferenceAssembly>True</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>True</ProduceReferenceAssembly>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<PackageTags>
|
<PackageIcon>QuanTAlib2.png</PackageIcon>
|
||||||
|
<PackageReadmeFile>readme.md</PackageReadmeFile>
|
||||||
|
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||||
|
<PackageTags>
|
||||||
Indicators;Stock;Market;Technical;Analysis;Algorithmic;Trading;Trade;Trend;Momentum;Finance;Algorithm;Algo;
|
Indicators;Stock;Market;Technical;Analysis;Algorithmic;Trading;Trade;Trend;Momentum;Finance;Algorithm;Algo;
|
||||||
AlgoTrading;Financial;Strategy;Chart;Charting;Oscillator;Overlay;Equity;Bitcoin;Crypto;Cryptocurrency;Forex;
|
AlgoTrading;Financial;Strategy;Chart;Charting;Oscillator;Overlay;Equity;Bitcoin;Crypto;Cryptocurrency;Forex;
|
||||||
Quantitative;Historical;Quotes;
|
Quantitative;Historical;Quotes;
|
||||||
</PackageTags>
|
</PackageTags>
|
||||||
<NoWarn>$(NoWarn);NU5104</NoWarn>
|
|
||||||
<PackageIcon>QuanTAlib2.png</PackageIcon>
|
|
||||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
|
||||||
<ProduceReferenceAssembly>True</ProduceReferenceAssembly>
|
|
||||||
<PackageIconUrl>https://raw.githubusercontent.com/mihakralj/QuanTAlib/main/.github/QuanTAlib2.png</PackageIconUrl>
|
|
||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
|
||||||
<PackageTags>
|
|
||||||
Indicators;Stock;Market;Technical;Analysis;Algorithmic;Trading;Trade;Trend;Momentum;Finance;Algorithm;Algo;
|
|
||||||
AlgoTrading;Financial;Strategy;Chart;Charting;Oscillator;Overlay;Equity;Bitcoin;Crypto;Cryptocurrency;Forex;
|
|
||||||
Quantitative;Historical;Quotes;
|
|
||||||
</PackageTags>
|
|
||||||
<PackageIcon>QuanTAlib2.png</PackageIcon>
|
<PackageIcon>QuanTAlib2.png</PackageIcon>
|
||||||
<PackageIconUrl>https://raw.githubusercontent.com/mihakralj/QuanTAlib/main/.github/QuanTAlib2.png</PackageIconUrl>
|
<PackageIconUrl>https://raw.githubusercontent.com/mihakralj/QuanTAlib/main/.github/QuanTAlib2.png</PackageIconUrl>
|
||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
|
||||||
<PackageIcon>QuanTAlib2.png</PackageIcon>
|
|
||||||
<PackageIconUrl>https://raw.githubusercontent.com/mihakralj/QuanTAlib/main/.github/QuanTAlib2.png</PackageIconUrl>
|
|
||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\docs\readme.md" Pack="true" PackagePath=""/>
|
<None Include="..\docs\readme.md" Pack="true" PackagePath=""/>
|
||||||
<None Include="..\.github\QuanTAlib2.png" Pack="true" Visible="false" PackagePath=""/>
|
<None Include="..\.github\QuanTAlib2.png" Pack="true" Visible="false" PackagePath=""/>
|
||||||
<PackageReference Include="System.Text.Json" Version="9.0.0-rc.1.24431.7" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="TradingPlatform.BusinessLayer">
|
<Reference Include="TradingPlatform.BusinessLayer">
|
||||||
<HintPath>..\.github\TradingPlatform.BusinessLayer.dll</HintPath>
|
<HintPath>..\.github\TradingPlatform.BusinessLayer.dll</HintPath>
|
||||||
|
|||||||
Reference in New Issue
Block a user