mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-25 05:48:06 +00:00
chore: Update .gitignore to exclude SonarQube files and add Codacy and SonarScanner scripts
refactor: Remove WarmupPeriod logging from SMA and WMA examples
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Codacy Coverage Upload for QuanTAlib
|
||||||
|
# Requires CODACY_PROJECT_TOKEN environment variable
|
||||||
|
|
||||||
|
if [[ -z "${CODACY_PROJECT_TOKEN:-}" ]]; then
|
||||||
|
echo "Error: CODACY_PROJECT_TOKEN environment variable not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Building solution..."
|
||||||
|
dotnet build --no-incremental
|
||||||
|
|
||||||
|
echo "==> Running tests with coverage..."
|
||||||
|
dotnet test --no-build --collect:"XPlat Code Coverage" \
|
||||||
|
-- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
|
||||||
|
|
||||||
|
# Find the coverage file
|
||||||
|
COVERAGE_FILE=$(find . -name "coverage.opencover.xml" -type f | head -1)
|
||||||
|
|
||||||
|
if [[ -z "$COVERAGE_FILE" ]]; then
|
||||||
|
echo "Error: No coverage file found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Uploading coverage to Codacy..."
|
||||||
|
echo " Coverage file: $COVERAGE_FILE"
|
||||||
|
|
||||||
|
bash <(curl -Ls https://coverage.codacy.com/get.sh) report \
|
||||||
|
-r "$COVERAGE_FILE" \
|
||||||
|
--project-token "$CODACY_PROJECT_TOKEN"
|
||||||
|
|
||||||
|
echo "==> Done! View results at https://app.codacy.com/gh/mihakralj/QuanTAlib"
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Static Analysis Scanner for QuanTAlib
|
||||||
|
# Runs SonarCloud and Qodana with code coverage
|
||||||
|
|
||||||
|
# Tokens must be set as environment variables
|
||||||
|
if [[ -z "${SONAR_TOKEN:-}" ]]; then
|
||||||
|
echo "Error: SONAR_TOKEN environment variable not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z "${QODANA_TOKEN:-}" ]]; then
|
||||||
|
echo "Error: QODANA_TOKEN environment variable not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Coverage output directory for Qodana
|
||||||
|
COVERAGE_DIR=".qodana/code-coverage"
|
||||||
|
|
||||||
|
echo "==> Building solution..."
|
||||||
|
dotnet build --no-incremental
|
||||||
|
|
||||||
|
echo "==> Running tests with coverage..."
|
||||||
|
mkdir -p "$COVERAGE_DIR"
|
||||||
|
dotnet test --no-build --collect:"XPlat Code Coverage" \
|
||||||
|
-- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=lcov
|
||||||
|
|
||||||
|
# Copy coverage to Qodana directory
|
||||||
|
find . -name "coverage.info" -exec cp {} "$COVERAGE_DIR/" \;
|
||||||
|
|
||||||
|
# Run SonarCloud
|
||||||
|
echo "==> Starting SonarScanner analysis..."
|
||||||
|
|
||||||
|
# Re-run tests with OpenCover format for SonarCloud
|
||||||
|
dotnet test --no-build --collect:"XPlat Code Coverage" \
|
||||||
|
-- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
|
||||||
|
|
||||||
|
dotnet sonarscanner begin \
|
||||||
|
/o:"mihakralj-quantalib" \
|
||||||
|
/k:"mihakralj_QuanTAlib" \
|
||||||
|
/d:sonar.token="$SONAR_TOKEN" \
|
||||||
|
/d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml"
|
||||||
|
|
||||||
|
dotnet build --no-incremental
|
||||||
|
|
||||||
|
dotnet sonarscanner end /d:sonar.token="$SONAR_TOKEN"
|
||||||
|
|
||||||
|
echo "==> SonarCloud: https://sonarcloud.io/project/overview?id=mihakralj_QuanTAlib"
|
||||||
|
|
||||||
|
# Run Qodana
|
||||||
|
echo "==> Starting Qodana analysis..."
|
||||||
|
|
||||||
|
QODANA_TOKEN="$QODANA_TOKEN" qodana scan \
|
||||||
|
--coverage-dir "$COVERAGE_DIR"
|
||||||
|
|
||||||
|
echo "==> Qodana analysis complete"
|
||||||
|
|
||||||
|
echo "==> Done!"
|
||||||
+8
-4
@@ -396,6 +396,10 @@ FodyWeavers.xsd
|
|||||||
|
|
||||||
# JetBrains Rider
|
# JetBrains Rider
|
||||||
*.sln.iml
|
*.sln.iml
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# SonarQube/SonarCloud
|
||||||
|
.sonarqube/
|
||||||
|
|
||||||
# Cline Memory Bank - exclude from git
|
# Cline Memory Bank - exclude from git
|
||||||
memory-bank/
|
memory-bank/
|
||||||
@@ -405,7 +409,7 @@ memory-bank/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.AppleDouble
|
.AppleDouble
|
||||||
.LSOverride
|
.LSOverride
|
||||||
|
|
||||||
|
|
||||||
#Ignore insiders AI rules
|
#Ignore insiders AI rules
|
||||||
.github/instructions/codacy.instructions.md
|
.github/instructions/codacy.instructions.md
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ Console.WriteLine($"Current SMA: {result.Value}");
|
|||||||
|
|
||||||
// Access properties
|
// Access properties
|
||||||
Console.WriteLine($"Name: {sma.Name}"); // "Sma(10)"
|
Console.WriteLine($"Name: {sma.Name}"); // "Sma(10)"
|
||||||
Console.WriteLine($"WarmupPeriod: {sma.WarmupPeriod}"); // 10
|
|
||||||
Console.WriteLine($"IsHot: {sma.IsHot}"); // true when buffer is full
|
Console.WriteLine($"IsHot: {sma.IsHot}"); // true when buffer is full
|
||||||
|
|
||||||
// Batch calculation (TSeries API)
|
// Batch calculation (TSeries API)
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ Console.WriteLine($"Current WMA: {result.Value}");
|
|||||||
|
|
||||||
// Access properties
|
// Access properties
|
||||||
Console.WriteLine($"Name: {wma.Name}"); // "Wma(10)"
|
Console.WriteLine($"Name: {wma.Name}"); // "Wma(10)"
|
||||||
Console.WriteLine($"WarmupPeriod: {wma.WarmupPeriod}"); // 10
|
|
||||||
Console.WriteLine($"IsHot: {wma.IsHot}"); // true when buffer is full
|
Console.WriteLine($"IsHot: {wma.IsHot}"); // true when buffer is full
|
||||||
|
|
||||||
// Batch calculation (TSeries API)
|
// Batch calculation (TSeries API)
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public readonly struct TBar : IEquatable<TBar>
|
|||||||
public override string ToString() => $"[{AsDateTime:yyyy-MM-dd HH:mm:ss}: O={Open:F2}, H={High:F2}, L={Low:F2}, C={Close:F2}, V={Volume:F2}]";
|
public override string ToString() => $"[{AsDateTime:yyyy-MM-dd HH:mm:ss}: O={Open:F2}, H={High:F2}, L={Low:F2}, C={Close:F2}, V={Volume:F2}]";
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
#pragma warning disable S1244 // Floating point equality is intentional for exact struct comparison
|
||||||
public bool Equals(TBar other) =>
|
public bool Equals(TBar other) =>
|
||||||
Time == other.Time &&
|
Time == other.Time &&
|
||||||
Open == other.Open &&
|
Open == other.Open &&
|
||||||
@@ -75,6 +76,7 @@ public readonly struct TBar : IEquatable<TBar>
|
|||||||
Low == other.Low &&
|
Low == other.Low &&
|
||||||
Close == other.Close &&
|
Close == other.Close &&
|
||||||
Volume == other.Volume;
|
Volume == other.Volume;
|
||||||
|
#pragma warning restore S1244
|
||||||
|
|
||||||
public override bool Equals(object? obj) => obj is TBar other && Equals(other);
|
public override bool Equals(object? obj) => obj is TBar other && Equals(other);
|
||||||
public override int GetHashCode() => HashCode.Combine(Time, Open, High, Low, Close, Volume);
|
public override int GetHashCode() => HashCode.Combine(Time, Open, High, Low, Close, Volume);
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ namespace QuanTAlib;
|
|||||||
/// Stateless design - only maintains minimal state needed for price continuity.
|
/// Stateless design - only maintains minimal state needed for price continuity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SkipLocalsInit]
|
[SkipLocalsInit]
|
||||||
|
#pragma warning disable S101 // Types should be named in PascalCase - GBM is a standard acronym
|
||||||
public class GBM : IFeed
|
public class GBM : IFeed
|
||||||
|
#pragma warning restore S101
|
||||||
{
|
{
|
||||||
private readonly Random _rnd;
|
private readonly Random _rnd;
|
||||||
|
|
||||||
@@ -17,7 +19,6 @@ public class GBM : IFeed
|
|||||||
|
|
||||||
private readonly double _mu;
|
private readonly double _mu;
|
||||||
private readonly double _sigma;
|
private readonly double _sigma;
|
||||||
private readonly double _dt;
|
|
||||||
|
|
||||||
// Precomputed GBM constants
|
// Precomputed GBM constants
|
||||||
private readonly double _drift;
|
private readonly double _drift;
|
||||||
@@ -63,10 +64,10 @@ public class GBM : IFeed
|
|||||||
|
|
||||||
// Calculate dt based on timeframe (assuming 252 trading days/year, 6.5 hours/day)
|
// Calculate dt based on timeframe (assuming 252 trading days/year, 6.5 hours/day)
|
||||||
double minutesPerYear = 252.0 * 6.5 * 60.0;
|
double minutesPerYear = 252.0 * 6.5 * 60.0;
|
||||||
_dt = timeframe.TotalMinutes / minutesPerYear;
|
double dt = timeframe.TotalMinutes / minutesPerYear;
|
||||||
|
|
||||||
_drift = (mu - 0.5 * sigma * sigma) * _dt;
|
_drift = (mu - 0.5 * sigma * sigma) * dt;
|
||||||
_vol = sigma * Math.Sqrt(_dt);
|
_vol = sigma * Math.Sqrt(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -81,8 +82,10 @@ public class GBM : IFeed
|
|||||||
return _cachedZ;
|
return _cachedZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable S2245 // Random is acceptable for simulation/testing purposes
|
||||||
double u1 = 1.0 - _rnd.NextDouble();
|
double u1 = 1.0 - _rnd.NextDouble();
|
||||||
double u2 = 1.0 - _rnd.NextDouble();
|
double u2 = 1.0 - _rnd.NextDouble();
|
||||||
|
#pragma warning restore S2245
|
||||||
double mag = Math.Sqrt(-2.0 * Math.Log(u1));
|
double mag = Math.Sqrt(-2.0 * Math.Log(u1));
|
||||||
double angle = 2.0 * Math.PI * u2;
|
double angle = 2.0 * Math.PI * u2;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user