diff --git a/.sonarlint/QuanTAlib.json b/.sonarlint/QuanTAlib.json
deleted file mode 100644
index 482e31c0..00000000
--- a/.sonarlint/QuanTAlib.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "SonarCloudOrganization": "mihakralj",
- "ProjectKey": "mihakralj_QuanTAlib"
-}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..e77d093f
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,13 @@
+{
+ "sonarlint.connectedMode.connections.sonarcloud": [
+ {
+ "organizationKey": "mihakralj",
+ "token": "6df7cd62a17dc4e1c5532df1da2f49d5a977dd50",
+ "connectionId": "mihakralj"
+ }
+ ],
+ "sonarlint.connectedMode.project": {
+ "connectionId": "mihakralj",
+ "projectKey": "mihakralj_QuanTAlib"
+ }
+}
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
index 48962b26..9aa0211e 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -35,6 +35,7 @@
all
runtime; build; native; contentfiles; analyzers
+
diff --git a/QuanTAlib.sln b/QuanTAlib.sln
index 7b1d3247..8727aad2 100644
--- a/QuanTAlib.sln
+++ b/QuanTAlib.sln
@@ -1,57 +1,68 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.0.31903.59
+VisualStudioVersion = 17.5.002.0
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
-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
-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
-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
-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
-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
-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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
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
HideSolutionNode = FALSE
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
- {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
EndGlobal
diff --git a/SyntheticVendor/SyntheticVendor.cs b/SyntheticVendor/SyntheticVendor.cs
index a770055d..03d49548 100644
--- a/SyntheticVendor/SyntheticVendor.cs
+++ b/SyntheticVendor/SyntheticVendor.cs
@@ -540,7 +540,10 @@ namespace SyntheticVendorNamespace
openValue = 0.0001;
closeValue = 100;
}
- else { }
+ else
+ {
+ // No action
+ }
return new HistoryItemBar
{
diff --git a/Tests/test_consistency.cs b/Tests/test_consistency.cs
deleted file mode 100644
index ea6ae40d..00000000
--- a/Tests/test_consistency.cs
+++ /dev/null
@@ -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);
- }
- }
-
-}
diff --git a/Tests/test_iTBar.cs b/Tests/test_iTBar.cs
new file mode 100644
index 00000000..4f21c69a
--- /dev/null
+++ b/Tests/test_iTBar.cs
@@ -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
-
lib\%(RecursiveDir)%(Filename)%(Extension)
diff --git a/quantower/Statistics/Statistics.csproj b/quantower/Statistics/Statistics.csproj
index 36fadba0..262800f0 100644
--- a/quantower/Statistics/Statistics.csproj
+++ b/quantower/Statistics/Statistics.csproj
@@ -8,7 +8,6 @@
-
lib\%(RecursiveDir)%(Filename)%(Extension)
diff --git a/quantower/Statistics/_IndicatorBarBase.cs b/quantower/Statistics/_IndicatorBarBase.cs
new file mode 100644
index 00000000..a5fae449
--- /dev/null
+++ b/quantower/Statistics/_IndicatorBarBase.cs
@@ -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 allPoints = new List();
+ 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 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));
+ }
+}
\ No newline at end of file
diff --git a/quantower/Volatility/AtrIndicator.cs b/quantower/Volatility/AtrIndicator.cs
new file mode 100644
index 00000000..fe1b0738
--- /dev/null
+++ b/quantower/Volatility/AtrIndicator.cs
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/quantower/Volatility/Volatility.csproj b/quantower/Volatility/Volatility.csproj
new file mode 100644
index 00000000..7247b808
--- /dev/null
+++ b/quantower/Volatility/Volatility.csproj
@@ -0,0 +1,29 @@
+
+
+ Indicator
+ bin\$(Configuration)\
+ true
+ true
+ true
+
+
+
+
+ lib\%(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+
+
+
+
+
+ ..\..\.github\TradingPlatform.BusinessLayer.dll
+
+
+ TradingPlatform.BusinessLayer.xml
+
+
+
+
\ No newline at end of file
diff --git a/quantower/Volatility/_IndicatorBarBase.cs b/quantower/Volatility/_IndicatorBarBase.cs
new file mode 100644
index 00000000..a5fae449
--- /dev/null
+++ b/quantower/Volatility/_IndicatorBarBase.cs
@@ -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 allPoints = new List();
+ 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 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));
+ }
+}
\ No newline at end of file