Update Python installation and dependencies

This commit is contained in:
Miha Kralj
2023-05-05 07:49:58 -07:00
parent 56f8db2949
commit 9714dedcba
6 changed files with 123 additions and 37 deletions
+22
View File
@@ -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
+3 -4
View File
@@ -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>
+3 -3
View File
@@ -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
View File
@@ -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" />
+90 -26
View File
@@ -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);
}
}
}
}
}
+2
View File
@@ -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()
{