mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-09 06:27:45 +00:00
Update Python installation and dependencies
This commit is contained in:
@@ -45,6 +45,27 @@ jobs:
|
||||
#configFilePath: GitVersion.yml
|
||||
updateAssemblyInfo: true
|
||||
|
||||
############## Install Python
|
||||
|
||||
# - name: Install Python3
|
||||
# uses: actions/setup-python@v2
|
||||
# with:
|
||||
# python-version: 3.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python3-dev
|
||||
sudo apt-get install -y python3-pip
|
||||
|
||||
- name: Install pandas-ta
|
||||
run: |
|
||||
pip3 install numpy
|
||||
pip3 install pandas
|
||||
pip3 install pandas-ta
|
||||
|
||||
############## Install more tools
|
||||
|
||||
- name: Install JDK11 for Sonar Scanner
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
@@ -158,3 +179,4 @@ jobs:
|
||||
--api-key ${{ secrets.NUGET_DEPLOY_KEY_QUANTLIB }}
|
||||
--source https://api.nuget.org/v3/index.json
|
||||
--skip-duplicate
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Title>QuanTAlib</Title>
|
||||
<Version>0.2.0</Version>
|
||||
<Version>0.2.5</Version>
|
||||
<AssemblyVersion>0.2.5</AssemblyVersion>
|
||||
<FileVersion>0.2.5</FileVersion>
|
||||
<Product>Library of TA Calculations, Charts and Strategies for Quantower</Product>
|
||||
<Description>Quantitative Technical Analysis Library in C# for Quantower</Description>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
@@ -33,9 +35,6 @@
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageLicenseFile>
|
||||
</PackageLicenseFile>
|
||||
<AssemblyVersion>0.2.1.0</AssemblyVersion>
|
||||
<FileVersion>0.2.1.0</FileVersion>
|
||||
<InformationalVersion>0.2.1-dev.2+Branch.dev.Sha.cb5fe2dc86a78fe9358da810d17952c82299ed3d</InformationalVersion>
|
||||
<SuppressNETSdkWarningProperty>NETSDK1057</SuppressNETSdkWarningProperty>
|
||||
<SuppressNETSdkWarningProperty>IDE1006</SuppressNETSdkWarningProperty>
|
||||
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
|
||||
|
||||
@@ -29,9 +29,9 @@ public class CROSS_Series : Pair_TSeries_Indicator {
|
||||
val = TValue1.v == TValue2.v ? 0 : val;
|
||||
double over = TValue1.v > TValue2.v ? 1 : val;
|
||||
|
||||
val = (this._previous < over) ? 1 : -1;
|
||||
(System.DateTime t, double v) result = ((TValue1.t > TValue2.t) ? TValue1.t : TValue2.t,
|
||||
((this._previous == over) || Double.IsNaN(this._previous) || (this._previous == 0)) ? 0 : val);
|
||||
val = (_previous < over) ? 1 : -1;
|
||||
val = ((_previous == over) || Double.IsNaN(this._previous) || (this._previous == 0)) ? 0 : val;
|
||||
(System.DateTime t, double v) result = ((TValue1.t > TValue2.t) ? TValue1.t : TValue2.t,val);
|
||||
|
||||
this._previous = over;
|
||||
|
||||
|
||||
+3
-4
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
@@ -18,8 +18,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Python.Included" Version="3.11.2" />
|
||||
<PackageReference Include="pythonnet" Version="3.1.0-preview2023-03-04" />
|
||||
<PackageReference Include="pythonnet" Version="3.0.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
@@ -29,7 +28,7 @@
|
||||
<PackageReference Include="TALib.NETCore" Version="0.4.4" />
|
||||
<PackageReference Include="Skender.Stock.Indicators" Version="3.0.0-preview1014-0015" />
|
||||
<PackageReference Include="Tulip.NETCore" Version="0.8.0.1" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.0-preview.2.23128.3" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.0-preview.3.23174.8" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Calculations\Calculations.csproj" />
|
||||
|
||||
@@ -1,41 +1,37 @@
|
||||
using Xunit;
|
||||
using System;
|
||||
using QuanTAlib;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.Marshalling;
|
||||
using Python.Runtime;
|
||||
using Python.Included;
|
||||
|
||||
namespace Validations;
|
||||
|
||||
/*
|
||||
|
||||
public class PandasTA : IDisposable
|
||||
{
|
||||
private bool disposed = false;
|
||||
private readonly GBM_Feed bars;
|
||||
private readonly Random rnd = new();
|
||||
private readonly Random rnd = new();
|
||||
private readonly int period, skip;
|
||||
private int digits;
|
||||
private readonly string dllpath;
|
||||
private readonly int digits;
|
||||
private readonly dynamic np;
|
||||
private readonly dynamic ta;
|
||||
private readonly dynamic pd;
|
||||
private readonly dynamic df;
|
||||
|
||||
|
||||
public PandasTA() {
|
||||
bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0);
|
||||
period = rnd.Next(maxValue: 28) + 3;
|
||||
skip = period+10;
|
||||
digits = 8;
|
||||
|
||||
Installer.InstallPath = Path.GetFullPath(path: ".");
|
||||
Installer.SetupPython().Wait();
|
||||
Installer.TryInstallPip();
|
||||
Installer.PipInstallModule(module_name: "numpy");
|
||||
Installer.PipInstallModule(module_name: "pandas");
|
||||
Installer.PipInstallModule(module_name: "pandas-ta");
|
||||
dllpath = Installer.InstallPath + "\\" + Installer.InstallDirectory + "\\" + Runtime.PythonDLL;
|
||||
Runtime.PythonDLL = dllpath;
|
||||
string pythonDLL = PythonLibrary.Locate();
|
||||
Runtime.PythonDLL = pythonDLL;
|
||||
PythonEngine.Initialize();
|
||||
|
||||
np = Py.Import(name: "numpy");
|
||||
np = Py.Import(name: "numpy");
|
||||
pd = Py.Import(name: "pandas");
|
||||
ta = Py.Import(name: "pandas_ta");
|
||||
|
||||
@@ -52,11 +48,21 @@ public class PandasTA : IDisposable
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
PythonEngine.Shutdown();
|
||||
Dispose(true);
|
||||
PythonEngine.Shutdown();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
~PandasTA() {
|
||||
Dispose(false);
|
||||
}
|
||||
protected virtual void Dispose(bool disposing) {
|
||||
if (!disposed) {
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact] void ADL() {
|
||||
[Fact]
|
||||
void ADL() {
|
||||
ADL_Series QL = new(bars);
|
||||
var pta = df.ta.ad(high: df.high, low: df.low, close:df.close, volume:df.volume);
|
||||
for (int i = QL.Length-1; i > skip; i--)
|
||||
@@ -67,7 +73,7 @@ public class PandasTA : IDisposable
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
/*
|
||||
[Fact] void ADOSC() {
|
||||
ADOSC_Series QL = new(bars);
|
||||
var pta = df.ta.adosc(high: df.high, low: df.low, close: df.close, volume: df.volume);
|
||||
@@ -124,7 +130,7 @@ public class PandasTA : IDisposable
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
void CMO() {
|
||||
CMO_Series QL = new(bars.Close, period, false);
|
||||
@@ -135,7 +141,7 @@ public class PandasTA : IDisposable
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact] void DEMA() {
|
||||
DEMA_Series QL = new(bars.Close, period, false);
|
||||
var pta = df.ta.dema(close: df.close, length: period);
|
||||
@@ -146,7 +152,7 @@ public class PandasTA : IDisposable
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact] void EMA() {
|
||||
EMA_Series QL = new(bars.Close, period, false);
|
||||
var pta = df.ta.ema(close: df.close, length: period);
|
||||
@@ -157,7 +163,7 @@ public class PandasTA : IDisposable
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact] void ENTROPY() {
|
||||
ENTROPY_Series QL = new(bars.Close, period, useNaN: false);
|
||||
var pta = df.ta.entropy(close: df.close, length: period);
|
||||
@@ -197,6 +203,7 @@ public class PandasTA : IDisposable
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Fact] void HWMA() {
|
||||
HWMA_Series QL = new(bars.Close, useNaN: false);
|
||||
var pta = df.ta.hwma(close: df.close);
|
||||
@@ -206,8 +213,8 @@ public class PandasTA : IDisposable
|
||||
double PanTA_item = (double)pta[i - 1];
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Fact] void KAMA() {
|
||||
KAMA_Series QL = new(bars.Close, period);
|
||||
var pta = df.ta.kama(close: df.close, length: period);
|
||||
@@ -311,7 +318,7 @@ public class PandasTA : IDisposable
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact] void SMA() {
|
||||
SMA_Series QL = new(bars.Close, period, false);
|
||||
var pta = df.ta.sma(close: df.close, length: period);
|
||||
@@ -322,7 +329,7 @@ public class PandasTA : IDisposable
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact] void SSDEV() {
|
||||
SSDEV_Series QL = new(bars.Close, period, useNaN: false);
|
||||
var pta = df.ta.stdev(close: df.close, length: period, ddof: 1);
|
||||
@@ -434,6 +441,63 @@ public class PandasTA : IDisposable
|
||||
Assert.InRange(PanTA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
public static class PythonLibrary {
|
||||
public static string Locate() {
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
|
||||
string[] paths = Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? Array.Empty<string>();
|
||||
foreach (string path in paths) {
|
||||
string[] pythonDLLs = Directory.GetFiles(path, "python3*.dll");
|
||||
if (pythonDLLs.Length > 0) {
|
||||
foreach (string item in pythonDLLs) {
|
||||
if (!item.EndsWith("python3.dll", StringComparison.OrdinalIgnoreCase)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
throw new FileNotFoundException("Python library not found in PATH");
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
|
||||
List<string> pythonLibraries = new List<string>();
|
||||
List<string> directoriesToSearch = new List<string> { "/opt/hostedtoolcache/Python" }; // Add more directories as needed
|
||||
string filePattern = "libpython3.*.so";
|
||||
SearchFiles(directoriesToSearch, filePattern, pythonLibraries);
|
||||
|
||||
if (pythonLibraries.Count > 0) {
|
||||
return pythonLibraries[0];
|
||||
}
|
||||
else {
|
||||
throw new FileNotFoundException("Python library not found");
|
||||
}
|
||||
}
|
||||
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
|
||||
throw new NotSupportedException("Not supported yet");
|
||||
}
|
||||
|
||||
else { throw new NotSupportedException("Unsupported operating system"); }
|
||||
}
|
||||
static void SearchFiles(List<string> directoriesToSearch, string filePattern, List<string> foundFiles)
|
||||
{
|
||||
foreach (string directory in directoriesToSearch)
|
||||
{
|
||||
if (Directory.Exists(directory))
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] files = Directory.GetFiles(directory, filePattern, SearchOption.AllDirectories);
|
||||
foundFiles.AddRange(files);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Error searching in directory: " + directory + " - " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ public class Skender
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
[Fact]
|
||||
public void ADL()
|
||||
{
|
||||
@@ -42,6 +43,7 @@ public class Skender
|
||||
Assert.InRange(SK_item! - QL_item, -Math.Pow(10,-digits), Math.Pow(10,-digits));
|
||||
}
|
||||
}
|
||||
*/
|
||||
[Fact]
|
||||
public void ALMA()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user