mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-27 17:27:43 +00:00
Fixes
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
name: "CodeQL Config"
|
||||
|
||||
queries:
|
||||
- uses: security-and-quality
|
||||
- uses: security-extended
|
||||
|
||||
paths-ignore:
|
||||
- '**/test/**'
|
||||
- '**/tests/**'
|
||||
- '**/*.test.cs'
|
||||
- '**/obj/**'
|
||||
- '**/bin/**'
|
||||
- '**/docs/**'
|
||||
|
||||
query-filters:
|
||||
- exclude:
|
||||
problem.severity:
|
||||
- warning
|
||||
- recommendation
|
||||
|
||||
paths:
|
||||
- src
|
||||
+125
-62
@@ -1,17 +1,37 @@
|
||||
name: Publish Workflow
|
||||
|
||||
on:
|
||||
push: # Triggers on push events to any branch
|
||||
pull_request: # Triggers on pull request events targeting any branch
|
||||
workflow_dispatch: # Allows manual triggering of the workflow
|
||||
push:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'docs/**'
|
||||
- '.gitignore'
|
||||
- 'LICENSE'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'docs/**'
|
||||
- '.gitignore'
|
||||
- 'LICENSE'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read # Allows SonarCloud to decorate PRs with analysis results
|
||||
security-events: write # Required for CodeQL analysis and uploading SARIF results
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: '8.x'
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||
|
||||
jobs:
|
||||
Code_Coverage:
|
||||
timeout-minutes: 30
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -22,7 +42,20 @@ jobs:
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '8.x'
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: ${{ runner.os }}-nuget-
|
||||
|
||||
- name: Cache dotnet tools
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.dotnet/tools
|
||||
key: ${{ runner.os }}-dotnet-tools-${{ hashFiles('**/*.csproj') }}
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
@@ -69,6 +102,8 @@ jobs:
|
||||
/d:sonar.verbose="true"
|
||||
|
||||
- name: Build Projects
|
||||
id: build
|
||||
continue-on-error: true
|
||||
run: |
|
||||
dotnet build --no-restore --configuration Debug
|
||||
dotnet build ./lib/quantalib.csproj --configuration Release --nologo
|
||||
@@ -76,8 +111,15 @@ jobs:
|
||||
dotnet build ./quantower/Statistics/_Statistics.csproj --configuration Release --nologo
|
||||
dotnet build ./quantower/Volatility/_Volatility.csproj --configuration Release --nologo
|
||||
dotnet build ./SyntheticVendor/SyntheticVendor.csproj --configuration Release --nologo
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "Build failed" }
|
||||
|
||||
- name: Check Build Status
|
||||
if: steps.build.outcome == 'failure'
|
||||
run: exit 1
|
||||
|
||||
- name: Run Tests with Coverage
|
||||
id: tests
|
||||
continue-on-error: true
|
||||
run: |
|
||||
dotnet test --no-build --configuration Debug /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
|
||||
dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml"
|
||||
@@ -87,9 +129,21 @@ jobs:
|
||||
|
||||
- name: Generate Coverage Report
|
||||
run: |
|
||||
reportgenerator -reports:*cover*.xml -targetdir:.
|
||||
reportgenerator -reports:*cover*.xml -targetdir:./coverage-report
|
||||
|
||||
- name: Upload Coverage Reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-reports
|
||||
path: |
|
||||
**/TestResults
|
||||
**/coverage-report
|
||||
**/*cover*.xml
|
||||
**/dotcover.*
|
||||
|
||||
- name: End SonarCloud Analysis
|
||||
if: always()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
@@ -109,7 +163,13 @@ jobs:
|
||||
verbose: true
|
||||
|
||||
CodeQL:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
@@ -119,12 +179,22 @@ jobs:
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '8.x'
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: ${{ runner.os }}-nuget-
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: 'csharp'
|
||||
queries: security-and-quality
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
tools: latest
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
@@ -132,63 +202,51 @@ jobs:
|
||||
- name: Build
|
||||
run: dotnet build --no-restore --configuration Debug
|
||||
|
||||
- name: Run Codacy Analysis CLI
|
||||
uses: codacy/codacy-analysis-cli-action@v4
|
||||
with:
|
||||
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
verbose: true
|
||||
output: results.sarif
|
||||
format: sarif
|
||||
gh-code-scanning-compat: true
|
||||
max-allowed-issues: 2147483647
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
- name: Upload SARIF results file
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
output: results
|
||||
upload: true
|
||||
|
||||
SecurityCodeScan:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/dotnet@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
LD_PRELOAD: '' # Clear the LD_PRELOAD to avoid CodeQL conflicts
|
||||
with:
|
||||
fetch-depth: 0
|
||||
args: |
|
||||
--file=./lib/quantalib.csproj
|
||||
--severity-threshold=low
|
||||
--detection-depth=4
|
||||
--package-manager=nuget
|
||||
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@v2
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
- name: Run Snyk on Solution
|
||||
uses: snyk/actions/dotnet@master
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
LD_PRELOAD: ''
|
||||
with:
|
||||
dotnet-version: |
|
||||
8.x
|
||||
3.1.x
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Set up projects for analysis
|
||||
uses: security-code-scan/security-code-scan-add-action@v1
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
dotnet restore
|
||||
dotnet build --no-restore --configuration Debug
|
||||
|
||||
- name: Convert SARIF for uploading to GitHub
|
||||
uses: security-code-scan/security-code-scan-results-action@v1
|
||||
|
||||
- name: Upload SARIF
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
args: |
|
||||
--file=QuanTAlib.sln
|
||||
--all-projects
|
||||
--detection-depth=4
|
||||
|
||||
- name: Run Snyk IaC
|
||||
uses: snyk/actions/iac@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
LD_PRELOAD: ''
|
||||
with:
|
||||
args: |
|
||||
--severity-threshold=low
|
||||
|
||||
build_publish:
|
||||
needs: [Code_Coverage, CodeQL, SecurityCodeScan]
|
||||
timeout-minutes: 20
|
||||
needs: [Code_Coverage, CodeQL]
|
||||
if: |
|
||||
success() &&
|
||||
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')) ||
|
||||
@@ -203,7 +261,14 @@ jobs:
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '8.x'
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: ${{ runner.os }}-nuget-
|
||||
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v0
|
||||
@@ -227,8 +292,6 @@ jobs:
|
||||
dotnet build ./quantower/Volatility/_Volatility.csproj --configuration Release --nologo
|
||||
dotnet build ./SyntheticVendor/SyntheticVendor.csproj --configuration Release --nologo
|
||||
|
||||
############# Publish dev release
|
||||
|
||||
- name: Create or Update Development Release
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
env:
|
||||
@@ -248,16 +311,16 @@ jobs:
|
||||
|
||||
- name: Push prerelease package to myget.org
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
continue-on-error: true
|
||||
id: myget-push
|
||||
run: |
|
||||
dotnet nuget push 'lib/bin/Release/QuanTAlib.*.nupkg' \
|
||||
--source https://www.myget.org/F/quantalib/api/v3/index.json \
|
||||
--force-english-output \
|
||||
--api-key ${{ secrets.MYGET_DEPLOY_KEY_QUANTALIB }}
|
||||
|
||||
############## Publish main release
|
||||
--source https://www.myget.org/F/quantalib/api/v3/index.json \
|
||||
--force-english-output \
|
||||
--api-key ${{ secrets.MYGET_DEPLOY_KEY_QUANTALIB }}
|
||||
|
||||
- name: Create GitHub Release
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
if: github.ref == 'refs/heads/main'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
|
||||
@@ -597,25 +597,6 @@ public class SyntheticVendor : Vendor
|
||||
};
|
||||
}
|
||||
|
||||
private HistoryItemBar GeneratePulseWave(DateTime time, TimeSpan slice)
|
||||
{
|
||||
double hours = (time - DateTime.UnixEpoch).TotalHours;
|
||||
double period = 24; // 24-hour period
|
||||
double position = hours % period;
|
||||
double value = position < period / 5 ? 100 : -100; // 20% duty cycle
|
||||
|
||||
return new HistoryItemBar
|
||||
{
|
||||
TicksLeft = time.Ticks,
|
||||
TicksRight = time.Add(slice).Ticks - 1,
|
||||
Open = value,
|
||||
High = 100,
|
||||
Low = -100,
|
||||
Close = value,
|
||||
Volume = 100,
|
||||
Ticks = 100
|
||||
};
|
||||
}
|
||||
|
||||
private HistoryItemBar GenerateTriangleWave(DateTime time, TimeSpan slice)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace QuanTAlib;
|
||||
public class Dsma : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _buffer;
|
||||
private readonly double _c1, _c2, _c3;
|
||||
private readonly double _c2, _c3;
|
||||
private readonly double _scaleFactor;
|
||||
private readonly double _periodRecip; // 1/_period
|
||||
private readonly double _scaleByPeriod; // 5/_period
|
||||
@@ -59,7 +59,7 @@ public class Dsma : AbstractBase
|
||||
|
||||
_c2 = b1;
|
||||
_c3 = -a1 * a1;
|
||||
_c1 = 1.0 - _c2 - _c3;
|
||||
double _c1 = 1.0 - _c2 - _c3;
|
||||
_c1Half = _c1 * 0.5;
|
||||
_scaleByPeriod = 5.0 / period;
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ public sealed class Cv : AbstractBase
|
||||
private readonly double _omega;
|
||||
private double _prevClose;
|
||||
private double _prevVariance;
|
||||
private double _longTermVariance;
|
||||
private bool _isInitialized;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -82,7 +81,6 @@ public sealed class Cv : AbstractBase
|
||||
base.Init();
|
||||
_prevClose = 0;
|
||||
_prevVariance = 0;
|
||||
_longTermVariance = 0;
|
||||
_isInitialized = false;
|
||||
}
|
||||
|
||||
@@ -116,7 +114,7 @@ public sealed class Cv : AbstractBase
|
||||
// Initialize with first available data if not done
|
||||
if (!_isInitialized && _index > _period)
|
||||
{
|
||||
_longTermVariance = squaredReturn; // Use current squared return as initial estimate
|
||||
double _longTermVariance = squaredReturn; // Use current squared return as initial estimate
|
||||
_prevVariance = _longTermVariance;
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace QuanTAlib;
|
||||
public sealed class Cvi : AbstractBase
|
||||
{
|
||||
private readonly int _period;
|
||||
private readonly int _smoothPeriod;
|
||||
private readonly CircularBuffer _smoothed;
|
||||
private readonly double _alpha;
|
||||
private double _ema;
|
||||
@@ -50,10 +49,9 @@ public sealed class Cvi : AbstractBase
|
||||
public Cvi(int period = 10, int smoothPeriod = 10)
|
||||
{
|
||||
_period = period;
|
||||
_smoothPeriod = smoothPeriod;
|
||||
_alpha = 2.0 / (_smoothPeriod + 1);
|
||||
WarmupPeriod = _period + _smoothPeriod;
|
||||
Name = $"CVI({_period},{_smoothPeriod})";
|
||||
_alpha = 2.0 / (smoothPeriod + 1);
|
||||
WarmupPeriod = _period + smoothPeriod;
|
||||
Name = $"CVI({_period},{smoothPeriod})";
|
||||
_smoothed = new CircularBuffer(_period);
|
||||
Init();
|
||||
}
|
||||
|
||||
+9
-13
@@ -42,7 +42,6 @@ namespace QuanTAlib;
|
||||
[SkipLocalsInit]
|
||||
public sealed class Fcb : AbstractBase
|
||||
{
|
||||
private readonly int _period;
|
||||
private readonly double _smoothing;
|
||||
private readonly CircularBuffer _highs;
|
||||
private readonly CircularBuffer _lows;
|
||||
@@ -56,11 +55,10 @@ public sealed class Fcb : AbstractBase
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Fcb(int period = 20, double smoothing = 0.5)
|
||||
{
|
||||
_period = period;
|
||||
_smoothing = smoothing;
|
||||
_alpha = 2.0 / (_period + 1);
|
||||
_alpha = 2.0 / (period + 1);
|
||||
WarmupPeriod = period + 4; // Need extra periods for fractal identification
|
||||
Name = $"FCB({_period},{_smoothing})";
|
||||
Name = $"FCB({period},{_smoothing})";
|
||||
_highs = new CircularBuffer(period);
|
||||
_lows = new CircularBuffer(period);
|
||||
Init();
|
||||
@@ -116,16 +114,14 @@ public sealed class Fcb : AbstractBase
|
||||
bool isFractalHigh = false;
|
||||
bool isFractalLow = false;
|
||||
|
||||
if (_index >= 5)
|
||||
{
|
||||
// Fractal high: current high is higher than 2 bars before and after
|
||||
isFractalHigh = _highs[2] > _highs[0] && _highs[2] > _highs[1] &&
|
||||
_highs[2] > _highs[3] && _highs[2] > _highs[4];
|
||||
// Fractal high: current high is higher than 2 bars before and after
|
||||
isFractalHigh = _highs[2] > _highs[0] && _highs[2] > _highs[1] &&
|
||||
_highs[2] > _highs[3] && _highs[2] > _highs[4];
|
||||
|
||||
// Fractal low: current low is lower than 2 bars before and after
|
||||
isFractalLow = _lows[2] < _lows[0] && _lows[2] < _lows[1] &&
|
||||
_lows[2] < _lows[3] && _lows[2] < _lows[4];
|
||||
|
||||
// Fractal low: current low is lower than 2 bars before and after
|
||||
isFractalLow = _lows[2] < _lows[0] && _lows[2] < _lows[1] &&
|
||||
_lows[2] < _lows[3] && _lows[2] < _lows[4];
|
||||
}
|
||||
|
||||
// Update EMAs with fractal points
|
||||
if (isFractalHigh)
|
||||
|
||||
Reference in New Issue
Block a user