CORR - Pearson's Correlation Coefficient

This commit is contained in:
Miha Kralj
2022-11-15 21:12:03 -08:00
parent 80d82e5863
commit 73b41ac0a0
9 changed files with 1242 additions and 1141 deletions
+356 -356
View File
@@ -1,356 +1,356 @@
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.
## ##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files # User-specific files
*.rsuser *.rsuser
*.suo *.suo
*.user *.user
*.userosscache *.userosscache
*.sln.docstates *.sln.docstates
.vscode/ .vscode/
*.deps.json *.deps.json
.Sandbox/ .Sandbox/
.sonarlint/ .sonarlint/
.DS_Store .DS_Store
# User-specific files (MonoDevelop/Xamarin Studio) # User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs *.userprefs
# Mono auto generated files # Mono auto generated files
mono_crash.* mono_crash.*
# Build results # Build results
[Dd]ebug/ [Dd]ebug/
[Dd]ebugPublic/ [Dd]ebugPublic/
[Rr]elease/ [Rr]elease/
[Rr]eleases/ [Rr]eleases/
x64/ x64/
x86/ x86/
[Aa][Rr][Mm]/ [Aa][Rr][Mm]/
[Aa][Rr][Mm]64/ [Aa][Rr][Mm]64/
bld/ bld/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
[Ll]og/ [Ll]og/
[Ll]ogs/ [Ll]ogs/
# Visual Studio 2015/2017 cache/options directory # Visual Studio 2015/2017 cache/options directory
.vs/ .vs/
# Uncomment if you have tasks that create the project's static files in wwwroot # Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/ #wwwroot/
# Visual Studio 2017 auto generated files # Visual Studio 2017 auto generated files
Generated\ Files/ Generated\ Files/
# MSTest test Results # MSTest test Results
[Tt]est[Rr]esult*/ [Tt]est[Rr]esult*/
[Bb]uild[Ll]og.* [Bb]uild[Ll]og.*
# NUnit # NUnit
*.VisualState.xml *.VisualState.xml
TestResult.xml TestResult.xml
nunit-*.xml nunit-*.xml
# Build Results of an ATL Project # Build Results of an ATL Project
[Dd]ebugPS/ [Dd]ebugPS/
[Rr]eleasePS/ [Rr]eleasePS/
dlldata.c dlldata.c
# Benchmark Results # Benchmark Results
BenchmarkDotNet.Artifacts/ BenchmarkDotNet.Artifacts/
# .NET Core # .NET Core
project.lock.json project.lock.json
project.fragment.lock.json project.fragment.lock.json
artifacts/ artifacts/
# StyleCop # StyleCop
StyleCopReport.xml StyleCopReport.xml
# Files built by Visual Studio # Files built by Visual Studio
*_i.c *_i.c
*_p.c *_p.c
*_h.h *_h.h
*.ilk *.ilk
*.meta *.meta
*.obj *.obj
*.iobj *.iobj
*.pch *.pch
*.pdb *.pdb
*.ipdb *.ipdb
*.pgc *.pgc
*.pgd *.pgd
*.rsp *.rsp
*.sbr *.sbr
*.tlb *.tlb
*.tli *.tli
*.tlh *.tlh
*.tmp *.tmp
*.tmp_proj *.tmp_proj
*_wpftmp.csproj *_wpftmp.csproj
*.log *.log
*.vspscc *.vspscc
*.vssscc *.vssscc
.builds .builds
*.pidb *.pidb
*.svclog *.svclog
*.scc *.scc
# Chutzpah Test files # Chutzpah Test files
_Chutzpah* _Chutzpah*
# Visual C++ cache files # Visual C++ cache files
ipch/ ipch/
*.aps *.aps
*.ncb *.ncb
*.opendb *.opendb
*.opensdf *.opensdf
*.sdf *.sdf
*.cachefile *.cachefile
*.VC.db *.VC.db
*.VC.VC.opendb *.VC.VC.opendb
# Visual Studio profiler # Visual Studio profiler
*.psess *.psess
*.vsp *.vsp
*.vspx *.vspx
*.sap *.sap
# Visual Studio Trace Files # Visual Studio Trace Files
*.e2e *.e2e
# TFS 2012 Local Workspace # TFS 2012 Local Workspace
$tf/ $tf/
# Guidance Automation Toolkit # Guidance Automation Toolkit
*.gpState *.gpState
# ReSharper is a .NET coding add-in # ReSharper is a .NET coding add-in
_ReSharper*/ _ReSharper*/
*.[Rr]e[Ss]harper *.[Rr]e[Ss]harper
*.DotSettings.user *.DotSettings.user
# TeamCity is a build add-in # TeamCity is a build add-in
_TeamCity* _TeamCity*
# DotCover is a Code Coverage Tool # DotCover is a Code Coverage Tool
*.dotCover *.dotCover
# AxoCover is a Code Coverage Tool # AxoCover is a Code Coverage Tool
.axoCover/* .axoCover/*
!.axoCover/settings.json !.axoCover/settings.json
# Visual Studio code coverage results # Visual Studio code coverage results
*.coverage *.coverage
*.coveragexml *.coveragexml
# NCrunch # NCrunch
_NCrunch_* _NCrunch_*
.*crunch*.local.xml .*crunch*.local.xml
nCrunchTemp_* nCrunchTemp_*
# MightyMoose # MightyMoose
*.mm.* *.mm.*
AutoTest.Net/ AutoTest.Net/
# Web workbench (sass) # Web workbench (sass)
.sass-cache/ .sass-cache/
# Installshield output folder # Installshield output folder
[Ee]xpress/ [Ee]xpress/
# DocProject is a documentation generator add-in # DocProject is a documentation generator add-in
DocProject/buildhelp/ DocProject/buildhelp/
DocProject/Help/*.HxT DocProject/Help/*.HxT
DocProject/Help/*.HxC DocProject/Help/*.HxC
DocProject/Help/*.hhc DocProject/Help/*.hhc
DocProject/Help/*.hhk DocProject/Help/*.hhk
DocProject/Help/*.hhp DocProject/Help/*.hhp
DocProject/Help/Html2 DocProject/Help/Html2
DocProject/Help/html DocProject/Help/html
# Click-Once directory # Click-Once directory
publish/ publish/
# Publish Web Output # Publish Web Output
*.[Pp]ublish.xml *.[Pp]ublish.xml
*.azurePubxml *.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings, # Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted # but database connection strings (with potential passwords) will be unencrypted
*.pubxml *.pubxml
*.publishproj *.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to # Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained # checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted # in these scripts will be unencrypted
PublishScripts/ PublishScripts/
# NuGet Packages # NuGet Packages
*.nupkg *.nupkg
# NuGet Symbol Packages # NuGet Symbol Packages
*.snupkg *.snupkg
# The packages folder can be ignored because of Package Restore # The packages folder can be ignored because of Package Restore
**/[Pp]ackages/* **/[Pp]ackages/*
# except build/, which is used as an MSBuild target. # except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/ !**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed # Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config #!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files # NuGet v3's project.json files produces more ignorable files
*.nuget.props *.nuget.props
*.nuget.targets *.nuget.targets
# Microsoft Azure Build Output # Microsoft Azure Build Output
csx/ csx/
*.build.csdef *.build.csdef
# Microsoft Azure Emulator # Microsoft Azure Emulator
ecf/ ecf/
rcf/ rcf/
# Windows Store app package directories and files # Windows Store app package directories and files
AppPackages/ AppPackages/
BundleArtifacts/ BundleArtifacts/
Package.StoreAssociation.xml Package.StoreAssociation.xml
_pkginfo.txt _pkginfo.txt
*.appx *.appx
*.appxbundle *.appxbundle
*.appxupload *.appxupload
# Visual Studio cache files # Visual Studio cache files
# files ending in .cache can be ignored # files ending in .cache can be ignored
*.[Cc]ache *.[Cc]ache
# but keep track of directories ending in .cache # but keep track of directories ending in .cache
!?*.[Cc]ache/ !?*.[Cc]ache/
# Others # Others
ClientBin/ ClientBin/
~$* ~$*
*~ *~
*.dbmdl *.dbmdl
*.dbproj.schemaview *.dbproj.schemaview
*.jfm *.jfm
*.pfx *.pfx
*.publishsettings *.publishsettings
orleans.codegen.cs orleans.codegen.cs
# Including strong name files can present a security risk # Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424) # (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk #*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components # Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/ #bower_components/
# RIA/Silverlight projects # RIA/Silverlight projects
Generated_Code/ Generated_Code/
# Backup & report files from converting an old project file # Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed, # to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-) # because we have git ;-)
_UpgradeReport_Files/ _UpgradeReport_Files/
Backup*/ Backup*/
UpgradeLog*.XML UpgradeLog*.XML
UpgradeLog*.htm UpgradeLog*.htm
ServiceFabricBackup/ ServiceFabricBackup/
*.rptproj.bak *.rptproj.bak
# SQL Server files # SQL Server files
*.mdf *.mdf
*.ldf *.ldf
*.ndf *.ndf
# Business Intelligence projects # Business Intelligence projects
*.rdl.data *.rdl.data
*.bim.layout *.bim.layout
*.bim_*.settings *.bim_*.settings
*.rptproj.rsuser *.rptproj.rsuser
*- [Bb]ackup.rdl *- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl *- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl *- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes # Microsoft Fakes
FakesAssemblies/ FakesAssemblies/
# GhostDoc plugin setting file # GhostDoc plugin setting file
*.GhostDoc.xml *.GhostDoc.xml
# Node.js Tools for Visual Studio # Node.js Tools for Visual Studio
.ntvs_analysis.dat .ntvs_analysis.dat
node_modules/ node_modules/
# Visual Studio 6 build log # Visual Studio 6 build log
*.plg *.plg
# Visual Studio 6 workspace options file # Visual Studio 6 workspace options file
*.opt *.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw *.vbw
# Visual Studio LightSwitch build output # Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts **/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml **/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts **/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml **/*.Server/ModelManifest.xml
_Pvt_Extensions _Pvt_Extensions
# Paket dependency manager # Paket dependency manager
.paket/paket.exe .paket/paket.exe
paket-files/ paket-files/
# FAKE - F# Make # FAKE - F# Make
.fake/ .fake/
# CodeRush personal settings # CodeRush personal settings
.cr/personal .cr/personal
# Python Tools for Visual Studio (PTVS) # Python Tools for Visual Studio (PTVS)
__pycache__/ __pycache__/
*.pyc *.pyc
# Cake - Uncomment if you are using it # Cake - Uncomment if you are using it
# tools/** # tools/**
# !tools/packages.config # !tools/packages.config
# Tabs Studio # Tabs Studio
*.tss *.tss
# Telerik's JustMock configuration file # Telerik's JustMock configuration file
*.jmconfig *.jmconfig
# BizTalk build output # BizTalk build output
*.btp.cs *.btp.cs
*.btm.cs *.btm.cs
*.odx.cs *.odx.cs
*.xsd.cs *.xsd.cs
# OpenCover UI analysis results # OpenCover UI analysis results
OpenCover/ OpenCover/
# Azure Stream Analytics local run output # Azure Stream Analytics local run output
ASALocalRun/ ASALocalRun/
# MSBuild Binary and Structured Log # MSBuild Binary and Structured Log
*.binlog *.binlog
# NVidia Nsight GPU debugger configuration file # NVidia Nsight GPU debugger configuration file
*.nvuser *.nvuser
# MFractors (Xamarin productivity tool) working folder # MFractors (Xamarin productivity tool) working folder
.mfractor/ .mfractor/
# Local History for Visual Studio # Local History for Visual Studio
.localhistory/ .localhistory/
# BeatPulse healthcheck temp database # BeatPulse healthcheck temp database
healthchecksdb healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017 # Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder # Ionide (cross platform F# VS Code tools) working folder
.ionide/ .ionide/
dotCover.Output.dcvr dotCover.Output.dcvr
+15 -2
View File
@@ -2,13 +2,13 @@
using System; using System;
/* <summary> /* <summary>
Abstract classes with all scaffolding required to build indicators. Abstract classes with all scaffolding required to build indicators.
All abstracts support period, NaN, and all permutations of Add() methods. All abstracts support period, NaN, and all permutations of Add() methods.
Indicator classess need to implement: Indicator classess need to implement:
- Chaining constructor (Abstract's constructor executes first) - Chaining constructor (Abstract's constructor executes first)
- Default Add(value) class - Default Add(value) class
- optional Add(series) bulk insert class (for optimization of historical analysis) - optional Add(series) bulk insert class (for optimization of historical analysis)
Single_TSeries_Indicator - one single-value TSeries in, one TSeries out. Single_TSeries_Indicator - one single-value TSeries in, one TSeries out.
Pair_TSeries_Indicator - Two TSeries in, one TSeries out. (includes simple semaphoring) Pair_TSeries_Indicator - Two TSeries in, one TSeries out. (includes simple semaphoring)
Single_TBars_Indicator - One OHLCV TBars in, one TSeries out. Single_TBars_Indicator - One OHLCV TBars in, one TSeries out.
@@ -42,11 +42,24 @@ public abstract class Single_TSeries_Indicator : TSeries
public abstract class Pair_TSeries_Indicator : TSeries public abstract class Pair_TSeries_Indicator : TSeries
{ {
protected readonly int _p;
protected readonly bool _NaN;
protected readonly TSeries _d1; protected readonly TSeries _d1;
protected readonly TSeries _d2; protected readonly TSeries _d2;
protected readonly double _dd1, _dd2; protected readonly double _dd1, _dd2;
// Chainable Constructors - add them at the end of primary constructors if needed // Chainable Constructors - add them at the end of primary constructors if needed
protected Pair_TSeries_Indicator(TSeries source1, TSeries source2, int period, bool useNaN)
{
this._p = period;
this._NaN = useNaN;
this._d1 = source1;
this._d2 = source2;
this._dd1 = double.NaN;
this._dd2 = double.NaN;
this._d1.Pub += this.Sub;
this._d2.Pub += this.Sub;
}
protected Pair_TSeries_Indicator(TSeries source1, TSeries source2) protected Pair_TSeries_Indicator(TSeries source1, TSeries source2)
{ {
this._d1 = source1; this._d1 = source1;
+46 -46
View File
@@ -1,47 +1,47 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
using System.Text.Json; using System.Text.Json;
/* <summary> /* <summary>
Yahoo Finance - Free API feed to collect daily market quotes Yahoo Finance - Free API feed to collect daily market quotes
Parameters: Parameters:
Symbol: stock symbol (default: "IBM") Symbol: stock symbol (default: "IBM")
Period: number of days of collected history (default: 252) Period: number of days of collected history (default: 252)
Usage: Usage:
Yahoo_Feed ticker = new("MSFT", 20) Yahoo_Feed ticker = new("MSFT", 20)
</summary> */ </summary> */
public class Yahoo_Feed : TBars public class Yahoo_Feed : TBars
{ {
public Yahoo_Feed(string Symbol = "IBM", int Period = 252) { public Yahoo_Feed(string Symbol = "IBM", int Period = 252) {
string requestUrl = "https://query1.finance.yahoo.com/v8/finance/chart/"+ string requestUrl = "https://query1.finance.yahoo.com/v8/finance/chart/"+
Symbol+"?interval=1d&period1="+ Symbol+"?interval=1d&period1="+
(int)new DateTimeOffset(DateTime.UtcNow.AddDays(-Period+1)).ToUnixTimeSeconds()+"&period2="+ (int)new DateTimeOffset(DateTime.UtcNow.AddDays(-Period+1)).ToUnixTimeSeconds()+"&period2="+
(int)new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds(); (int)new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
System.Net.Http.HttpClient client = new(); System.Net.Http.HttpClient client = new();
var msg = client.GetStringAsync(requestUrl).Result; var msg = client.GetStringAsync(requestUrl).Result;
var jresult = JsonSerializer.Deserialize<JsonDocument>(msg).RootElement; var jresult = JsonSerializer.Deserialize<JsonDocument>(msg).RootElement;
jresult.TryGetProperty("chart",out JsonElement json); jresult.TryGetProperty("chart",out JsonElement json);
json.TryGetProperty("result",out json); json.TryGetProperty("result",out json);
json[0].TryGetProperty("timestamp",out JsonElement datetime); json[0].TryGetProperty("timestamp",out JsonElement datetime);
json[0].TryGetProperty("indicators",out json); json[0].TryGetProperty("indicators",out json);
json.TryGetProperty("quote",out json); json.TryGetProperty("quote",out json);
json[0].TryGetProperty("open",out JsonElement open); json[0].TryGetProperty("open",out JsonElement open);
json[0].TryGetProperty("high",out JsonElement high); json[0].TryGetProperty("high",out JsonElement high);
json[0].TryGetProperty("low",out JsonElement low); json[0].TryGetProperty("low",out JsonElement low);
json[0].TryGetProperty("close",out JsonElement close); json[0].TryGetProperty("close",out JsonElement close);
json[0].TryGetProperty("volume",out JsonElement volume); json[0].TryGetProperty("volume",out JsonElement volume);
for (int i=0; i<datetime.GetArrayLength(); i++) { for (int i=0; i<datetime.GetArrayLength(); i++) {
DateTime d = DateTimeOffset.FromUnixTimeSeconds(long.Parse(datetime[i].GetRawText())).DateTime; DateTime d = DateTimeOffset.FromUnixTimeSeconds(long.Parse(datetime[i].GetRawText())).DateTime;
double o = Math.Round(double.Parse(open[i].GetRawText()),3); double o = Math.Round(double.Parse(open[i].GetRawText()),3);
double h = Math.Round(double.Parse(high[i].GetRawText()),3); double h = Math.Round(double.Parse(high[i].GetRawText()),3);
double l = Math.Round(double.Parse(low[i].GetRawText()),3); double l = Math.Round(double.Parse(low[i].GetRawText()),3);
double c = Math.Round(double.Parse(close[i].GetRawText()),3); double c = Math.Round(double.Parse(close[i].GetRawText()),3);
double v = Math.Round(double.Parse(volume[i].GetRawText()),3); double v = Math.Round(double.Parse(volume[i].GetRawText()),3);
base.Add(d, o, h, l, c, v); base.Add(d, o, h, l, c, v);
} }
} }
} }
+70
View File
@@ -0,0 +1,70 @@
namespace QuanTAlib;
using System;
/* <summary>
CORR: Pearson's Correlation Coefficient
PCC is a measure of linear correlation between two sets of data.
It is the ratio between the covariance of two variables and the product of
their standard deviations; it is essentially a normalized measurement of
the covariance, such that the result always has a value between 1 and 1.
Sources:
https://en.wikipedia.org/wiki/Pearson_correlation_coefficient
</summary> */
public class CORR_Series : Pair_TSeries_Indicator
{
public CORR_Series(TSeries d1, TSeries d2, int period, bool useNaN = false) : base(d1, d2, period, useNaN)
{
if (base._d1.Count > 0 && base._d2.Count > 0) { for (int i = 0; i < base._d1.Count; i++) { this.Add(base._d1[i], base._d2[i], false); } }
}
private readonly System.Collections.Generic.List<double> _x = new();
private readonly System.Collections.Generic.List<double> _xx = new();
private readonly System.Collections.Generic.List<double> _y = new();
private readonly System.Collections.Generic.List<double> _yy = new();
private readonly System.Collections.Generic.List<double> _xy = new();
public override void Add((System.DateTime t, double v) TValue1, (System.DateTime t, double v) TValue2, bool update)
{
if (update)
{
_x[_x.Count - 1] = TValue1.v;
_xx[_xx.Count - 1] = TValue1.v * TValue1.v;
_y[_y.Count - 1] = TValue2.v;
_y[_yy.Count - 1] = TValue2.v * TValue2.v;
_xy[_xy.Count - 1] = TValue1.v * TValue2.v;
}
else
{
_x.Add(TValue1.v);
_xx.Add(TValue1.v * TValue1.v);
_y.Add(TValue2.v);
_yy.Add(TValue2.v * TValue2.v);
_xy.Add(TValue1.v * TValue2.v);
}
if (_x.Count > this._p) { _x.RemoveAt(0); }
if (_xx.Count > this._p) { _xx.RemoveAt(0); }
if (_y.Count > this._p) { _y.RemoveAt(0); }
if (_yy.Count > this._p) { _yy.RemoveAt(0); }
if (_xy.Count > this._p) { _xy.RemoveAt(0); }
double _sumx = 0;
for (int i = 0; i < _x.Count; i++) { _sumx += _x[i]; }
double _sumxx = 0;
for (int i = 0; i < _xx.Count; i++) { _sumxx += _xx[i]; }
double _sumy = 0;
for (int i = 0; i < _y.Count; i++) { _sumy += _y[i]; }
double _sumyy = 0;
for (int i = 0; i < _yy.Count; i++) { _sumyy += _yy[i]; }
double _sumxy = 0;
for (int i = 0; i < _xy.Count; i++) { _sumxy += _xy[i]; }
double _div = (_sumxx - _sumx * _sumx / _p) * (_sumyy - _sumy * _sumy / _p);
double _cor = (_div != 0) ? (_sumxy - _sumx * _sumy / _p) / Math.Sqrt(_div) : 0.0;
var result = (TValue1.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _cor);
if (update) { base[base.Count - 1] = result; } else { base.Add(result); }
}
}
+92 -92
View File
@@ -1,93 +1,93 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
/* <summary> /* <summary>
LINREG: Linear Regression (using Least Square Method) LINREG: Linear Regression (using Least Square Method)
Linear Regression provides a slope of a straight line that is the best approximation of the given set of data. Linear Regression provides a slope of a straight line that is the best approximation of the given set of data.
The method of least squares is a standard approach in linear regression analysis to approximate the solution The method of least squares is a standard approach in linear regression analysis to approximate the solution
by minimizing the sum of the squares of the residuals made in the results of each individual equation. by minimizing the sum of the squares of the residuals made in the results of each individual equation.
Additional outputs provided by LINREG: Additional outputs provided by LINREG:
.Intercept - y-intercept point of the best fit line .Intercept - y-intercept point of the best fit line
.RSquared - R-Squared (R²), Coefficient of Determination .RSquared - R-Squared (R²), Coefficient of Determination
.StdDev - Standard Deviation of data over given periods .StdDev - Standard Deviation of data over given periods
y = Slope * x + Intercept y = Slope * x + Intercept
Sources: Sources:
https://en.wikipedia.org/wiki/Least_squares https://en.wikipedia.org/wiki/Least_squares
</summary> */ </summary> */
public class LINREG_Series : Single_TSeries_Indicator public class LINREG_Series : Single_TSeries_Indicator
{ {
public readonly TSeries Intercept = new(); public readonly TSeries Intercept = new();
public readonly TSeries RSquared = new(); public readonly TSeries RSquared = new();
public readonly TSeries StdDev = new(); public readonly TSeries StdDev = new();
private readonly System.Collections.Generic.List<double> _buffer = new(); private readonly System.Collections.Generic.List<double> _buffer = new();
public LINREG_Series(TSeries source, int period, bool useNaN = false) public LINREG_Series(TSeries source, int period, bool useNaN = false)
: base(source, period, useNaN) : base(source, period, useNaN)
{ {
if (this._data.Count > 0) { base.Add(this._data); } if (this._data.Count > 0) { base.Add(this._data); }
} }
public override void Add((System.DateTime t, double v) TValue, bool update) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); } else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); } if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }
int _len = this._buffer.Count; int _len = this._buffer.Count;
// get averages for period // get averages for period
double sumX = 0; double sumX = 0;
double sumY = 0; double sumY = 0;
for (int p = 0; p < _len; p++) for (int p = 0; p < _len; p++)
{ {
sumX += this.Count - _len + 2 + p; sumX += this.Count - _len + 2 + p;
sumY += _buffer[p]; sumY += _buffer[p];
} }
double avgX = sumX / _len; double avgX = sumX / _len;
double avgY = sumY / _len; double avgY = sumY / _len;
// least squares method // least squares method
double sumSqX = 0; double sumSqX = 0;
double sumSqY = 0; double sumSqY = 0;
double sumSqXY = 0; double sumSqXY = 0;
for (int p = 0; p < _len; p++) for (int p = 0; p < _len; p++)
{ {
double devX = this.Count - _len + 2 + p - avgX; double devX = this.Count - _len + 2 + p - avgX;
double devY = _buffer[p] - avgY; double devY = _buffer[p] - avgY;
sumSqX += devX * devX; sumSqX += devX * devX;
sumSqY += devY * devY; sumSqY += devY * devY;
sumSqXY += devX * devY; sumSqXY += devX * devY;
} }
double _slope = sumSqXY / sumSqX; double _slope = sumSqXY / sumSqX;
double _intercept = avgY - (_slope * avgX); double _intercept = avgY - (_slope * avgX);
// calculate Standard Deviation and R-Squared // calculate Standard Deviation and R-Squared
double stdDevX = Math.Sqrt(sumSqX / _len); double stdDevX = Math.Sqrt(sumSqX / _len);
double stdDevY = Math.Sqrt(sumSqY / _len); double stdDevY = Math.Sqrt(sumSqY / _len);
double _StdDev = stdDevY; double _StdDev = stdDevY;
double arrr = (stdDevX * stdDevY != 0) ? sumSqXY / (stdDevX * stdDevY) / _len : 0; double arrr = (stdDevX * stdDevY != 0) ? sumSqXY / (stdDevX * stdDevY) / _len : 0;
double _RSquared = arrr * arrr; double _RSquared = arrr * arrr;
var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _slope); var ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _slope);
base.Add(ret, update); base.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _intercept); ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _intercept);
Intercept.Add(ret, update); Intercept.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _StdDev); ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _StdDev);
StdDev.Add(ret, update); StdDev.Add(ret, update);
ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _RSquared); ret = (TValue.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _RSquared);
RSquared.Add(ret, update); RSquared.Add(ret, update);
} }
} }
+50 -50
View File
@@ -1,51 +1,51 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
/* <summary> /* <summary>
ZSCORE: number of standard deviations from SMA ZSCORE: number of standard deviations from SMA
Z-score describes a value's relationship to the mean of a series, as measured in Z-score describes a value's relationship to the mean of a series, as measured in
terms of standard deviations from the mean. If a Z-score is 0, it indicates that terms of standard deviations from the mean. If a Z-score is 0, it indicates that
the data point's score is identical to the mean score. A Z-score of 1.0 would the data point's score is identical to the mean score. A Z-score of 1.0 would
indicate a value that is one standard deviation from the mean. Z-scores may be indicate a value that is one standard deviation from the mean. Z-scores may be
positive or negative, with a positive value indicating the score is above the positive or negative, with a positive value indicating the score is above the
mean and a negative score indicating it is below the mean. mean and a negative score indicating it is below the mean.
Sources: Sources:
https://en.wikipedia.org/wiki/Z-score https://en.wikipedia.org/wiki/Z-score
https://www.investopedia.com/terms/z/zscore.asp https://www.investopedia.com/terms/z/zscore.asp
Calculation: Calculation:
std = std * STDEV(close, length) std = std * STDEV(close, length)
mean = SMA(close, length) mean = SMA(close, length)
ZSCORE = (close - mean) / std ZSCORE = (close - mean) / std
</summary> */ </summary> */
public class ZSCORE_Series : Single_TSeries_Indicator public class ZSCORE_Series : Single_TSeries_Indicator
{ {
public ZSCORE_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN) public ZSCORE_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{ {
if (base._data.Count > 0) { base.Add(base._data); } if (base._data.Count > 0) { base.Add(base._data); }
} }
private readonly System.Collections.Generic.List<double> _buffer = new(); private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { _buffer[_buffer.Count - 1] = TValue.v; } if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); } else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); } if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0; double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; } for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count; _sma /= this._buffer.Count;
double _pvar = 0; double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); } for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count; _pvar /= this._buffer.Count;
double _psdev = Math.Sqrt(_pvar); double _psdev = Math.Sqrt(_pvar);
double _zscore = (_psdev == 0) ? double.NaN : (TValue.v - _sma) / _psdev; double _zscore = (_psdev == 0) ? double.NaN : (TValue.v - _sma) / _psdev;
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _zscore); var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _zscore);
base.Add(result, update); base.Add(result, update);
} }
} }
+301 -292
View File
@@ -5,296 +5,305 @@ using Xunit;
namespace Validations; namespace Validations;
public class Skender_Stock public class Skender_Stock
{ {
private readonly GBM_Feed bars; private readonly GBM_Feed bars;
private readonly Random rnd = new(); private readonly Random rnd = new();
private readonly int period; private readonly int period;
private readonly IEnumerable<Quote> quotes; private readonly IEnumerable<Quote> quotes;
public Skender_Stock() public Skender_Stock()
{ {
bars = new(Bars: 5000, Volatility: 0.7, Drift: 0.0); bars = new(Bars: 5000, Volatility: 0.7, Drift: 0.0);
period = rnd.Next(28) + 3; period = rnd.Next(28) + 3;
quotes = bars.Select( quotes = bars.Select(
q => new Quote q => new Quote
{ {
Date = q.t, Date = q.t,
Open = (decimal)q.o, Open = (decimal)q.o,
High = (decimal)q.h, High = (decimal)q.h,
Low = (decimal)q.l, Low = (decimal)q.l,
Close = (decimal)q.c, Close = (decimal)q.c,
Volume = (decimal)q.v Volume = (decimal)q.v
}); });
} }
[Fact] [Fact]
public void SMA() public void SMA()
{ {
SMA_Series QL = new(bars.Close, period, false); SMA_Series QL = new(bars.Close, period, false);
var SK = quotes.GetSma(period); var SK = quotes.GetSma(period);
Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void EMA() public void EMA()
{ {
EMA_Series QL = new(bars.Close, period, false); EMA_Series QL = new(bars.Close, period, false);
var SK = quotes.GetEma(period); var SK = quotes.GetEma(period);
Assert.Equal(Math.Round((double)SK.Last().Ema!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Ema!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void WMA() public void WMA()
{ {
WMA_Series QL = new(bars.Close, period, false); WMA_Series QL = new(bars.Close, period, false);
var SK = quotes.GetWma(period); var SK = quotes.GetWma(period);
Assert.Equal(Math.Round((double)SK.Last().Wma!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Wma!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void DEMA() public void DEMA()
{ {
DEMA_Series QL = new(bars.Close, period, false); DEMA_Series QL = new(bars.Close, period, false);
var SK = quotes.GetDema(period); var SK = quotes.GetDema(period);
Assert.Equal(Math.Round((double)SK.Last().Dema!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Dema!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void TEMA() public void TEMA()
{ {
TEMA_Series QL = new(bars.Close, period, false); TEMA_Series QL = new(bars.Close, period, false);
var SK = quotes.GetTema(period); var SK = quotes.GetTema(period);
Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Tema!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void MAD() public void MAD()
{ {
MAD_Series QL = new(bars.Close, period, false); MAD_Series QL = new(bars.Close, period, false);
var SK = quotes.GetSmaAnalysis(period); var SK = quotes.GetSmaAnalysis(period);
Assert.Equal(Math.Round((double)SK.Last().Mad!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Mad!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void MSE() public void MSE()
{ {
MSE_Series QL = new(bars.Close, period, false); MSE_Series QL = new(bars.Close, period, false);
var SK = quotes.GetSmaAnalysis(period); var SK = quotes.GetSmaAnalysis(period);
Assert.Equal(Math.Round((double)SK.Last().Mse!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Mse!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void MAPE() public void MAPE()
{ {
MAPE_Series QL = new(bars.Close, period, false); MAPE_Series QL = new(bars.Close, period, false);
var SK = quotes.GetSmaAnalysis(period); var SK = quotes.GetSmaAnalysis(period);
Assert.Equal(Math.Round((double)SK.Last().Mape!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Mape!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void ATR() public void CORR()
{ {
ATR_Series QL = new(bars, period, false); CORR_Series QL = new(bars.High, bars.Low, period, false);
var SK = quotes.GetAtr(period); var SK = quotes.Use(CandlePart.High).GetCorrelation(quotes.Use(CandlePart.Low), period);
Assert.Equal(Math.Round((double)SK.Last().Atr!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Correlation!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void OBV() public void ATR()
{ {
OBV_Series QL = new(bars, period, false); ATR_Series QL = new(bars, period, false);
var SK = quotes.GetObv(period); var SK = quotes.GetAtr(period);
// adding volume[0] to OBV to pass the test and keep compatibility with TA-LIB Assert.Equal(Math.Round((double)SK.Last().Atr!, 6), Math.Round(QL.Last().v, 6));
Assert.Equal(Math.Round(SK.Last().Obv! + (double)quotes.First().Volume!, 5), }
Math.Round(QL.Last().v, 5));
} [Fact]
public void OBV()
[Fact] {
public void ADL() OBV_Series QL = new(bars, period, false);
{ var SK = quotes.GetObv(period);
ADL_Series QL = new(bars, false);
var SK = quotes.GetAdl(); // adding volume[0] to OBV to pass the test and keep compatibility with TA-LIB
Assert.Equal(Math.Round(SK.Last().Obv! + (double)quotes.First().Volume!, 5),
Assert.Equal(Math.Round(SK.Last().Adl!, 5), Math.Round(QL.Last().v, 5)); Math.Round(QL.Last().v, 5));
} }
[Fact] [Fact]
public void CCI() public void ADL()
{ {
CCI_Series QL = new(bars, period, false); ADL_Series QL = new(bars, false);
var SK = quotes.GetCci(period); var SK = quotes.GetAdl();
Assert.Equal(Math.Round((double)SK.Last().Cci!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round(SK.Last().Adl!, 5), Math.Round(QL.Last().v, 5));
} }
[Fact] [Fact]
public void ATRP() public void CCI()
{ {
ATRP_Series QL = new(bars, period, false); CCI_Series QL = new(bars, period, false);
var SK = quotes.GetAtr(period); var SK = quotes.GetCci(period);
Assert.Equal(Math.Round((double)SK.Last().Atrp!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Cci!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void KAMA() public void ATRP()
{ {
KAMA_Series QL = new(bars.Close, period, useNaN: false); ATRP_Series QL = new(bars, period, false);
var SK = quotes.GetKama(period); var SK = quotes.GetAtr(period);
Assert.Equal(Math.Round((double)SK.Last().Kama!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Atrp!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void HMA() public void KAMA()
{ {
HMA_Series QL = new(bars.Close, period, useNaN: false); KAMA_Series QL = new(bars.Close, period, useNaN: false);
var SK = quotes.GetHma(period); var SK = quotes.GetKama(period);
Assert.Equal(Math.Round((double)SK.Last().Hma!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Kama!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void SMMA() public void HMA()
{ {
SMMA_Series QL = new(bars.Close, period, useNaN: false); HMA_Series QL = new(bars.Close, period, useNaN: false);
var SK = quotes.GetSmma(period); var SK = quotes.GetHma(period);
Assert.Equal(Math.Round((double)SK.Last().Smma!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Hma!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void MACD() public void SMMA()
{ {
MACD_Series QL = new(bars.Close, 26, 12, 9, useNaN: false); SMMA_Series QL = new(bars.Close, period, useNaN: false);
var SK = quotes.GetMacd(12, 26, 9); var SK = quotes.GetSmma(period);
Assert.Equal(Math.Round((double)SK.Last().Macd!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Smma!, 6), Math.Round(QL.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().Signal!, 6), Math.Round(QL.Signal.Last().v, 6)); }
}
[Fact]
[Fact] public void MACD()
public void BBANDS() {
{ MACD_Series QL = new(bars.Close, 26, 12, 9, useNaN: false);
BBANDS_Series QL = new(bars.Close, period, 2.0, useNaN: false); var SK = quotes.GetMacd(12, 26, 9);
var SK = quotes.GetBollingerBands(period, 2.0);
Assert.Equal(Math.Round((double)SK.Last().Macd!, 6), Math.Round(QL.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Mid.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Signal!, 6), Math.Round(QL.Signal.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().UpperBand!, 6), Math.Round(QL.Upper.Last().v, 6)); }
Assert.Equal(Math.Round((double)SK.Last().LowerBand!, 6), Math.Round(QL.Lower.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().Width!, 6), Math.Round(QL.Bandwidth.Last().v, 6)); [Fact]
Assert.Equal(Math.Round((double)SK.Last().PercentB!, 6), Math.Round(QL.PercentB.Last().v, 6)); public void BBANDS()
Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Zscore.Last().v, 6)); {
} BBANDS_Series QL = new(bars.Close, period, 2.0, useNaN: false);
var SK = quotes.GetBollingerBands(period, 2.0);
[Fact]
public void RSI() Assert.Equal(Math.Round((double)SK.Last().Sma!, 6), Math.Round(QL.Mid.Last().v, 6));
{ Assert.Equal(Math.Round((double)SK.Last().UpperBand!, 6), Math.Round(QL.Upper.Last().v, 6));
RSI_Series QL = new(bars.Close, period, useNaN: false); Assert.Equal(Math.Round((double)SK.Last().LowerBand!, 6), Math.Round(QL.Lower.Last().v, 6));
var SK = quotes.GetRsi(period); Assert.Equal(Math.Round((double)SK.Last().Width!, 6), Math.Round(QL.Bandwidth.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().PercentB!, 6), Math.Round(QL.PercentB.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().Rsi!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Zscore.Last().v, 6));
} }
[Fact] [Fact]
public void ALMA() public void RSI()
{ {
ALMA_Series QL = new(bars.Close, period, useNaN: false); RSI_Series QL = new(bars.Close, period, useNaN: false);
var SK = quotes.GetAlma(period); var SK = quotes.GetRsi(period);
Assert.Equal(Math.Round((double)SK.Last().Alma!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Rsi!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void SDEV() public void ALMA()
{ {
SDEV_Series QL = new(bars.Close, period, useNaN: false); ALMA_Series QL = new(bars.Close, period, useNaN: false);
var SK = quotes.GetStdDev(period); var SK = quotes.GetAlma(period);
Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Alma!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void ZSCORE() public void SDEV()
{ {
ZSCORE_Series QL = new(bars.Close, period, useNaN: false); SDEV_Series QL = new(bars.Close, period, useNaN: false);
var SK = quotes.GetStdDev(period); var SK = quotes.GetStdDev(period);
Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void LINREG() public void ZSCORE()
{ {
LINREG_Series QL = new(bars.Close, period, useNaN: false); ZSCORE_Series QL = new(bars.Close, period, useNaN: false);
var SK = quotes.GetSlope(period); var SK = quotes.GetStdDev(period);
Assert.Equal(Math.Round((double)SK.Last().Slope!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().ZScore!, 6), Math.Round(QL.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().Intercept!, 6), Math.Round(QL.Intercept.Last().v, 6)); }
Assert.Equal(Math.Round((double)SK.Last().RSquared!, 6), Math.Round(QL.RSquared.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.StdDev.Last().v, 6)); [Fact]
} public void LINREG()
{
[Fact] LINREG_Series QL = new(bars.Close, period, useNaN: false);
public void TR() var SK = quotes.GetSlope(period);
{
TR_Series QL = new(bars, useNaN: false); Assert.Equal(Math.Round((double)SK.Last().Slope!, 6), Math.Round(QL.Last().v, 6));
var SK = quotes.GetTr(); Assert.Equal(Math.Round((double)SK.Last().Intercept!, 6), Math.Round(QL.Intercept.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().RSquared!, 6), Math.Round(QL.RSquared.Last().v, 6));
Assert.Equal(Math.Round((double)SK.Last().Tr!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().StdDev!, 6), Math.Round(QL.StdDev.Last().v, 6));
} }
[Fact] [Fact]
public void HL2() public void TR()
{ {
TSeries QL = bars.HL2; TR_Series QL = new(bars, useNaN: false);
var SK = quotes.GetBaseQuote(CandlePart.HL2); var SK = quotes.GetTr();
Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round((double)SK.Last().Tr!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void OC2() public void HL2()
{ {
TSeries QL = bars.OC2; TSeries QL = bars.HL2;
var SK = quotes.GetBaseQuote(CandlePart.OC2); var SK = quotes.GetBaseQuote(CandlePart.HL2);
Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void HLC3() public void OC2()
{ {
TSeries QL = bars.HLC3; TSeries QL = bars.OC2;
var SK = quotes.GetBaseQuote(CandlePart.HLC3); var SK = quotes.GetBaseQuote(CandlePart.OC2);
Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void OHL3() public void HLC3()
{ {
TSeries QL = bars.OHL3; TSeries QL = bars.HLC3;
var SK = quotes.GetBaseQuote(CandlePart.OHL3); var SK = quotes.GetBaseQuote(CandlePart.HLC3);
Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact] [Fact]
public void OHLC4() public void OHL3()
{ {
TSeries QL = bars.OHLC4; TSeries QL = bars.OHL3;
var SK = quotes.GetBaseQuote(CandlePart.OHLC4); var SK = quotes.GetBaseQuote(CandlePart.OHL3);
Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6)); Assert.Equal(Math.Round(SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
} }
[Fact]
public void OHLC4()
{
TSeries QL = bars.OHLC4;
var SK = quotes.GetBaseQuote(CandlePart.OHLC4);
Assert.Equal(Math.Round((double)SK.Last().Value!, 6), Math.Round(QL.Last().v, 6));
}
} }
+310 -301
View File
@@ -5,305 +5,314 @@ using QuanTAlib;
namespace Validations; namespace Validations;
public class TA_LIB public class TA_LIB
{ {
private readonly GBM_Feed bars; private readonly GBM_Feed bars;
private readonly Random rnd = new(); private readonly Random rnd = new();
private readonly int period; private readonly int period;
private readonly double[] TALIB; private readonly double[] TALIB;
private readonly double[] inopen; private readonly double[] inopen;
private readonly double[] inhigh; private readonly double[] inhigh;
private readonly double[] inlow; private readonly double[] inlow;
private readonly double[] inclose; private readonly double[] inclose;
private readonly double[] involume; private readonly double[] involume;
public TA_LIB() public TA_LIB()
{ {
bars = new(5000); bars = new(5000);
period = rnd.Next(28) + 3; period = rnd.Next(28) + 3;
TALIB = new double[bars.Count]; TALIB = new double[bars.Count];
inopen = bars.Open.v.ToArray(); inopen = bars.Open.v.ToArray();
inhigh = bars.High.v.ToArray(); inhigh = bars.High.v.ToArray();
inlow = bars.Low.v.ToArray(); inlow = bars.Low.v.ToArray();
inclose = bars.Close.v.ToArray(); inclose = bars.Close.v.ToArray();
involume = bars.Volume.v.ToArray(); involume = bars.Volume.v.ToArray();
} }
///////////////////////////////////////// /////////////////////////////////////////
[Fact] [Fact]
public void ADD() public void ADD()
{ {
ADD_Series QL = new(bars.Open, bars.Close); ADD_Series QL = new(bars.Open, bars.Close);
Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void SUB() public void SUB()
{ {
SUB_Series QL = new(bars.Open, bars.Close); SUB_Series QL = new(bars.Open, bars.Close);
Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void MUL() public void MUL()
{ {
MUL_Series QL = new(bars.Open, bars.Close); MUL_Series QL = new(bars.Open, bars.Close);
Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void DIV() public void DIV()
{ {
DIV_Series QL = new(bars.Open, bars.Close); DIV_Series QL = new(bars.Open, bars.Close);
Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void SDEV() public void CORR()
{ {
SDEV_Series QL = new(bars.Close, period, false); CORR_Series QL = new(bars.Open, bars.Close, period);
Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void SMA() public void SDEV()
{ {
SMA_Series QL = new(bars.Close, period, false); SDEV_Series QL = new(bars.Close, period, false);
Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void SUM() public void SMA()
{ {
SUM_Series QL = new(bars.Close, period, false); SMA_Series QL = new(bars.Close, period, false);
Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void MIDPRICE() public void SUM()
{ {
MIDPRICE_Series QL = new(bars, period, false); SUM_Series QL = new(bars.Close, period, false);
Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact]
[Fact] public void MIDPRICE()
public void VAR() {
{ MIDPRICE_Series QL = new(bars, period, false);
VAR_Series QL = new(bars.Close, period, false); Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 5, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 5)); }
}
[Fact] [Fact]
public void MIDPOINT() public void VAR()
{ {
MIDPOINT_Series QL = new(bars.Close, period, false); VAR_Series QL = new(bars.Close, period, false);
Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 5, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 5));
} }
[Fact] [Fact]
public void TRIMA() public void MIDPOINT()
{ {
TRIMA_Series QL = new(bars.Close, period, false); MIDPOINT_Series QL = new(bars.Close, period, false);
Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void EMA() public void TRIMA()
{ {
EMA_Series QL = new(bars.Close, period, false); TRIMA_Series QL = new(bars.Close, period, false);
Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void WMA() public void EMA()
{ {
WMA_Series QL = new(bars.Close, period, false); EMA_Series QL = new(bars.Close, period, false);
Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void DEMA() public void WMA()
{ {
DEMA_Series QL = new(bars.Close, period, false); WMA_Series QL = new(bars.Close, period, false);
Core.Dema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void TEMA() public void DEMA()
{ {
TEMA_Series QL = new(bars.Close, period, false); DEMA_Series QL = new(bars.Close, period, false);
Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Dema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void MAX() public void TEMA()
{ {
MAX_Series QL = new(bars.Close, period, false); TEMA_Series QL = new(bars.Close, period, false);
Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void MIN() public void MAX()
{ {
MIN_Series QL = new(bars.Close, period, false); MAX_Series QL = new(bars.Close, period, false);
Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void ADL() public void MIN()
{ {
ADL_Series QL = new(bars, false); MIN_Series QL = new(bars.Close, period, false);
Core.Ad(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void OBV() public void ADL()
{ {
OBV_Series QL = new(bars, period, false); ADL_Series QL = new(bars, false);
Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Ad(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void ADOSC() public void OBV()
{ {
ADOSC_Series QL = new(bars, false); OBV_Series QL = new(bars, period, false);
Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void ATR() public void ADOSC()
{ {
ATR_Series QL = new(bars, period, false); ADOSC_Series QL = new(bars, false);
Core.Atr(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void CCI() public void ATR()
{ {
CCI_Series QL = new(bars, period, false); ATR_Series QL = new(bars, period, false);
Core.Cci(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Atr(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void RSI() public void CCI()
{ {
RSI_Series QL = new(bars.Close, period, false); CCI_Series QL = new(bars, period, false);
Core.Rsi(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period); Core.Cci(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void TR() public void RSI()
{ {
TR_Series QL = new(bars, false); RSI_Series QL = new(bars.Close, period, false);
Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.Rsi(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void MACD() public void TR()
{ {
double[] macdSignal = new double[bars.Count]; TR_Series QL = new(bars, false);
double[] macdHist = new double[bars.Count]; Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
Core.Macd(inclose, 0, bars.Count - 1, outMacd: TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); }
Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Signal.Last().v, 6, MidpointRounding.AwayFromZero));
} [Fact]
public void MACD()
[Fact] {
public void BBANDS() double[] macdSignal = new double[bars.Count];
{ double[] macdHist = new double[bars.Count];
double[] outMiddle = new double[bars.Count]; MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
double[] outUpper = new double[bars.Count]; Core.Macd(inclose, 0, bars.Count - 1, outMacd: TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
double[] outLower = new double[bars.Count]; Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
BBANDS_Series QL = new(bars.Close, period: 26, multiplier: 2.0, false); Assert.Equal(Math.Round(macdSignal[macdSignal.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Signal.Last().v, 6, MidpointRounding.AwayFromZero));
Core.Bbands(inclose, 0, bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod: 26, optInNbDevUp: 2.0, optInNbDevDn: 2.0); }
Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Upper.Last().v, 6, MidpointRounding.AwayFromZero));
Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Mid.Last().v, 6, MidpointRounding.AwayFromZero)); [Fact]
Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Lower.Last().v, 6, MidpointRounding.AwayFromZero)); public void BBANDS()
} {
double[] outMiddle = new double[bars.Count];
[Fact] double[] outUpper = new double[bars.Count];
public void HL2() double[] outLower = new double[bars.Count];
{ BBANDS_Series QL = new(bars.Close, period: 26, multiplier: 2.0, false);
TSeries QL = bars.HL2; Core.Bbands(inclose, 0, bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod: 26, optInNbDevUp: 2.0, optInNbDevDn: 2.0);
Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Assert.Equal(Math.Round(outUpper[outUpper.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Upper.Last().v, 6, MidpointRounding.AwayFromZero));
Assert.Equal(Math.Round(outMiddle[outMiddle.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Mid.Last().v, 6, MidpointRounding.AwayFromZero));
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(outLower[outLower.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Lower.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void HLC3() public void HL2()
{ {
TSeries QL = bars.HLC3; TSeries QL = bars.HL2;
Core.TypPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void OHLC4() public void HLC3()
{ {
TSeries QL = bars.OHLC4; TSeries QL = bars.HLC3;
Core.AvgPrice(inopen, inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.TypPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact] [Fact]
public void HLCC4() public void OHLC4()
{ {
TSeries QL = bars.HLCC4; TSeries QL = bars.OHLC4;
Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _); Core.AvgPrice(inopen, inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero)); Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
} }
[Fact]
public void HLCC4()
{
TSeries QL = bars.HLCC4;
Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
Assert.Equal(Math.Round(TALIB[TALIB.Length - outBegIdx - 1], 6, MidpointRounding.AwayFromZero), Math.Round(QL.Last().v, 6, MidpointRounding.AwayFromZero));
}
} }
+2 -2
View File
@@ -55,7 +55,7 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
||||| |||||
| **STATISTICS & NUMERICAL ANALYSIS** | **QuanTAlib** | **TA-LIB** | **Skender** | **Pandas TA** | | **STATISTICS & NUMERICAL ANALYSIS** | **QuanTAlib** | **TA-LIB** | **Skender** | **Pandas TA** |
| ⭐ BIAS - Bias | `BIAS_Series` ||| bias | | ⭐ BIAS - Bias | `BIAS_Series` ||| bias |
| CORREL - Pearson's Correlation Coefficient || CORREL | GetCorrelation || | CORR - Pearson's Correlation Coefficient | `CORR_Series` | CORREL | GetCorrelation ||
| ⛔ COVAR - Covariance ||| GetCorrelation || | ⛔ COVAR - Covariance ||| GetCorrelation ||
| ⭐ ENTP - Entropy | `ENTP_Series` ||| entropy | | ⭐ ENTP - Entropy | `ENTP_Series` ||| entropy |
| ⭐ KURT - Kurtosis | `KURT_Series` ||| kurtosis | | ⭐ KURT - Kurtosis | `KURT_Series` ||| kurtosis |
@@ -72,7 +72,7 @@ See [Getting Started](https://github.com/mihakralj/QuanTAlib/blob/main/Docs/gett
| ⭐ SVAR - Sample Variance | `SVAR_Series` ||| variance | | ⭐ SVAR - Sample Variance | `SVAR_Series` ||| variance |
| ⛔ QUANTILE - Quantile |||| quantile | | ⛔ QUANTILE - Quantile |||| quantile |
| ✔️ WMAPE - Weighted Mean Absolute Percent Error | `WMAPE_Series` |||| | ✔️ WMAPE - Weighted Mean Absolute Percent Error | `WMAPE_Series` ||||
| ⭐ ZSCORE - Number of standard deviations from mean | ZSCORE_Series || GetStdDev | zscore | | ⭐ ZSCORE - Number of standard deviations from mean | `ZSCORE_Series` || GetStdDev | zscore |
|||||| ||||||
| **TREND INDICATORS & AVERAGES** | **QuanTAlib** | **TA-LIB** | **Skender** | **Pandas TA** | | **TREND INDICATORS & AVERAGES** | **QuanTAlib** | **TA-LIB** | **Skender** | **Pandas TA** |
| ⛔ AFIRMA - Autoregressive Finite Impulse Response Moving Average ||||| | ⛔ AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||