mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-25 13:58:04 +00:00
Atr
This commit is contained in:
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"SonarCloudOrganization": "mihakralj",
|
|
||||||
"ProjectKey": "mihakralj_QuanTAlib"
|
|
||||||
}
|
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"sonarlint.connectedMode.connections.sonarcloud": [
|
||||||
|
{
|
||||||
|
"organizationKey": "mihakralj",
|
||||||
|
"token": "6df7cd62a17dc4e1c5532df1da2f49d5a977dd50",
|
||||||
|
"connectionId": "mihakralj"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sonarlint.connectedMode.project": {
|
||||||
|
"connectionId": "mihakralj",
|
||||||
|
"projectKey": "mihakralj_QuanTAlib"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.DotNet.Interactive.Formatting" Version="1.0.0-beta.21459.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(IsLocalBuild)' == 'true'">
|
<PropertyGroup Condition="'$(IsLocalBuild)' == 'true'">
|
||||||
|
|||||||
+46
-35
@@ -1,57 +1,68 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.0.31903.59
|
VisualStudioVersion = 17.5.002.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "quantalib", "lib\quantalib.csproj", "{584E06A9-CEB4-476A-85CC-6A8FF3974AE2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "benchmark", "benchmark\benchmark.csproj", "{DBB674D9-43AA-4383-A4D0-E791847C7145}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{D85FEBB4-B651-466F-85CC-FD902378D4D2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "quantalib", "lib\quantalib.csproj", "{D2F742C0-9E2A-4B07-8D9F-0DF0BA3DDA31}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MovingAverages", "quantower\Averages\Averages.csproj", "{32CC09CC-26E3-4FCE-8932-C0513C4AD766}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SyntheticVendor", "SyntheticVendor\SyntheticVendor.csproj", "{1777C7BB-F67A-4F00-99BB-EE48178A7129}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntheticVendor", "SyntheticVendor\SyntheticVendor.csproj", "{20B1B5F1-8C36-4668-B0AE-951C13AE197B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "tests\Tests.csproj", "{A89D1A5D-9DB9-4E5D-A7D6-E153509430CD}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "quantower", "quantower", "{A8D9AE68-24E3-476C-BB98-244541BB4B43}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "quantower", "quantower", "{1EC1B338-6AD9-4E3D-82C3-6591CC148DD5}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Statistics", "quantower\Statistics\Statistics.csproj", "{B6D3EB11-63B6-430F-B526-E1981B3D8214}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Averages", "quantower\Averages\Averages.csproj", "{61AFF1E5-9E2B-47F4-9665-D8358C5BDD6F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "benchmark", "benchmark\benchmark.csproj", "{6629C6D2-FC34-4BDF-AEF4-A5859E05981E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Statistics", "quantower\Statistics\Statistics.csproj", "{7EBB6ECD-15FA-44DD-B231-FED97E0B710D}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volatility", "quantower\Volatility\Volatility.csproj", "{9190CFDD-9FD8-4E14-9269-79325B03EC6C}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{DBB674D9-43AA-4383-A4D0-E791847C7145}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DBB674D9-43AA-4383-A4D0-E791847C7145}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DBB674D9-43AA-4383-A4D0-E791847C7145}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DBB674D9-43AA-4383-A4D0-E791847C7145}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D2F742C0-9E2A-4B07-8D9F-0DF0BA3DDA31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D2F742C0-9E2A-4B07-8D9F-0DF0BA3DDA31}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D2F742C0-9E2A-4B07-8D9F-0DF0BA3DDA31}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D2F742C0-9E2A-4B07-8D9F-0DF0BA3DDA31}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1777C7BB-F67A-4F00-99BB-EE48178A7129}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1777C7BB-F67A-4F00-99BB-EE48178A7129}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1777C7BB-F67A-4F00-99BB-EE48178A7129}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1777C7BB-F67A-4F00-99BB-EE48178A7129}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A89D1A5D-9DB9-4E5D-A7D6-E153509430CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A89D1A5D-9DB9-4E5D-A7D6-E153509430CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A89D1A5D-9DB9-4E5D-A7D6-E153509430CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A89D1A5D-9DB9-4E5D-A7D6-E153509430CD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{61AFF1E5-9E2B-47F4-9665-D8358C5BDD6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{61AFF1E5-9E2B-47F4-9665-D8358C5BDD6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{61AFF1E5-9E2B-47F4-9665-D8358C5BDD6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{61AFF1E5-9E2B-47F4-9665-D8358C5BDD6F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7EBB6ECD-15FA-44DD-B231-FED97E0B710D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7EBB6ECD-15FA-44DD-B231-FED97E0B710D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7EBB6ECD-15FA-44DD-B231-FED97E0B710D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7EBB6ECD-15FA-44DD-B231-FED97E0B710D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9190CFDD-9FD8-4E14-9269-79325B03EC6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9190CFDD-9FD8-4E14-9269-79325B03EC6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9190CFDD-9FD8-4E14-9269-79325B03EC6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9190CFDD-9FD8-4E14-9269-79325B03EC6C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{584E06A9-CEB4-476A-85CC-6A8FF3974AE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{584E06A9-CEB4-476A-85CC-6A8FF3974AE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{584E06A9-CEB4-476A-85CC-6A8FF3974AE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{584E06A9-CEB4-476A-85CC-6A8FF3974AE2}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{D85FEBB4-B651-466F-85CC-FD902378D4D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{D85FEBB4-B651-466F-85CC-FD902378D4D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{D85FEBB4-B651-466F-85CC-FD902378D4D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{D85FEBB4-B651-466F-85CC-FD902378D4D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{32CC09CC-26E3-4FCE-8932-C0513C4AD766}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{32CC09CC-26E3-4FCE-8932-C0513C4AD766}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{32CC09CC-26E3-4FCE-8932-C0513C4AD766}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{32CC09CC-26E3-4FCE-8932-C0513C4AD766}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{20B1B5F1-8C36-4668-B0AE-951C13AE197B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{20B1B5F1-8C36-4668-B0AE-951C13AE197B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{20B1B5F1-8C36-4668-B0AE-951C13AE197B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{20B1B5F1-8C36-4668-B0AE-951C13AE197B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{B6D3EB11-63B6-430F-B526-E1981B3D8214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B6D3EB11-63B6-430F-B526-E1981B3D8214}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B6D3EB11-63B6-430F-B526-E1981B3D8214}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B6D3EB11-63B6-430F-B526-E1981B3D8214}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6629C6D2-FC34-4BDF-AEF4-A5859E05981E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6629C6D2-FC34-4BDF-AEF4-A5859E05981E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6629C6D2-FC34-4BDF-AEF4-A5859E05981E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6629C6D2-FC34-4BDF-AEF4-A5859E05981E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{B6D3EB11-63B6-430F-B526-E1981B3D8214} = {A8D9AE68-24E3-476C-BB98-244541BB4B43}
|
{61AFF1E5-9E2B-47F4-9665-D8358C5BDD6F} = {1EC1B338-6AD9-4E3D-82C3-6591CC148DD5}
|
||||||
|
{7EBB6ECD-15FA-44DD-B231-FED97E0B710D} = {1EC1B338-6AD9-4E3D-82C3-6591CC148DD5}
|
||||||
|
{9190CFDD-9FD8-4E14-9269-79325B03EC6C} = {1EC1B338-6AD9-4E3D-82C3-6591CC148DD5}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {080D10E4-B741-4A85-B37B-08845A5C78D9}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -540,7 +540,10 @@ namespace SyntheticVendorNamespace
|
|||||||
openValue = 0.0001;
|
openValue = 0.0001;
|
||||||
closeValue = 100;
|
closeValue = 100;
|
||||||
}
|
}
|
||||||
else { }
|
else
|
||||||
|
{
|
||||||
|
// No action
|
||||||
|
}
|
||||||
|
|
||||||
return new HistoryItemBar
|
return new HistoryItemBar
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,857 +0,0 @@
|
|||||||
using Xunit;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class Consistency
|
|
||||||
{
|
|
||||||
Random rnd;
|
|
||||||
int series_len = 1000;
|
|
||||||
int corrections = 100;
|
|
||||||
|
|
||||||
public Consistency()
|
|
||||||
{ //constructor
|
|
||||||
rnd = new((int)DateTime.Now.Ticks);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CanUpdate()
|
|
||||||
{
|
|
||||||
|
|
||||||
GbmFeed gbm = new();
|
|
||||||
TSeries input = new(gbm.Close);
|
|
||||||
TSeries output = new(input);
|
|
||||||
|
|
||||||
gbm.Add(10000);
|
|
||||||
|
|
||||||
Assert.Equal(input.Count, output.Count);
|
|
||||||
for (int i = 0; i < input.Count; i++)
|
|
||||||
{
|
|
||||||
Assert.Equal(input[i].v, output[i].v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Alma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
double offset = rnd.Next();
|
|
||||||
double sigma = rnd.Next(1, 100);
|
|
||||||
Alma ma1 = new(period: p, offset: offset, sigma: sigma);
|
|
||||||
Alma ma2 = new(period: p, offset: offset, sigma: sigma);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Convolution_isNew()
|
|
||||||
{
|
|
||||||
Convolution ma1 = new(new double[] { 1.0, 2, 3, 2, 1 });
|
|
||||||
Convolution ma2 = new(new double[] { 1.0, 2, 3, 2, 1 });
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Dema_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Dema ma1 = new(p);
|
|
||||||
Dema ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Dsma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Dsma ma1 = new(p);
|
|
||||||
Dsma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Dwma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Dwma ma1 = new(p);
|
|
||||||
Dwma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void EmaSma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Ema ma1 = new(p, useSma: true);
|
|
||||||
Ema ma2 = new(p, useSma: true);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Ema_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Ema ma1 = new(p, useSma: false);
|
|
||||||
Ema ma2 = new(p, useSma: false);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Sma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Sma ma1 = new(p);
|
|
||||||
Sma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Epma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Epma ma1 = new(p);
|
|
||||||
Epma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Frama_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Frama ma1 = new(p);
|
|
||||||
Frama ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Fwma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Fwma ma1 = new(p);
|
|
||||||
Fwma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Gma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Gma ma1 = new(p);
|
|
||||||
Gma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Hma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Hma ma1 = new(p);
|
|
||||||
Hma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Hwma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Hwma ma1 = new(p);
|
|
||||||
Hwma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Kama_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Kama ma1 = new(p);
|
|
||||||
Kama ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Ltma_isNew()
|
|
||||||
{
|
|
||||||
int p = rnd.Next(0, 1);
|
|
||||||
Ltma ma1 = new(p);
|
|
||||||
Ltma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Mama_isNew()
|
|
||||||
{
|
|
||||||
int p = rnd.Next(0, 1);
|
|
||||||
Mama ma1 = new(p, p * 0.1);
|
|
||||||
Mama ma2 = new(p, p * 0.1);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
|
|
||||||
Assert.True(ma1.Value == ma2.Value, $"Assertion failed for p={p}, i={i}. Expected {ma1.Value} but got {ma2.Value}.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Mgdi_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Mgdi ma1 = new(p);
|
|
||||||
Mgdi ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Mma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Mma ma1 = new(p);
|
|
||||||
Mma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Qema_isNew()
|
|
||||||
{
|
|
||||||
Qema ma1 = new();
|
|
||||||
Qema ma2 = new();
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Rema_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Rema ma1 = new(p);
|
|
||||||
Rema ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Rma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Rma ma1 = new(p);
|
|
||||||
Rma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Sinema_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Sinema ma1 = new(p);
|
|
||||||
Sinema ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Smma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Smma ma1 = new(p);
|
|
||||||
Smma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void T3_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
T3 ma1 = new(p);
|
|
||||||
T3 ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Tema_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Tema ma1 = new(p);
|
|
||||||
Tema ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Trima_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Trima ma1 = new(p);
|
|
||||||
Trima ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Vidya_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Vidya ma1 = new(p);
|
|
||||||
Vidya ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Wma_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Wma ma1 = new(p);
|
|
||||||
Wma ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[Fact]
|
|
||||||
public void Zlema_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Zlema ma1 = new(p);
|
|
||||||
Zlema ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Entropy_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Entropy ma1 = new(p);
|
|
||||||
Entropy ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Kurtosis_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(5, 100);
|
|
||||||
Kurtosis ma1 = new(p);
|
|
||||||
Kurtosis ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Max_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Max ma1 = new(p, 0.01);
|
|
||||||
Max ma2 = new(p, 0.01);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Min_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Min ma1 = new(p, 0.01);
|
|
||||||
Min ma2 = new(p, 0.01);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Med_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Median ma1 = new(p);
|
|
||||||
Median ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Mode_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Mode ma1 = new(p);
|
|
||||||
Mode ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Percentile_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Percentile ma1 = new(p, 50);
|
|
||||||
Percentile ma2 = new(p, 50);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Skew_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Skew ma1 = new(p);
|
|
||||||
Skew ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Stddev_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Stddev ma1 = new(p);
|
|
||||||
Stddev ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Variance_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Variance ma1 = new(p);
|
|
||||||
Variance ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Zscore_isNew()
|
|
||||||
{
|
|
||||||
int p = (int)rnd.Next(2, 100);
|
|
||||||
Zscore ma1 = new(p);
|
|
||||||
Zscore ma2 = new(p);
|
|
||||||
for (int i = 0; i < series_len; i++)
|
|
||||||
{
|
|
||||||
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
for (int j = 0; j < corrections; j++)
|
|
||||||
{
|
|
||||||
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
|
||||||
ma1.Calc(item1);
|
|
||||||
}
|
|
||||||
ma2.Calc(new TValue(item1.Time, item1.Value, IsNew: true));
|
|
||||||
Assert.Equal(ma1.Value, ma2.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using Xunit;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace QuanTAlib
|
||||||
|
{
|
||||||
|
public class BarIndicatorTests
|
||||||
|
{
|
||||||
|
private Random rnd;
|
||||||
|
private const int SeriesLen = 1000;
|
||||||
|
private const int Corrections = 100;
|
||||||
|
|
||||||
|
public BarIndicatorTests()
|
||||||
|
{
|
||||||
|
rnd = new Random((int)DateTime.Now.Ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly iTValue[] indicators = new iTValue[]
|
||||||
|
{
|
||||||
|
new Atr(period: 14),
|
||||||
|
};
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(GetIndicators))]
|
||||||
|
public void IndicatorIsNew(iTValue indicator)
|
||||||
|
{
|
||||||
|
var indicator1 = indicator;
|
||||||
|
var indicator2 = indicator;
|
||||||
|
|
||||||
|
MethodInfo calcMethod = indicator.GetType().GetMethod("Calc")!;
|
||||||
|
if (calcMethod == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Calc method not found for indicator type: {indicator.GetType().Name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < SeriesLen; i++)
|
||||||
|
{
|
||||||
|
TBar item1 = new(Time: DateTime.Now, Open: rnd.Next(-100, 100), High: rnd.Next(-100, 100), Low: rnd.Next(-100, 100), Close: rnd.Next(-100, 100), Volume: rnd.Next(-1000, 1000), IsNew: true);
|
||||||
|
calcMethod.Invoke(indicator1, new object[] { item1 });
|
||||||
|
|
||||||
|
for (int j = 0; j < Corrections; j++)
|
||||||
|
{
|
||||||
|
item1 = new(Time: DateTime.Now, Open: rnd.Next(-100, 100), High: rnd.Next(-100, 100), Low: rnd.Next(-100, 100), Close: rnd.Next(-100, 100), Volume: rnd.Next(-1000, 1000), IsNew: false);
|
||||||
|
calcMethod.Invoke(indicator1, new object[] { item1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
var item2 = new TBar (item1.Time, item1.Open, item1.High, item1.Low, item1.Close, item1.Volume , IsNew: true);
|
||||||
|
calcMethod.Invoke(indicator2, new object[] { item2 });
|
||||||
|
|
||||||
|
Assert.Equal(indicator1.Value, indicator2.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> GetIndicators()
|
||||||
|
{
|
||||||
|
return indicators.Select(indicator => new object[] { indicator });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
using Xunit;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace QuanTAlib
|
||||||
|
{
|
||||||
|
public class IndicatorTests
|
||||||
|
{
|
||||||
|
private Random rnd;
|
||||||
|
private const int SeriesLen = 1000;
|
||||||
|
private const int Corrections = 100;
|
||||||
|
|
||||||
|
public IndicatorTests()
|
||||||
|
{
|
||||||
|
rnd = new Random((int)DateTime.Now.Ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly iTValue[] indicators =
|
||||||
|
[
|
||||||
|
new Ema(period: 10, useSma: true),
|
||||||
|
new Alma(period: 14, offset: 0.85, sigma: 6),
|
||||||
|
new Convolution(new double[] { 1.0, 2, 3, 2, 1 }),
|
||||||
|
new Dema(period: 14),
|
||||||
|
new Dsma(period: 14),
|
||||||
|
new Dwma(period: 14),
|
||||||
|
new Epma(period: 14),
|
||||||
|
new Frama(period: 14),
|
||||||
|
new Fwma(period: 14),
|
||||||
|
new Gma(period: 14),
|
||||||
|
new Hma(period: 14),
|
||||||
|
new Hwma(period: 14),
|
||||||
|
new Kama(period: 14),
|
||||||
|
new Mama(fastLimit: 0.5, slowLimit: 0.05),
|
||||||
|
new Mgdi(period: 14),
|
||||||
|
new Mma(period: 14),
|
||||||
|
new Qema(),
|
||||||
|
new Rema(period: 14),
|
||||||
|
new Rma(period: 14),
|
||||||
|
new Sinema(period: 14),
|
||||||
|
new Sma(period: 14),
|
||||||
|
new Smma(period: 14),
|
||||||
|
new T3(period: 14),
|
||||||
|
new Tema(period: 14),
|
||||||
|
new Trima(period: 14),
|
||||||
|
new Vidya(shortPeriod: 14, longPeriod: 30, alpha: 0.2),
|
||||||
|
new Wma(period: 14),
|
||||||
|
new Zlema(period: 14),
|
||||||
|
new Entropy(period: 14),
|
||||||
|
new Kurtosis(period: 14),
|
||||||
|
new Max(period: 14, decay: 0.01),
|
||||||
|
new Min(period: 14, decay: 0.01),
|
||||||
|
new Median(period: 14),
|
||||||
|
new Mode(period: 14),
|
||||||
|
new Percentile(period: 14, percent: 50),
|
||||||
|
new Skew(period: 14),
|
||||||
|
new Stddev(period: 14),
|
||||||
|
new Variance(period: 14),
|
||||||
|
new Zscore(period: 14)
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(GetIndicators))]
|
||||||
|
public void IndicatorIsNew(iTValue indicator)
|
||||||
|
{
|
||||||
|
var indicator1 = indicator;
|
||||||
|
var indicator2 = indicator;
|
||||||
|
|
||||||
|
MethodInfo calcMethod = indicator.GetType().GetMethod("Calc")!;
|
||||||
|
if (calcMethod == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Calc method not found for indicator type: {indicator.GetType().Name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < SeriesLen; i++)
|
||||||
|
{
|
||||||
|
TValue item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: true);
|
||||||
|
calcMethod.Invoke(indicator1, new object[] { item1 });
|
||||||
|
|
||||||
|
for (int j = 0; j < Corrections; j++)
|
||||||
|
{
|
||||||
|
item1 = new(Time: DateTime.Now, Value: rnd.Next(-100, 100), IsNew: false);
|
||||||
|
calcMethod.Invoke(indicator1, new object[] { item1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
var item2 = new TValue(item1.Time, item1.Value, IsNew: true);
|
||||||
|
calcMethod.Invoke(indicator2, new object[] { item2 });
|
||||||
|
|
||||||
|
Assert.Equal(indicator1.Value, indicator2.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> GetIndicators()
|
||||||
|
{
|
||||||
|
return indicators.Select(indicator => new object[] { indicator });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -320,4 +320,24 @@ public class SkenderTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ATR()
|
||||||
|
{
|
||||||
|
for (int run = 0; run < iterations; run++)
|
||||||
|
{
|
||||||
|
period = rnd.Next(50) + 5;
|
||||||
|
Atr ma = new(period: period);
|
||||||
|
TSeries QL = new();
|
||||||
|
foreach (TBar item in bars) { QL.Add(ma.Calc(item)); }
|
||||||
|
|
||||||
|
var SK = quotes.GetAtr(lookbackPeriods: period).Select(i => i.Atr.Null2NaN()!);
|
||||||
|
Assert.Equal(QL.Length, QL.Length);
|
||||||
|
|
||||||
|
for (int i = QL.Length - 1; i > period +500; i--)
|
||||||
|
{
|
||||||
|
Assert.InRange(SK.ElementAt(i) - QL[i].Value, -range, range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Backlog and done
|
||||||
|
|
||||||
|
|**QT**|**Cht**|Cmnt|Docs|isNew|Valid|
|
||||||
|
|--|:--:|:--:|:--:|:--:|:--:|
|
||||||
|
|AFIRMA|✔️|||||
|
||||||
+31
-3
@@ -8,6 +8,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css" integrity="sha384-G+RAlt+LEfAH/nY+DZh3+XIhRboypMI32hiJ9BwnmjF41May5BWQKyrDrEkNdV/i" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css" integrity="sha384-G+RAlt+LEfAH/nY+DZh3+XIhRboypMI32hiJ9BwnmjF41May5BWQKyrDrEkNdV/i" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/katex.min.css" integrity="sha384-3UiQGuEI4TTMaFmGIZumfRPtfKQ3trwQE2JgosJxCnGmQpL/lJdjpcHkaaFwHlcI" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/katex.min.css" integrity="sha384-3UiQGuEI4TTMaFmGIZumfRPtfKQ3trwQE2JgosJxCnGmQpL/lJdjpcHkaaFwHlcI" crossorigin="anonymous">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.markdown-section {
|
.markdown-section {
|
||||||
max-width: none !important;
|
max-width: none !important;
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
.markdown-section table tbody td {
|
.markdown-section table tbody td {
|
||||||
padding: 4px 1px;
|
padding: 4px 1px;
|
||||||
}
|
}
|
||||||
:root {
|
:root {
|
||||||
--sidebar-width: 350px;
|
--sidebar-width: 350px;
|
||||||
@@ -32,7 +33,34 @@
|
|||||||
.sidebar-toggle {
|
.sidebar-toggle {
|
||||||
width: var(--sidebar-width);
|
width: var(--sidebar-width);
|
||||||
}
|
}
|
||||||
|
/* Updated styles for partially expandable sidebar */
|
||||||
|
.sidebar-nav ul ul ul ul {
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: 0;
|
||||||
|
transition: max-height 0.3s ease-out;
|
||||||
|
}
|
||||||
|
.sidebar-nav ul ul ul li:hover > ul {
|
||||||
|
max-height: 1000px;
|
||||||
|
transition: max-height 0.3s ease-in;
|
||||||
|
}
|
||||||
|
.sidebar-nav .collapse.level-4 > ul {
|
||||||
|
max-height: 0 !important;
|
||||||
|
}
|
||||||
|
.sidebar-nav .collapse.level-4:hover > ul {
|
||||||
|
max-height: 1000px !important;
|
||||||
|
}
|
||||||
|
.sidebar-nav .folder > .app-sub-sidebar {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
/* Ensure levels 1, 2, and 3 are always visible */
|
||||||
|
.sidebar-nav > ul,
|
||||||
|
.sidebar-nav > ul > li > ul,
|
||||||
|
.sidebar-nav > ul > li > ul > li > ul {
|
||||||
|
max-height: none !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
@@ -40,10 +68,10 @@
|
|||||||
window.$docsify = {
|
window.$docsify = {
|
||||||
homepage: 'readme.md',
|
homepage: 'readme.md',
|
||||||
loadSidebar: true,
|
loadSidebar: true,
|
||||||
subMaxLevel: 1,
|
subMaxLevel: 4, // Increased to allow for level 4+ items
|
||||||
name: '',
|
name: '',
|
||||||
repo: '',
|
repo: '',
|
||||||
sidebarDisplayLevel: 2,
|
sidebarDisplayLevel: 3, // Changed to keep levels 1, 2, and 3 expanded
|
||||||
themeable: {
|
themeable: {
|
||||||
readyTransition: true,
|
readyTransition: true,
|
||||||
responsiveTables: true
|
responsiveTables: true
|
||||||
|
|||||||
+2
-5
@@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
**Quan**titative **TA** **lib**rary (QuanTAlib) is a C# library of classess and methods for quantitative technical analysis useful for analyzing quotes with [Quantower](https://www.quantower.com/) and other C#-based trading platforms.
|
**Quan**titative **TA** **lib**rary (QuanTAlib) is a C# library of classess and methods for quantitative technical analysis useful for analyzing quotes with [Quantower](https://www.quantower.com/) and other C#-based trading platforms.
|
||||||
|
|
||||||
[**Visit documentation pages**](https://mihakralj.github.io/QuanTAlib/#/)
|
[**Visit documentation pages**](https://mihakralj.github.io/QuanTAlib/#/)<br>
|
||||||
|
[**List of indicators - implemented and planned**](indicators/indicators.md)
|
||||||
|
|
||||||
**QuanTAlib** is a C# library written with some specific design criteria in mind. Here is why there is '_yet another C# TA library_':
|
**QuanTAlib** is a C# library written with some specific design criteria in mind. Here is why there is '_yet another C# TA library_':
|
||||||
|
|
||||||
@@ -24,10 +25,6 @@
|
|||||||
- **Allow updates/corrections** of the last quote - QuanTAlib is re-calculating the last value as many times as required before continuing to the new bar
|
- **Allow updates/corrections** of the last quote - QuanTAlib is re-calculating the last value as many times as required before continuing to the new bar
|
||||||
- **Calculate early data right** - calculated data is as valid as mathematically possible from the first value onwards - no blackout or warming-up periods. All indicators return data from the first bar, alongside with a flag `isHot` - defining if calculation is already stable.
|
- **Calculate early data right** - calculated data is as valid as mathematically possible from the first value onwards - no blackout or warming-up periods. All indicators return data from the first bar, alongside with a flag `isHot` - defining if calculation is already stable.
|
||||||
|
|
||||||
### Coverage
|
|
||||||
|
|
||||||
[List of indicators - implemented and planned](indicators/indicators.md)
|
|
||||||
|
|
||||||
## Installation to Quantower
|
## Installation to Quantower
|
||||||
|
|
||||||
- `<Quantower_root>` is the directory where Quantower is installed - where `Start.lnk` launcher is
|
- `<Quantower_root>` is the directory where Quantower is installed - where `Start.lnk` launcher is
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class Ama : AbstractBase
|
|
||||||
{
|
|
||||||
private readonly int Period;
|
|
||||||
private readonly CircularBuffer _buffer;
|
|
||||||
private readonly double _alpha; // Adaptive factor
|
|
||||||
private double _lastAfirma, _p_lastAfirma;
|
|
||||||
private double _lastError, _p_lastError;
|
|
||||||
|
|
||||||
public Ama(int period, double alpha = 0.1)
|
|
||||||
{
|
|
||||||
if (period < 1)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1.");
|
|
||||||
}
|
|
||||||
if (alpha <= 0 || alpha >= 1)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(alpha), "Alpha must be between 0 and 1 (exclusive).");
|
|
||||||
}
|
|
||||||
Period = period;
|
|
||||||
WarmupPeriod = period;
|
|
||||||
_buffer = new CircularBuffer(period);
|
|
||||||
_alpha = alpha;
|
|
||||||
Name = "Afirma";
|
|
||||||
WarmupPeriod = period;
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ama(object source, int period, double alpha = 0.1) : this(period: period, alpha: alpha)
|
|
||||||
{
|
|
||||||
var pubEvent = source.GetType().GetEvent("Pub");
|
|
||||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Init()
|
|
||||||
{
|
|
||||||
base.Init();
|
|
||||||
_lastAfirma = 0;
|
|
||||||
_lastError = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ManageState(bool isNew)
|
|
||||||
{
|
|
||||||
if (isNew)
|
|
||||||
{
|
|
||||||
_lastValidValue = Input.Value;
|
|
||||||
_index++;
|
|
||||||
_p_lastAfirma = _lastAfirma;
|
|
||||||
_p_lastError = _lastError;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_lastAfirma = _p_lastAfirma;
|
|
||||||
_lastError = _p_lastError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Core AFIRMA calculation
|
|
||||||
/// </summary>
|
|
||||||
protected override double Calculation()
|
|
||||||
{
|
|
||||||
double result;
|
|
||||||
ManageState(IsNew);
|
|
||||||
_buffer.Add(Input.Value, Input.IsNew);
|
|
||||||
|
|
||||||
if (_index < Period)
|
|
||||||
{
|
|
||||||
// Use simple average during warmup period
|
|
||||||
result = _buffer.Average();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// AFIRMA calculation
|
|
||||||
double sma = _buffer.Average();
|
|
||||||
double error = Input.Value - _lastAfirma;
|
|
||||||
double denominator = Math.Abs(error) + Math.Abs(_lastError);
|
|
||||||
double adaptiveFactor = denominator != 0 ? _alpha * Math.Abs(error) / denominator : _alpha;
|
|
||||||
result = sma + adaptiveFactor * (Input.Value - sma);
|
|
||||||
|
|
||||||
_lastError = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastAfirma = result;
|
|
||||||
IsHot = _index >= WarmupPeriod;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,6 @@ public class Mama : AbstractBase
|
|||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
Fama = new TValue();
|
Fama = new TValue();
|
||||||
base.Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ManageState(bool isNew)
|
protected override void ManageState(bool isNew)
|
||||||
|
|||||||
+12
-28
@@ -1,7 +1,6 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
public class T3 : AbstractBase
|
public class T3 : AbstractBase {
|
||||||
{
|
|
||||||
private readonly int _period;
|
private readonly int _period;
|
||||||
private readonly bool _useSma;
|
private readonly bool _useSma;
|
||||||
private readonly double _k, _c1, _c2, _c3, _c4;
|
private readonly double _k, _c1, _c2, _c3, _c4;
|
||||||
@@ -9,10 +8,8 @@ public class T3 : AbstractBase
|
|||||||
private double _lastEma1, _lastEma2, _lastEma3, _lastEma4, _lastEma5, _lastEma6;
|
private double _lastEma1, _lastEma2, _lastEma3, _lastEma4, _lastEma5, _lastEma6;
|
||||||
private double _p_lastEma1, _p_lastEma2, _p_lastEma3, _p_lastEma4, _p_lastEma5, _p_lastEma6;
|
private double _p_lastEma1, _p_lastEma2, _p_lastEma3, _p_lastEma4, _p_lastEma5, _p_lastEma6;
|
||||||
|
|
||||||
public T3(int period, double vfactor = 0.7, bool useSma = true)
|
public T3(int period, double vfactor = 0.7, bool useSma = true) {
|
||||||
{
|
if (period < 1) {
|
||||||
if (period < 1)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Period must be greater than or equal to 1.", nameof(period));
|
throw new ArgumentException("Period must be greater than or equal to 1.", nameof(period));
|
||||||
}
|
}
|
||||||
_period = period;
|
_period = period;
|
||||||
@@ -37,15 +34,12 @@ public class T3 : AbstractBase
|
|||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T3(object source, int period, double vfactor = 0.7, bool useSma = true) : this(period, vfactor, useSma)
|
public T3(object source, int period, double vfactor = 0.7, bool useSma = true) : this(period, vfactor, useSma) {
|
||||||
{
|
|
||||||
var pubEvent = source.GetType().GetEvent("Pub");
|
var pubEvent = source.GetType().GetEvent("Pub");
|
||||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init()
|
public override void Init() {
|
||||||
{
|
|
||||||
base.Init();
|
|
||||||
_lastEma1 = _lastEma2 = _lastEma3 = _lastEma4 = _lastEma5 = _lastEma6 = 0;
|
_lastEma1 = _lastEma2 = _lastEma3 = _lastEma4 = _lastEma5 = _lastEma6 = 0;
|
||||||
_buffer1.Clear();
|
_buffer1.Clear();
|
||||||
_buffer2.Clear();
|
_buffer2.Clear();
|
||||||
@@ -55,10 +49,8 @@ public class T3 : AbstractBase
|
|||||||
_buffer6.Clear();
|
_buffer6.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ManageState(bool isNew)
|
protected override void ManageState(bool isNew) {
|
||||||
{
|
if (isNew) {
|
||||||
if (isNew)
|
|
||||||
{
|
|
||||||
_lastValidValue = Input.Value;
|
_lastValidValue = Input.Value;
|
||||||
_index++;
|
_index++;
|
||||||
_p_lastEma1 = _lastEma1;
|
_p_lastEma1 = _lastEma1;
|
||||||
@@ -67,9 +59,7 @@ public class T3 : AbstractBase
|
|||||||
_p_lastEma4 = _lastEma4;
|
_p_lastEma4 = _lastEma4;
|
||||||
_p_lastEma5 = _lastEma5;
|
_p_lastEma5 = _lastEma5;
|
||||||
_p_lastEma6 = _lastEma6;
|
_p_lastEma6 = _lastEma6;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
_lastEma1 = _p_lastEma1;
|
_lastEma1 = _p_lastEma1;
|
||||||
_lastEma2 = _p_lastEma2;
|
_lastEma2 = _p_lastEma2;
|
||||||
_lastEma3 = _p_lastEma3;
|
_lastEma3 = _p_lastEma3;
|
||||||
@@ -80,18 +70,14 @@ public class T3 : AbstractBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override double Calculation()
|
protected override double Calculation() {
|
||||||
{
|
|
||||||
ManageState(Input.IsNew);
|
ManageState(Input.IsNew);
|
||||||
|
|
||||||
double ema1, ema2, ema3, ema4, ema5, ema6;
|
double ema1, ema2, ema3, ema4, ema5, ema6;
|
||||||
|
|
||||||
if (_index == 1)
|
if (_index == 1) {
|
||||||
{
|
|
||||||
ema1 = ema2 = ema3 = ema4 = ema5 = ema6 = Input.Value;
|
ema1 = ema2 = ema3 = ema4 = ema5 = ema6 = Input.Value;
|
||||||
}
|
} else if (_index <= _period && _useSma) {
|
||||||
else if (_index <= _period && _useSma)
|
|
||||||
{
|
|
||||||
_buffer1.Add(Input.Value, Input.IsNew);
|
_buffer1.Add(Input.Value, Input.IsNew);
|
||||||
ema1 = _buffer1.Average();
|
ema1 = _buffer1.Average();
|
||||||
_buffer2.Add(ema1, Input.IsNew);
|
_buffer2.Add(ema1, Input.IsNew);
|
||||||
@@ -104,9 +90,7 @@ public class T3 : AbstractBase
|
|||||||
ema5 = _buffer5.Average();
|
ema5 = _buffer5.Average();
|
||||||
_buffer6.Add(ema5, Input.IsNew);
|
_buffer6.Add(ema5, Input.IsNew);
|
||||||
ema6 = _buffer6.Average();
|
ema6 = _buffer6.Average();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
ema1 = _k * (Input.Value - _lastEma1) + _lastEma1;
|
ema1 = _k * (Input.Value - _lastEma1) + _lastEma1;
|
||||||
ema2 = _k * (ema1 - _lastEma2) + _lastEma2;
|
ema2 = _k * (ema1 - _lastEma2) + _lastEma2;
|
||||||
ema3 = _k * (ema2 - _lastEma3) + _lastEma3;
|
ema3 = _k * (ema2 - _lastEma3) + _lastEma3;
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a base implementation for financial indicators in the QuanTAlib library.
|
||||||
|
/// This abstract class implements the iTValue interface and defines common properties
|
||||||
|
/// and methods used by inheriting indicator types.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class AbstractBarBase : iTValue
|
||||||
|
{
|
||||||
|
public DateTime Time { get; set; }
|
||||||
|
public double Value { get; set; }
|
||||||
|
public bool IsNew { get; set; }
|
||||||
|
public bool IsHot { get; set; }
|
||||||
|
|
||||||
|
public TBar Input { get; set; }
|
||||||
|
public String Name { get; set; } = "";
|
||||||
|
public int WarmupPeriod { get; set; }
|
||||||
|
|
||||||
|
public TValue Tick => new(Time, Value, IsNew, IsHot); // Stores the current value of indicator
|
||||||
|
public event ValueSignal Pub = delegate { }; // Publisher of generated values
|
||||||
|
|
||||||
|
protected int _index; //tracking the position of output
|
||||||
|
protected double _lastValidValue;
|
||||||
|
// other _internal vars defined here
|
||||||
|
|
||||||
|
protected AbstractBarBase()
|
||||||
|
{ //add parameters into constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Sub(object source, in TBarEventArgs args) => Calc(args.Bar);
|
||||||
|
|
||||||
|
public virtual void Init()
|
||||||
|
{
|
||||||
|
_index = 0;
|
||||||
|
_lastValidValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual TValue Calc(TBar input)
|
||||||
|
{
|
||||||
|
Input = input;
|
||||||
|
if (double.IsNaN(input.Close) || double.IsInfinity(input.Close))
|
||||||
|
{
|
||||||
|
return Process(new TValue(Time: input.Time, Value: GetLastValid(), IsNew: input.IsNew, IsHot: true));
|
||||||
|
}
|
||||||
|
this.Value = Calculation();
|
||||||
|
return Process(new TValue(Time: Input.Time, Value: this.Value, IsNew: Input.IsNew, IsHot: this.IsHot));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual double GetLastValid()
|
||||||
|
{
|
||||||
|
return this.Value;
|
||||||
|
}
|
||||||
|
protected abstract void ManageState(bool isNew);
|
||||||
|
protected abstract double Calculation();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes the calculated value, updates the indicator's own state,
|
||||||
|
/// and publishes the result through an event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The calculated TValue to process.</param>
|
||||||
|
/// <returns>The processed TValue.</returns>
|
||||||
|
protected virtual TValue Process(TValue value)
|
||||||
|
{
|
||||||
|
this.Time = value.Time;
|
||||||
|
this.Value = value.Value;
|
||||||
|
this.IsNew = value.IsNew;
|
||||||
|
this.IsHot = value.IsHot;
|
||||||
|
Pub?.Invoke(this, new ValueEventArgs(value));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -84,7 +84,8 @@ public class TBarSeries : List<TBar>
|
|||||||
|
|
||||||
public new virtual void Add(TBar bar)
|
public new virtual void Add(TBar bar)
|
||||||
{
|
{
|
||||||
if (bar.IsNew) { base.Add(bar); } else { this[^1] = bar; }
|
if (bar.IsNew || base.Count == 0) { base.Add(bar); }
|
||||||
|
else { this[^1] = bar; }
|
||||||
Pub?.Invoke(this, new TBarEventArgs(bar));
|
Pub?.Invoke(this, new TBarEventArgs(bar));
|
||||||
|
|
||||||
Open.Add(bar.Time, bar.Open, IsNew: bar.IsNew, IsHot: true);
|
Open.Add(bar.Time, bar.Open, IsNew: bar.IsNew, IsHot: true);
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ public class TSeries : List<TValue>
|
|||||||
|
|
||||||
public new virtual void Add(TValue tick)
|
public new virtual void Add(TValue tick)
|
||||||
{
|
{
|
||||||
if (tick.IsNew) { base.Add(tick); }
|
if (tick.IsNew || base.Count==0) { base.Add(tick); }
|
||||||
else { this[^1] = tick; }
|
else { this[^1] = tick; }
|
||||||
Pub?.Invoke(this, new ValueEventArgs(tick));
|
Pub?.Invoke(this, new ValueEventArgs(tick));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="readme.md" Pack="true" PackagePath=""/>
|
<None Include="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="Microsoft.DotNet.Interactive.Formatting" Version="1.0.0-beta.24229.4" />
|
|
||||||
<PackageReference Include="System.Text.Json" Version="9.0.0-rc.1.24431.7" />
|
<PackageReference Include="System.Text.Json" Version="9.0.0-rc.1.24431.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class Atr : AbstractBarBase
|
||||||
|
{
|
||||||
|
private readonly int _period;
|
||||||
|
private readonly Ema _ma;
|
||||||
|
private double _prevClose, _p_prevClose;
|
||||||
|
|
||||||
|
public Atr(int period) : base()
|
||||||
|
{
|
||||||
|
if (period < 1)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1.");
|
||||||
|
}
|
||||||
|
_period = period;
|
||||||
|
_ma = new(1.0/period);
|
||||||
|
WarmupPeriod = _ma.WarmupPeriod;
|
||||||
|
Name = $"ATR({_period})";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Atr(object source, int period) : this(period)
|
||||||
|
{
|
||||||
|
var pubEvent = source.GetType().GetEvent("Pub");
|
||||||
|
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
_ma.Init();
|
||||||
|
_prevClose = double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ManageState(bool isNew)
|
||||||
|
{
|
||||||
|
if (isNew)
|
||||||
|
{
|
||||||
|
_index++;
|
||||||
|
_p_prevClose = _prevClose;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_prevClose = _p_prevClose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override double Calculation()
|
||||||
|
{
|
||||||
|
ManageState(Input.IsNew);
|
||||||
|
|
||||||
|
double trueRange = Math.Max(
|
||||||
|
Math.Max(
|
||||||
|
Input.High - Input.Low,
|
||||||
|
Math.Abs(Input.High - _prevClose)
|
||||||
|
),
|
||||||
|
Math.Abs(Input.Low - _prevClose)
|
||||||
|
);
|
||||||
|
if (_index < 2)
|
||||||
|
{
|
||||||
|
trueRange = Input.High - Input.Low;
|
||||||
|
}
|
||||||
|
|
||||||
|
TValue emaTrueRange = _ma.Calc(new TValue(Input.Time, trueRange, Input.IsNew));
|
||||||
|
IsHot = _ma.IsHot;
|
||||||
|
_prevClose = Input.Close;
|
||||||
|
|
||||||
|
return emaTrueRange.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#!meta
|
||||||
|
|
||||||
|
{"kernelInfo":{"defaultKernelName":"csharp","items":[{"aliases":[],"name":"csharp"}]}}
|
||||||
|
|
||||||
|
#!csharp
|
||||||
|
|
||||||
|
#r "nuget:Skender.Stock.Indicators"
|
||||||
|
#r "..\lib\obj\Debug\QuanTAlib.dll"
|
||||||
|
|
||||||
|
#!csharp
|
||||||
|
|
||||||
|
using Skender.Stock.Indicators;
|
||||||
|
using QuanTAlib;
|
||||||
|
|
||||||
|
GbmFeed gbm = new();
|
||||||
|
Atr atr = new(gbm, 5);
|
||||||
|
TSeries res = new(atr);
|
||||||
|
gbm.Add(100);
|
||||||
|
|
||||||
|
IEnumerable<Quote> quotes = gbm.Select(item => new Quote { Date = item.Time, Open = (decimal)item.Open,
|
||||||
|
High = (decimal)item.High, Low = (decimal)item.Low, Close = (decimal)item.Close, Volume = (decimal)item.Volume });
|
||||||
|
var SkResults = quotes.GetAtr(5).Select(i => i.Atr.Null2NaN()!);
|
||||||
|
for (int i=0; i< gbm.Length; i++) {
|
||||||
|
Console.WriteLine($"{gbm.High[i].Value,6:F2} {gbm.Low[i].Value,6:F2} {gbm.Close[i].Value,6:F2}\t\t{res[i].Value,10:F4} {SkResults.ElementAt(i),10:F4}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#!csharp
|
||||||
|
|
||||||
|
Random rnd = new((int)DateTime.Now.Ticks);
|
||||||
|
GbmFeed feed = new(sigma: 0.5, mu: 0.0);
|
||||||
|
TBarSeries bars = new(feed);
|
||||||
|
feed.Add(20);
|
||||||
|
IEnumerable<Quote> quotes;
|
||||||
|
|
||||||
|
int period = rnd.Next(5) + 2;
|
||||||
|
Atr ma = new(period: period);
|
||||||
|
TSeries QL = new();
|
||||||
|
foreach (TBar item in bars) {
|
||||||
|
Console.WriteLine($"{ma.Calc(item)}");
|
||||||
|
//QL.Add(ma.Calc(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
#!csharp
|
||||||
|
|
||||||
|
bars
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using TradingPlatform.BusinessLayer;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class AmaIndicator : IndicatorBase
|
|
||||||
{
|
|
||||||
[InputParameter("Period", sortIndex: 1, 2, 2000, 1, 0)]
|
|
||||||
public int Period { get; set; } = 10;
|
|
||||||
|
|
||||||
[InputParameter("Alpha", sortIndex: 2, minimum: -0.01, maximum: 1.0, increment: 0.01, decimalPlaces: 2)]
|
|
||||||
public double Alpha { get; set; } = 0.1;
|
|
||||||
private Ama? ma;
|
|
||||||
protected override AbstractBase QuanTAlib => ma!;
|
|
||||||
public override string ShortName => $"AMA {Period} : {Alpha} : {SourceName}";
|
|
||||||
|
|
||||||
|
|
||||||
public AmaIndicator()
|
|
||||||
{
|
|
||||||
Name = "AMA - Adaptive Moving Average";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void InitIndicator()
|
|
||||||
{
|
|
||||||
ma = new Ama(period: Period, alpha: Alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
|
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.Interactive.Formatting" Version="1.0.0-beta.21459.1" />
|
|
||||||
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\obj\**">
|
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\obj\**">
|
||||||
<Link>lib\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
<Link>lib\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
|
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.DotNet.Interactive.Formatting" Version="1.0.0-beta.21459.1" />
|
|
||||||
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\obj\**">
|
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\obj\**">
|
||||||
<Link>lib\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
<Link>lib\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
using TradingPlatform.BusinessLayer.Chart;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Collections;
|
||||||
|
using TradingPlatform.BusinessLayer.TimeSync;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
public abstract class IndicatorBarBase : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 20)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
public int MinHistoryDepths { get; set; }
|
||||||
|
|
||||||
|
// LineSeries.LineSeries(string, Color, int, LineStyle)'
|
||||||
|
|
||||||
|
protected LineSeries? Series;
|
||||||
|
protected abstract AbstractBarBase QuanTAlib { get; }
|
||||||
|
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => 0;
|
||||||
|
|
||||||
|
protected IndicatorBarBase()
|
||||||
|
{
|
||||||
|
OnBackGround = true;
|
||||||
|
SeparateWindow = false;
|
||||||
|
Series = new(name: $"{Name}", color: Color.RoyalBlue, width: 2, style: LineStyle.Solid);
|
||||||
|
|
||||||
|
AddLineSeries(Series);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void InitIndicator();
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
InitIndicator();
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar bar = new(Time: Time(),
|
||||||
|
Open: GetPrice(PriceType.Open),
|
||||||
|
High: GetPrice(PriceType.High),
|
||||||
|
Low: GetPrice(PriceType.Low),
|
||||||
|
Close: GetPrice(PriceType.Close),
|
||||||
|
Volume: GetPrice(PriceType.Volume),
|
||||||
|
IsNew: args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar);
|
||||||
|
|
||||||
|
TValue result = QuanTAlib.Calc(bar);
|
||||||
|
Series!.SetValue(result.Value);
|
||||||
|
Series!.SetMarker(0, Color.Transparent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
List<Point> allPoints = new List<Point>();
|
||||||
|
if (CurrentChart == null) { return; }
|
||||||
|
|
||||||
|
Graphics gr = args.Graphics;
|
||||||
|
|
||||||
|
var mainWindow = this.CurrentChart.Windows[args.WindowIndex];
|
||||||
|
var converter = mainWindow.CoordinatesConverter;
|
||||||
|
var clientRect = mainWindow.ClientRectangle;
|
||||||
|
|
||||||
|
gr.SetClip(clientRect);
|
||||||
|
DateTime leftTime = new[] { converter.GetTime(clientRect.Left), Time(this.Count - 1) }.Max();
|
||||||
|
DateTime rightTime = new[] { converter.GetTime(clientRect.Right), Time(0) }.Min();
|
||||||
|
|
||||||
|
int leftIndex = (int)HistoricalData.GetIndexByTime(leftTime.Ticks) + 1;
|
||||||
|
int rightIndex = (int)HistoricalData.GetIndexByTime(rightTime.Ticks);
|
||||||
|
|
||||||
|
for (int i = rightIndex; i < leftIndex; i++)
|
||||||
|
{
|
||||||
|
int barX = (int)converter.GetChartX(Time(i));
|
||||||
|
int barY = (int)converter.GetChartY(Series![i]);
|
||||||
|
int halfBarWidth = CurrentChart.BarsWidth / 2;
|
||||||
|
Point point = new Point(barX + halfBarWidth, barY);
|
||||||
|
allPoints.Add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allPoints.Count > 1)
|
||||||
|
{
|
||||||
|
DrawSmoothCombinedCurve(gr, allPoints, this.Count - QuanTAlib.WarmupPeriod - rightIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawSmoothCombinedCurve(Graphics gr, List<Point> allPoints, int hotCount)
|
||||||
|
{
|
||||||
|
if (allPoints.Count < 2) { return; }
|
||||||
|
|
||||||
|
using (Pen defaultPen = new(Series!.Color, Series.Width) { DashStyle = ConvertLineStyleToDashStyle(Series.Style) })
|
||||||
|
using (Pen coldPen = new(Series!.Color, Series.Width) { DashStyle = DashStyle.Dot })
|
||||||
|
{
|
||||||
|
// Draw the hot part
|
||||||
|
if (hotCount > 0)
|
||||||
|
{
|
||||||
|
var hotPoints = allPoints.Take(Math.Min(hotCount + 1, allPoints.Count)).ToArray();
|
||||||
|
gr.DrawCurve(defaultPen, hotPoints, 0, hotPoints.Length - 1, (float)0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the cold part
|
||||||
|
if (ShowColdValues && hotCount < allPoints.Count)
|
||||||
|
{
|
||||||
|
var coldPoints = allPoints.Skip(Math.Max(0, hotCount)).ToArray();
|
||||||
|
gr.DrawCurve(coldPen, coldPoints, 0, coldPoints.Length - 1, (float)0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static DashStyle ConvertLineStyleToDashStyle(LineStyle lineStyle)
|
||||||
|
{
|
||||||
|
return lineStyle switch
|
||||||
|
{
|
||||||
|
LineStyle.Solid => DashStyle.Solid,
|
||||||
|
LineStyle.Dash => DashStyle.Dash,
|
||||||
|
LineStyle.Dot => DashStyle.Dot,
|
||||||
|
LineStyle.DashDot => DashStyle.DashDot,
|
||||||
|
_ => DashStyle.Solid,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
protected static void DrawText(Graphics gr, string text, Rectangle clientRect)
|
||||||
|
{
|
||||||
|
Font font = new Font("Inter", 8);
|
||||||
|
SizeF textSize = gr.MeasureString(text, font);
|
||||||
|
RectangleF textRect = new RectangleF(clientRect.Left + 5,
|
||||||
|
clientRect.Bottom - textSize.Height - 10,
|
||||||
|
textSize.Width + 10, textSize.Height + 10);
|
||||||
|
gr.FillRectangle(SystemBrushes.ControlDarkDark, textRect);
|
||||||
|
gr.DrawString(text, font, Brushes.White, new PointF(textRect.X + 6, textRect.Y + 5));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class AtrIndicator : IndicatorBarBase
|
||||||
|
{
|
||||||
|
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
|
||||||
|
public int Period { get; set; } = 20;
|
||||||
|
|
||||||
|
private Atr? atr;
|
||||||
|
protected override AbstractBarBase QuanTAlib => atr!;
|
||||||
|
public override string ShortName => $"ATR {Period}";
|
||||||
|
public AtrIndicator()
|
||||||
|
{
|
||||||
|
Name = "ATR - Average True Range";
|
||||||
|
SeparateWindow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void InitIndicator()
|
||||||
|
{
|
||||||
|
atr = new(Period);
|
||||||
|
MinHistoryDepths = atr!.WarmupPeriod;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<AlgoType>Indicator</AlgoType>
|
||||||
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
|
<IsLocalBuild Condition="'$(GITHUB_ACTIONS)' == ''">true</IsLocalBuild>
|
||||||
|
<UpdateAssemblyInfo>true</UpdateAssemblyInfo>
|
||||||
|
<GenerateGitVersionInformation>true</GenerateGitVersionInformation>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
|
||||||
|
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\obj\**">
|
||||||
|
<Link>lib\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="CopyCustomContent" AfterTargets="AfterBuild" Condition="'$(IsLocalBuild)' == 'true'">
|
||||||
|
<Copy SourceFiles="$(OutputPath)\Volatility.dll" DestinationFolder="$(QuantowerRoot)\Settings\Scripts\Indicators\QuanTAlib\Volatility" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="TradingPlatform.BusinessLayer">
|
||||||
|
<HintPath>..\..\.github\TradingPlatform.BusinessLayer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<None Include="..\..\.github\TradingPlatform.BusinessLayer.xml">
|
||||||
|
<Link>TradingPlatform.BusinessLayer.xml</Link>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
using TradingPlatform.BusinessLayer.Chart;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Collections;
|
||||||
|
using TradingPlatform.BusinessLayer.TimeSync;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
public abstract class IndicatorBarBase : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 20)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
public int MinHistoryDepths { get; set; }
|
||||||
|
|
||||||
|
// LineSeries.LineSeries(string, Color, int, LineStyle)'
|
||||||
|
|
||||||
|
protected LineSeries? Series;
|
||||||
|
protected abstract AbstractBarBase QuanTAlib { get; }
|
||||||
|
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => 0;
|
||||||
|
|
||||||
|
protected IndicatorBarBase()
|
||||||
|
{
|
||||||
|
OnBackGround = true;
|
||||||
|
SeparateWindow = false;
|
||||||
|
Series = new(name: $"{Name}", color: Color.RoyalBlue, width: 2, style: LineStyle.Solid);
|
||||||
|
|
||||||
|
AddLineSeries(Series);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void InitIndicator();
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
InitIndicator();
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar bar = new(Time: Time(),
|
||||||
|
Open: GetPrice(PriceType.Open),
|
||||||
|
High: GetPrice(PriceType.High),
|
||||||
|
Low: GetPrice(PriceType.Low),
|
||||||
|
Close: GetPrice(PriceType.Close),
|
||||||
|
Volume: GetPrice(PriceType.Volume),
|
||||||
|
IsNew: args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar);
|
||||||
|
|
||||||
|
TValue result = QuanTAlib.Calc(bar);
|
||||||
|
Series!.SetValue(result.Value);
|
||||||
|
Series!.SetMarker(0, Color.Transparent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
List<Point> allPoints = new List<Point>();
|
||||||
|
if (CurrentChart == null) { return; }
|
||||||
|
|
||||||
|
Graphics gr = args.Graphics;
|
||||||
|
|
||||||
|
var mainWindow = this.CurrentChart.Windows[args.WindowIndex];
|
||||||
|
var converter = mainWindow.CoordinatesConverter;
|
||||||
|
var clientRect = mainWindow.ClientRectangle;
|
||||||
|
|
||||||
|
gr.SetClip(clientRect);
|
||||||
|
DateTime leftTime = new[] { converter.GetTime(clientRect.Left), Time(this.Count - 1) }.Max();
|
||||||
|
DateTime rightTime = new[] { converter.GetTime(clientRect.Right), Time(0) }.Min();
|
||||||
|
|
||||||
|
int leftIndex = (int)HistoricalData.GetIndexByTime(leftTime.Ticks) + 1;
|
||||||
|
int rightIndex = (int)HistoricalData.GetIndexByTime(rightTime.Ticks);
|
||||||
|
|
||||||
|
for (int i = rightIndex; i < leftIndex; i++)
|
||||||
|
{
|
||||||
|
int barX = (int)converter.GetChartX(Time(i));
|
||||||
|
int barY = (int)converter.GetChartY(Series![i]);
|
||||||
|
int halfBarWidth = CurrentChart.BarsWidth / 2;
|
||||||
|
Point point = new Point(barX + halfBarWidth, barY);
|
||||||
|
allPoints.Add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allPoints.Count > 1)
|
||||||
|
{
|
||||||
|
DrawSmoothCombinedCurve(gr, allPoints, this.Count - QuanTAlib.WarmupPeriod - rightIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawSmoothCombinedCurve(Graphics gr, List<Point> allPoints, int hotCount)
|
||||||
|
{
|
||||||
|
if (allPoints.Count < 2) { return; }
|
||||||
|
|
||||||
|
using (Pen defaultPen = new(Series!.Color, Series.Width) { DashStyle = ConvertLineStyleToDashStyle(Series.Style) })
|
||||||
|
using (Pen coldPen = new(Series!.Color, Series.Width) { DashStyle = DashStyle.Dot })
|
||||||
|
{
|
||||||
|
// Draw the hot part
|
||||||
|
if (hotCount > 0)
|
||||||
|
{
|
||||||
|
var hotPoints = allPoints.Take(Math.Min(hotCount + 1, allPoints.Count)).ToArray();
|
||||||
|
gr.DrawCurve(defaultPen, hotPoints, 0, hotPoints.Length - 1, (float)0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the cold part
|
||||||
|
if (ShowColdValues && hotCount < allPoints.Count)
|
||||||
|
{
|
||||||
|
var coldPoints = allPoints.Skip(Math.Max(0, hotCount)).ToArray();
|
||||||
|
gr.DrawCurve(coldPen, coldPoints, 0, coldPoints.Length - 1, (float)0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static DashStyle ConvertLineStyleToDashStyle(LineStyle lineStyle)
|
||||||
|
{
|
||||||
|
return lineStyle switch
|
||||||
|
{
|
||||||
|
LineStyle.Solid => DashStyle.Solid,
|
||||||
|
LineStyle.Dash => DashStyle.Dash,
|
||||||
|
LineStyle.Dot => DashStyle.Dot,
|
||||||
|
LineStyle.DashDot => DashStyle.DashDot,
|
||||||
|
_ => DashStyle.Solid,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
protected static void DrawText(Graphics gr, string text, Rectangle clientRect)
|
||||||
|
{
|
||||||
|
Font font = new Font("Inter", 8);
|
||||||
|
SizeF textSize = gr.MeasureString(text, font);
|
||||||
|
RectangleF textRect = new RectangleF(clientRect.Left + 5,
|
||||||
|
clientRect.Bottom - textSize.Height - 10,
|
||||||
|
textSize.Width + 10, textSize.Height + 10);
|
||||||
|
gr.FillRectangle(SystemBrushes.ControlDarkDark, textRect);
|
||||||
|
gr.DrawString(text, font, Brushes.White, new PointF(textRect.X + 6, textRect.Y + 5));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user