Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d5f5e14dda | |||
| 7e5d394f2a | |||
| ff268500ef | |||
| 929fc17127 | |||
| 41d5a7dd25 | |||
| e595ea8bfe |
+135
-24
@@ -34,7 +34,7 @@ jobs:
|
||||
rust:
|
||||
name: Rust ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
examples-smoke:
|
||||
name: Examples (syntax smoke)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -195,7 +195,7 @@ jobs:
|
||||
clippy-bindings:
|
||||
name: Clippy bindings
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -279,7 +279,7 @@ jobs:
|
||||
msrv:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -328,7 +328,7 @@ jobs:
|
||||
coverage:
|
||||
name: Coverage
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -370,7 +370,7 @@ jobs:
|
||||
supply-chain:
|
||||
name: Supply-chain (cargo-deny)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -389,7 +389,7 @@ jobs:
|
||||
fuzz-smoke:
|
||||
name: Fuzz (smoke)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -443,7 +443,7 @@ jobs:
|
||||
python:
|
||||
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -525,7 +525,7 @@ jobs:
|
||||
wasm:
|
||||
name: WASM build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -575,7 +575,7 @@ jobs:
|
||||
node:
|
||||
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -622,9 +622,17 @@ jobs:
|
||||
cache: npm
|
||||
cache-dependency-path: bindings/node/package-lock.json
|
||||
|
||||
# npm's own fetch-retry (npm_config_fetch_retries) rides out per-request
|
||||
# blips; wrap the whole `npm ci` once more so a longer registry hiccup
|
||||
# retries the install instead of failing the job.
|
||||
- name: Install Node dependencies
|
||||
working-directory: bindings/node
|
||||
run: npm ci
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 20
|
||||
command: cd bindings/node && npm ci
|
||||
shell: bash
|
||||
|
||||
- name: Build native module
|
||||
working-directory: bindings/node
|
||||
@@ -649,7 +657,7 @@ jobs:
|
||||
c-abi:
|
||||
name: C ABI on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -705,7 +713,7 @@ jobs:
|
||||
csharp:
|
||||
name: C# on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -723,6 +731,19 @@ jobs:
|
||||
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
|
||||
timeout-minutes: 6
|
||||
|
||||
# Cache the restored NuGet packages so dotnet test/build resolve from the
|
||||
# local store instead of hitting nuget.org every run. No packages.lock.json
|
||||
# exists, so key on the project files; never block the job on a slow restore.
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
continue-on-error: true
|
||||
timeout-minutes: 6
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-nuget-
|
||||
|
||||
# The binding links against the C ABI hub at runtime; build it first so the
|
||||
# DllImportResolver finds target/release/wickra.{dll,so,dylib}. .NET 8 SDK is
|
||||
# preinstalled on the GitHub runners, so no setup-dotnet step is needed.
|
||||
@@ -732,8 +753,17 @@ jobs:
|
||||
- name: .NET info
|
||||
run: dotnet --info
|
||||
|
||||
# dotnet test restores from nuget.org first; retry so a transient restore
|
||||
# blip retries instead of failing the job (the cached packages above make
|
||||
# the retry cheap).
|
||||
- name: Test the C# binding
|
||||
run: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 15
|
||||
max_attempts: 2
|
||||
retry_wait_seconds: 20
|
||||
command: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
|
||||
shell: bash
|
||||
|
||||
- name: Build the C# examples
|
||||
shell: bash
|
||||
@@ -756,7 +786,7 @@ jobs:
|
||||
go:
|
||||
name: Go on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -879,7 +909,7 @@ jobs:
|
||||
r:
|
||||
name: R on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -912,10 +942,17 @@ jobs:
|
||||
r-version: "release"
|
||||
use-public-rspm: true
|
||||
|
||||
# Use the repos configured by setup-r (use-public-rspm) so Linux installs
|
||||
# binary packages — building testthat's deps from source is slow and flaky.
|
||||
- name: Install test dependency
|
||||
run: Rscript -e 'install.packages("testthat")'
|
||||
# Install the R dependencies via setup-r-dependencies: it restores a cached
|
||||
# package library (actions/cache) and pulls RSPM *binaries* instead of
|
||||
# compiling testthat / knitr and their deps from source — the slow, flaky
|
||||
# path that previously blew past the job timeout on the ubuntu runner.
|
||||
- name: Install R dependencies (cached binaries)
|
||||
uses: r-lib/actions/setup-r-dependencies@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2
|
||||
with:
|
||||
working-directory: bindings/r
|
||||
extra-packages: |
|
||||
any::testthat
|
||||
any::knitr
|
||||
|
||||
- name: Install and test the R binding
|
||||
shell: bash
|
||||
@@ -932,14 +969,39 @@ jobs:
|
||||
R CMD INSTALL bindings/r
|
||||
Rscript -e 'library(testthat); library(wickra); test_dir("bindings/r/tests/testthat", stop_on_failure = TRUE)'
|
||||
|
||||
# Full R CMD check, gated on the documentation problems r-universe surfaces
|
||||
# (undocumented exported objects, codoc mismatches) that R CMD INSTALL above
|
||||
# does not catch — exactly what shipped stale to r-universe with the 0.9.3
|
||||
# data layer. Ubuntu-only; these checks are platform-independent. Vignettes
|
||||
# are skipped here (building them needs pandoc and the vignette is exercised
|
||||
# in the next step), so the two --no-build-vignettes warnings are ignored.
|
||||
- name: R CMD check (documentation & consistency, like r-universe)
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
shell: bash
|
||||
run: |
|
||||
export WICKRA_INCLUDE_DIR="${WICKRA_INCLUDE_DIR//\\//}"
|
||||
export WICKRA_LIB_DIR="${WICKRA_LIB_DIR//\\//}"
|
||||
R CMD build bindings/r --no-build-vignettes --no-manual
|
||||
R CMD check wickra_*.tar.gz --no-manual --no-vignettes --no-tests || true
|
||||
log=$(find . -maxdepth 2 -name 00check.log | head -1)
|
||||
echo "::group::00check.log"; cat "$log"; echo "::endgroup::"
|
||||
problems=$(grep -E '\.\.\. (WARNING|ERROR)' "$log" \
|
||||
| grep -vE "checking (files in .vignettes.|package vignettes)" || true)
|
||||
if [ -n "$problems" ]; then
|
||||
echo "::error::R CMD check found problems (run roxygen2::roxygenise() in bindings/r if the docs are stale):"
|
||||
echo "$problems"
|
||||
exit 1
|
||||
fi
|
||||
echo "R CMD check: documentation and consistency clean."
|
||||
|
||||
- name: Build the vignette code
|
||||
shell: bash
|
||||
# The getting-started vignette runs at R CMD check time on r-universe /
|
||||
# CRAN (with pandoc); this job only INSTALLs, so execute the vignette's R
|
||||
# chunks here (knit, no pandoc needed) to catch a broken example before it
|
||||
# reaches the published build.
|
||||
# knitr is installed by the cached setup-r-dependencies step above.
|
||||
run: |
|
||||
Rscript -e 'install.packages("knitr", repos = Sys.getenv("RSPM", unset = "https://cloud.r-project.org"))'
|
||||
Rscript -e 'knitr::knit("bindings/r/vignettes/getting-started.Rmd", output = tempfile(fileext = ".md"), quiet = TRUE); cat("vignette code OK\n")'
|
||||
|
||||
- name: Run the offline R examples
|
||||
@@ -961,7 +1023,7 @@ jobs:
|
||||
java:
|
||||
name: Java on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 20 # backstop: cap a wedged job instead of GitHub's 6h default (slowest real job ~5 min)
|
||||
timeout-minutes: 30 # backstop: cap a wedged job instead of GitHub's 6h default (headroom for slow registry/package installs)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -1016,8 +1078,16 @@ jobs:
|
||||
|
||||
# `install` runs the archetype test suite (the real FFI boundary check) and
|
||||
# installs the binding to the local repo so the examples can resolve it.
|
||||
# Maven resolves plugins/deps from the network on a cache miss; retry so a
|
||||
# transient Central blip retries instead of failing the job.
|
||||
- name: Test and install the Java binding
|
||||
run: mvn -B -f bindings/java install
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 20
|
||||
max_attempts: 2
|
||||
retry_wait_seconds: 20
|
||||
command: mvn -B -f bindings/java install
|
||||
shell: bash
|
||||
|
||||
- name: Build the Java examples
|
||||
run: mvn -B -f examples/java compile
|
||||
@@ -1031,6 +1101,47 @@ jobs:
|
||||
mvn -B -q -f examples/java exec:exec -Dexec.mainClass="org.wickra.examples.$cls"
|
||||
done
|
||||
|
||||
# Build a Python wheel inside both the manylinux and the musllinux container,
|
||||
# mirroring the Linux wheel build in release.yml. The 3-OS Python jobs build
|
||||
# natively on the runner, which already ships system OpenSSL, so they cannot
|
||||
# catch a build-time gap that only exists inside the slim release containers —
|
||||
# exactly what broke the 0.9.3 Linux wheels (the live-binance data layer links
|
||||
# native-tls -> openssl-sys, and the containers provide no OpenSSL: manylinux
|
||||
# lacks the headers, musllinux cross-compiles against a musl sysroot without
|
||||
# OpenSSL at all). The wheels are built with the `vendored-tls` feature, which
|
||||
# statically compiles OpenSSL from source. This job exercises both container
|
||||
# builds on every PR, so the same class of breakage now fails CI, not release.
|
||||
python-wheel-container-smoke:
|
||||
name: Python wheel (${{ matrix.manylinux }} smoke)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30 # backstop: vendored OpenSSL adds a from-source compile
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
manylinux: [auto, musllinux_1_2]
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Sync root README into bindings/python so the build matches release
|
||||
run: cp README.md bindings/python/README.md
|
||||
|
||||
- uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
||||
with:
|
||||
working-directory: bindings/python
|
||||
target: x86_64
|
||||
# Keep in sync with release.yml: vendored OpenSSL for the Linux wheels.
|
||||
args: --release --out dist --features vendored-tls
|
||||
manylinux: ${{ matrix.manylinux }}
|
||||
# Building OpenSSL from source needs Perl modules (IPC::Cmd,
|
||||
# Time::Piece, ...) the minimal manylinux (CentOS 7) image lacks.
|
||||
# perl-core pulls the full distribution; the explicit names document
|
||||
# the ones OpenSSL's Configure has required. The musllinux cross image
|
||||
# ships a complete Perl and has no yum, so this is a no-op there.
|
||||
before-script-linux: |
|
||||
if command -v yum >/dev/null 2>&1; then yum install -y perl-core perl-IPC-Cmd perl-Data-Dumper perl-Time-Piece; fi
|
||||
|
||||
# The cross-library benchmark has moved to a dedicated scheduled workflow
|
||||
# (.github/workflows/bench.yml) — see audit finding R10. It runs nightly
|
||||
# at 03:00 UTC and on-demand via `workflow_dispatch`, and is no longer on
|
||||
|
||||
@@ -36,6 +36,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
cargo-publish:
|
||||
name: Publish to crates.io
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
runs-on: ubuntu-latest
|
||||
# The publish jobs run with long-lived registry tokens. Binding them to a
|
||||
# protected GitHub environment lets the org require a reviewer to approve
|
||||
@@ -139,6 +140,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
python-wheels:
|
||||
name: Build wheels (${{ matrix.target }}/${{ matrix.manylinux }} on ${{ matrix.os }})
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -184,8 +186,22 @@ jobs:
|
||||
with:
|
||||
working-directory: bindings/python
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --strip --out dist
|
||||
# The live-binance data layer links native-tls -> openssl-sys, which
|
||||
# needs OpenSSL at build time. The manylinux containers lack the headers
|
||||
# and the musllinux build cross-compiles against a musl sysroot with no
|
||||
# OpenSSL at all, so build the Linux wheels with vendored OpenSSL
|
||||
# (compiled from source, linked statically). No-op on the native
|
||||
# macOS/Windows runners, where native-tls never pulls openssl-sys. The
|
||||
# CI `python-wheel-container-smoke` job exercises both containers on PRs.
|
||||
args: --release --strip --out dist --features vendored-tls
|
||||
manylinux: ${{ matrix.manylinux }}
|
||||
# Building OpenSSL from source needs Perl modules (IPC::Cmd,
|
||||
# Time::Piece, ...) the minimal manylinux (CentOS 7) image lacks.
|
||||
# perl-core pulls the full distribution; the explicit names document
|
||||
# the ones OpenSSL's Configure has required. The musllinux cross image
|
||||
# ships a complete Perl and has no yum, so this is a no-op there.
|
||||
before-script-linux: |
|
||||
if command -v yum >/dev/null 2>&1; then yum install -y perl-core perl-IPC-Cmd perl-Data-Dumper perl-Time-Piece; fi
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
# Include manylinux in the name so the glibc and musl x86_64/aarch64
|
||||
@@ -195,6 +211,7 @@ jobs:
|
||||
|
||||
python-sdist:
|
||||
name: Build Python sdist
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
@@ -214,6 +231,7 @@ jobs:
|
||||
|
||||
python-publish:
|
||||
name: Publish to PyPI
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [python-wheels, python-sdist]
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -237,6 +255,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
node-build:
|
||||
name: Node build (${{ matrix.target }})
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -282,8 +301,13 @@ jobs:
|
||||
timeout-minutes: 6
|
||||
|
||||
- name: Install Node deps
|
||||
working-directory: bindings/node
|
||||
run: npm ci
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 20
|
||||
command: cd bindings/node && npm ci
|
||||
shell: bash
|
||||
|
||||
- name: Build native module
|
||||
working-directory: bindings/node
|
||||
@@ -298,6 +322,7 @@ jobs:
|
||||
|
||||
node-publish:
|
||||
name: Publish to npm
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: node-build
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -337,8 +362,13 @@ jobs:
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Install Node deps
|
||||
working-directory: bindings/node
|
||||
run: npm ci
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 20
|
||||
command: cd bindings/node && npm ci
|
||||
shell: bash
|
||||
|
||||
- name: Download all platform binaries
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
@@ -470,6 +500,7 @@ jobs:
|
||||
# which requires the `id-token: write` permission set at the job level.
|
||||
wasm-publish:
|
||||
name: Publish wickra-wasm to npm
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
# `id-token: write` lets npm publish embed a Sigstore provenance
|
||||
@@ -509,6 +540,10 @@ jobs:
|
||||
with:
|
||||
targets: wasm32-unknown-unknown
|
||||
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
|
||||
timeout-minutes: 6
|
||||
|
||||
- name: Install wasm-pack (latest, via prebuilt binary)
|
||||
# See the matching note in ci.yml: jetli's default installs an old
|
||||
# 0.10.x wasm-pack whose build subcommand rejects --features.
|
||||
@@ -576,6 +611,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
c-abi-build:
|
||||
name: C ABI library (${{ matrix.target }})
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -631,6 +667,7 @@ jobs:
|
||||
# workflow release.yml) exchanges the GitHub OIDC token for a short-lived key.
|
||||
csharp-publish:
|
||||
name: Publish to NuGet
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: c-abi-build
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -675,11 +712,18 @@ jobs:
|
||||
echo "staged ${RID[$target]}:"; ls -l "$dest"
|
||||
done
|
||||
|
||||
# dotnet pack restores from nuget.org first; retry so a transient restore
|
||||
# blip retries instead of failing the release.
|
||||
- name: Pack
|
||||
shell: bash
|
||||
run: |
|
||||
version="${GITHUB_REF_NAME#v}"
|
||||
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
|
||||
with:
|
||||
timeout_minutes: 15
|
||||
max_attempts: 2
|
||||
retry_wait_seconds: 20
|
||||
shell: bash
|
||||
command: |
|
||||
version="${GITHUB_REF_NAME#v}"
|
||||
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
|
||||
|
||||
# Exchange the GitHub OIDC token for a short-lived (~1h) NuGet API key.
|
||||
# 'user' is the nuget.org profile name (the package owner), not an email.
|
||||
@@ -714,6 +758,7 @@ jobs:
|
||||
# match the release tag (kept in sync by the version-bump checklist).
|
||||
java-publish:
|
||||
name: Publish to Maven Central
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: c-abi-build
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
@@ -785,6 +830,7 @@ jobs:
|
||||
# derived artifact, so its bot commit is intentionally unsigned.
|
||||
go-mirror:
|
||||
name: Mirror the Go module to wickra-go
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: c-abi-build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -868,6 +914,7 @@ jobs:
|
||||
|
||||
github-release:
|
||||
name: Attach assets to the draft GitHub Release
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
@@ -993,6 +1040,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
attestations:
|
||||
name: Attest build provenance
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [cargo-publish, python-wheels, python-sdist, github-release]
|
||||
runs-on: ubuntu-latest
|
||||
# Signed SLSA build-provenance attestations for the published crates and
|
||||
@@ -1076,6 +1124,7 @@ jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
publish-release:
|
||||
name: Publish the GitHub Release
|
||||
timeout-minutes: 45 # backstop only: release build/publish jobs compile from source (vendored OpenSSL) and must not be killed mid-build; far above the ~10 min real runtime
|
||||
needs: [github-release, attestations]
|
||||
if: always() && needs.github-release.result == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
+66
-1
@@ -7,6 +7,68 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.9.6] - 2026-06-18
|
||||
|
||||
Documentation release for the R binding. The library API and every indicator
|
||||
are unchanged from `0.9.5`; only the R package's help pages change.
|
||||
|
||||
### Fixed
|
||||
- **R package: document the data-layer exports and refresh the man pages.**
|
||||
r-universe's `R CMD check` reported two warnings against the `0.9.3` data layer
|
||||
it built for the first time in `0.9.5`: twelve undocumented exported objects
|
||||
(`BinanceFeed`, `CandleReader`, `Resampler`, `TickAggregator`,
|
||||
`fetch_binance_klines` and the `name` / `is_ready` / `warmup_period` / `push` /
|
||||
`read` generics) and a codoc mismatch on `AwesomeOscillatorHistogram` (its help
|
||||
page still listed `sma_period` after the argument was renamed to `lookback`).
|
||||
The roxygen sources existed but the `man/*.Rd` had never been regenerated; they
|
||||
are now complete, and a `push()` example that constructed a `TickAggregator`
|
||||
without its required `gap_fill` argument is fixed. CI now runs `R CMD check` so
|
||||
documentation drift fails the pull request instead of surfacing on r-universe.
|
||||
|
||||
|
||||
## [0.9.5] - 2026-06-17
|
||||
|
||||
Maintenance release. The library API and every indicator are unchanged from
|
||||
`0.9.4`; the only change that ships to users is to the R package's build script.
|
||||
The rest of the release is CI / release-pipeline hardening (dependency caching,
|
||||
job timeouts, and network-install retries) that does not affect the artifacts.
|
||||
|
||||
### Fixed
|
||||
- **R package: retry the C ABI download.** `configure` / `configure.win` fetch the
|
||||
prebuilt `wickra-c-<triple>.tar.gz` from the matching GitHub release. A freshly
|
||||
cut release can briefly return 404 while its assets propagate across the CDN
|
||||
(and a transient network blip would also fail it), so the single-shot download
|
||||
is now retried with a backoff (~2 min) before giving up. Fixes
|
||||
`cannot open URL … 404 Not Found` on r-universe / source installs taken right
|
||||
after a release.
|
||||
|
||||
|
||||
## [0.9.4] - 2026-06-17
|
||||
|
||||
Packaging fix for the `0.9.3` data layer. The library is identical to `0.9.3` on
|
||||
every platform that already published; the only additions are an opt-in
|
||||
`vendored-tls` build feature and the Linux Python wheels, which `0.9.3` could not
|
||||
build.
|
||||
|
||||
### Fixed
|
||||
- **Linux Python wheels (`manylinux` / `musllinux`) now build.** The `live-binance`
|
||||
data layer links `native-tls` -> `openssl-sys`, which needs OpenSSL at build
|
||||
time. The `manylinux` wheel containers ship no OpenSSL headers and the
|
||||
`musllinux` build cross-compiles against a musl sysroot that has no OpenSSL at
|
||||
all, so the wheels failed to compile. The Linux wheels are now built with a new
|
||||
opt-in `vendored-tls` feature that compiles OpenSSL from source and links it
|
||||
statically (no system OpenSSL required, on either libc). The native macOS and
|
||||
Windows wheels were unaffected (Security.framework / SChannel). As a result
|
||||
`0.9.3` shipped to crates.io, Maven Central, NuGet, and npm but not to PyPI;
|
||||
PyPI publishes starting with `0.9.4`.
|
||||
|
||||
### Added
|
||||
- **`vendored-tls` feature** on `wickra-data` (and the Python binding): builds the
|
||||
`live-binance` TLS stack against a statically compiled OpenSSL. Off by default;
|
||||
used by the release wheels and exercised on every PR by a `manylinux` /
|
||||
`musllinux` container build-smoke CI job.
|
||||
|
||||
|
||||
## [0.9.3] - 2026-06-17
|
||||
|
||||
### Changed
|
||||
@@ -1810,7 +1872,10 @@ public API changes.
|
||||
optional Binance live feed.
|
||||
- Bindings for Python, Node.js, and WebAssembly.
|
||||
|
||||
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.9.3...HEAD
|
||||
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.9.6...HEAD
|
||||
[0.9.6]: https://github.com/wickra-lib/wickra/compare/v0.9.5...v0.9.6
|
||||
[0.9.5]: https://github.com/wickra-lib/wickra/compare/v0.9.4...v0.9.5
|
||||
[0.9.4]: https://github.com/wickra-lib/wickra/compare/v0.9.3...v0.9.4
|
||||
[0.9.3]: https://github.com/wickra-lib/wickra/compare/v0.9.2...v0.9.3
|
||||
[0.9.2]: https://github.com/wickra-lib/wickra/compare/v0.9.1...v0.9.2
|
||||
[0.9.1]: https://github.com/wickra-lib/wickra/compare/v0.9.0...v0.9.1
|
||||
|
||||
Generated
+19
-9
@@ -907,6 +907,15 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "300.5.4+3.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.116"
|
||||
@@ -915,6 +924,7 @@ checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
@@ -1775,7 +1785,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"criterion",
|
||||
@@ -1786,7 +1796,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-bench"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"kand",
|
||||
@@ -1798,7 +1808,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-c"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"tokio",
|
||||
"wickra-core",
|
||||
@@ -1807,7 +1817,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-core"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"proptest",
|
||||
@@ -1817,7 +1827,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-data"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"csv",
|
||||
@@ -1836,7 +1846,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-examples"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"tokio",
|
||||
@@ -1846,7 +1856,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-node"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"napi",
|
||||
"napi-build",
|
||||
@@ -1858,7 +1868,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-python"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"pyo3",
|
||||
@@ -1869,7 +1879,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wickra-wasm"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ members = [
|
||||
exclude = ["fuzz"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
authors = ["kingchenc <support@wickra.org>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.86"
|
||||
@@ -26,8 +26,8 @@ keywords = ["finance", "trading", "indicators", "technical-analysis", "ta"]
|
||||
categories = ["finance", "mathematics", "science"]
|
||||
|
||||
[workspace.dependencies]
|
||||
wickra-core = { path = "crates/wickra-core", version = "0.9.3" }
|
||||
wickra-data = { path = "crates/wickra-data", version = "0.9.3" }
|
||||
wickra-core = { path = "crates/wickra-core", version = "0.9.6" }
|
||||
wickra-data = { path = "crates/wickra-data", version = "0.9.6" }
|
||||
|
||||
thiserror = "2"
|
||||
rayon = "1.10"
|
||||
|
||||
+3
-3
@@ -2,13 +2,13 @@
|
||||
|
||||
## Supported versions
|
||||
|
||||
Wickra is pre-1.0. Security fixes are applied to the latest released `0.9.3`
|
||||
Wickra is pre-1.0. Security fixes are applied to the latest released `0.9.6`
|
||||
version only; please upgrade to the newest release before reporting an issue.
|
||||
|
||||
| Version | Supported |
|
||||
| --- | --- |
|
||||
| 0.9.3 (latest) | :white_check_mark: |
|
||||
| < 0.9.3 | :x: |
|
||||
| 0.9.6 (latest) | :white_check_mark: |
|
||||
| < 0.9.6 | :x: |
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<!-- NuGet package metadata -->
|
||||
<PackageId>Wickra</PackageId>
|
||||
<Version>0.9.3</Version>
|
||||
<Version>0.9.6</Version>
|
||||
<Authors>kingchenc</Authors>
|
||||
<Description>High-performance streaming technical-analysis indicators (514 indicators) for .NET, backed by the native Rust core via the Wickra C ABI.</Description>
|
||||
<PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression>
|
||||
|
||||
@@ -30,14 +30,14 @@ Maven:
|
||||
<dependency>
|
||||
<groupId>org.wickra</groupId>
|
||||
<artifactId>wickra</artifactId>
|
||||
<version>0.9.3</version>
|
||||
<version>0.9.6</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Gradle:
|
||||
|
||||
```kotlin
|
||||
implementation("org.wickra:wickra:0.9.3")
|
||||
implementation("org.wickra:wickra:0.9.6")
|
||||
```
|
||||
|
||||
The native library ships prebuilt per platform (Linux, macOS, Windows — x64 and
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.wickra</groupId>
|
||||
<artifactId>wickra</artifactId>
|
||||
<version>0.9.3</version>
|
||||
<version>0.9.6</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Wickra</name>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wickra-darwin-arm64",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"description": "Native binding for wickra (macOS Apple Silicon). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||
"main": "wickra.darwin-arm64.node",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wickra-darwin-x64",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"description": "Native binding for wickra (macOS Intel). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||
"main": "wickra.darwin-x64.node",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wickra-linux-arm64-gnu",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"description": "Native binding for wickra (linux arm64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||
"main": "wickra.linux-arm64-gnu.node",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wickra-linux-x64-gnu",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"description": "Native binding for wickra (linux x64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||
"main": "wickra.linux-x64-gnu.node",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wickra-win32-arm64-msvc",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"description": "Native binding for wickra (Windows arm64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||
"main": "wickra.win32-arm64-msvc.node",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wickra-win32-x64-msvc",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"description": "Native binding for wickra (Windows x64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
|
||||
"main": "wickra.win32-x64-msvc.node",
|
||||
"files": [
|
||||
|
||||
Generated
+20
-20
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "wickra",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wickra",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.18.0"
|
||||
@@ -15,12 +15,12 @@
|
||||
"node": ">= 20"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"wickra-darwin-arm64": "0.9.3",
|
||||
"wickra-darwin-x64": "0.9.3",
|
||||
"wickra-linux-arm64-gnu": "0.9.3",
|
||||
"wickra-linux-x64-gnu": "0.9.3",
|
||||
"wickra-win32-arm64-msvc": "0.9.3",
|
||||
"wickra-win32-x64-msvc": "0.9.3"
|
||||
"wickra-darwin-arm64": "0.9.6",
|
||||
"wickra-darwin-x64": "0.9.6",
|
||||
"wickra-linux-arm64-gnu": "0.9.6",
|
||||
"wickra-linux-x64-gnu": "0.9.6",
|
||||
"wickra-win32-arm64-msvc": "0.9.6",
|
||||
"wickra-win32-x64-msvc": "0.9.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/cli": {
|
||||
@@ -41,8 +41,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/wickra-darwin-arm64": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/wickra-darwin-arm64/-/wickra-darwin-arm64-0.9.3.tgz",
|
||||
"version": "0.9.6",
|
||||
"resolved": "https://registry.npmjs.org/wickra-darwin-arm64/-/wickra-darwin-arm64-0.9.6.tgz",
|
||||
"integrity": "sha512-4eZiBR/yGUdr4nzhEUFy2i69XgNx64iI2ax/LPamsThgylC0KpHOZKK19QzJ2d9KbK4C8nMjME5FLuR+4GNEwQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
@@ -57,8 +57,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/wickra-darwin-x64": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/wickra-darwin-x64/-/wickra-darwin-x64-0.9.3.tgz",
|
||||
"version": "0.9.6",
|
||||
"resolved": "https://registry.npmjs.org/wickra-darwin-x64/-/wickra-darwin-x64-0.9.6.tgz",
|
||||
"integrity": "sha512-6hf8zI3QPjTFp4zCpmgUwDvNtu6jHqNUHKD5e55POo0CgA52HkpyxSPtVm8TGTIZDI7kPjlbOdBM8CJ76mmXwA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
@@ -73,8 +73,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/wickra-linux-arm64-gnu": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/wickra-linux-arm64-gnu/-/wickra-linux-arm64-gnu-0.9.3.tgz",
|
||||
"version": "0.9.6",
|
||||
"resolved": "https://registry.npmjs.org/wickra-linux-arm64-gnu/-/wickra-linux-arm64-gnu-0.9.6.tgz",
|
||||
"integrity": "sha512-kSe6y0xBMSiqdPLXNjwop5WZdHtvdBNKSEBCwZ4hFq33p4apW25/wrlzv9/oDuyD4kuPabJEhCCnFOplh58CUg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
@@ -89,8 +89,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/wickra-linux-x64-gnu": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/wickra-linux-x64-gnu/-/wickra-linux-x64-gnu-0.9.3.tgz",
|
||||
"version": "0.9.6",
|
||||
"resolved": "https://registry.npmjs.org/wickra-linux-x64-gnu/-/wickra-linux-x64-gnu-0.9.6.tgz",
|
||||
"integrity": "sha512-tWBWS4qz7hxM4xnpFb59bhf6TaLwXq0Z3jEa/2l7r8PiHA94g8r8S53NRMiT+4yiL5hSWe/nUiC/YXdRrhEZ4g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
@@ -105,8 +105,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/wickra-win32-arm64-msvc": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/wickra-win32-arm64-msvc/-/wickra-win32-arm64-msvc-0.9.3.tgz",
|
||||
"version": "0.9.6",
|
||||
"resolved": "https://registry.npmjs.org/wickra-win32-arm64-msvc/-/wickra-win32-arm64-msvc-0.9.6.tgz",
|
||||
"integrity": "sha512-EXIckHxAtF75PUGDKRzXyqMe9ldP0JjSdu68WFN6iJfp+McYrGu6h40TEJlQ/oUEIoPqiZB/xhVyo/el5Lg7zw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
@@ -121,8 +121,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/wickra-win32-x64-msvc": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/wickra-win32-x64-msvc/-/wickra-win32-x64-msvc-0.9.3.tgz",
|
||||
"version": "0.9.6",
|
||||
"resolved": "https://registry.npmjs.org/wickra-win32-x64-msvc/-/wickra-win32-x64-msvc-0.9.6.tgz",
|
||||
"integrity": "sha512-Yfsqq1Xwp6hdxMyLze411vNdo7BDwI6+lPSe7A9XdqyPecNDbtKwYLpsal2r8EHbNzqM+R8XnuRtUaEQS5VlUQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wickra",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"description": "Streaming-first technical indicators: incremental, fast, install-free. Node bindings powered by Rust.",
|
||||
"author": "kingchenc <support@wickra.org>",
|
||||
"main": "index.js",
|
||||
@@ -47,12 +47,12 @@
|
||||
"node": ">= 20"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"wickra-linux-x64-gnu": "0.9.3",
|
||||
"wickra-linux-arm64-gnu": "0.9.3",
|
||||
"wickra-darwin-x64": "0.9.3",
|
||||
"wickra-darwin-arm64": "0.9.3",
|
||||
"wickra-win32-x64-msvc": "0.9.3",
|
||||
"wickra-win32-arm64-msvc": "0.9.3"
|
||||
"wickra-linux-x64-gnu": "0.9.6",
|
||||
"wickra-linux-arm64-gnu": "0.9.6",
|
||||
"wickra-darwin-x64": "0.9.6",
|
||||
"wickra-darwin-arm64": "0.9.6",
|
||||
"wickra-win32-x64-msvc": "0.9.6",
|
||||
"wickra-win32-arm64-msvc": "0.9.6"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "napi build --platform --release",
|
||||
|
||||
@@ -17,6 +17,13 @@ publish = false
|
||||
name = "_wickra"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
# Build the bundled data layer against a statically compiled OpenSSL. The
|
||||
# release workflow (and the manylinux/musllinux CI smoke job) enable this so the
|
||||
# Linux wheels do not depend on system OpenSSL at build time. See the
|
||||
# `vendored-tls` feature in wickra-data for the rationale.
|
||||
vendored-tls = ["wickra-data/vendored-tls"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
||||
|
||||
[project]
|
||||
name = "wickra"
|
||||
version = "0.9.3"
|
||||
version = "0.9.6"
|
||||
description = "Streaming-first technical indicators: incremental, fast, install-free."
|
||||
readme = "README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Package: wickra
|
||||
Type: Package
|
||||
Title: Streaming-First Technical Indicators
|
||||
Version: 0.9.3
|
||||
Version: 0.9.6
|
||||
Authors@R: person("Wickra contributors", role = c("aut", "cre"), email = "support@wickra.org")
|
||||
Description: R bindings for the Wickra technical-analysis library over its C ABI
|
||||
hub. Exposes 514 indicators, each an O(1) streaming state machine shared with
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Generated by roxygen2: do not edit by hand
|
||||
|
||||
S3method(base::flush,wickra_indicator)
|
||||
S3method(batch,wickra_indicator)
|
||||
S3method(flush,wickra_indicator)
|
||||
S3method(is_ready,wickra_indicator)
|
||||
S3method(name,wickra_indicator)
|
||||
S3method(push,wickra_indicator)
|
||||
|
||||
@@ -479,7 +479,14 @@ Camarilla <- function() {
|
||||
.wk_obj("camarilla", ptr, "Camarilla")
|
||||
}
|
||||
|
||||
#' CandleReader: parse OHLCV candles from a CSV string
|
||||
#' Parse OHLCV candles from a CSV string
|
||||
#'
|
||||
#' Builds a reader over an in-memory CSV string with a header row and OHLCV
|
||||
#' columns. Pass the result to [read()] to get every parsed candle.
|
||||
#'
|
||||
#' @param csv A length-one character string of CSV text (a header row followed
|
||||
#' by OHLCV data rows).
|
||||
#' @return A `wickra_indicator` candle reader; read its candles with [read()].
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
CandleReader <- function(csv) {
|
||||
@@ -2687,7 +2694,14 @@ RenkoTrailingStop <- function(block_size) {
|
||||
.wk_obj("renko_trailing_stop", ptr, "RenkoTrailingStop")
|
||||
}
|
||||
|
||||
#' Resampler indicator
|
||||
#' Resample candles to a higher timeframe
|
||||
#'
|
||||
#' Aggregates a stream of candles into higher-timeframe bars. Feed candles with
|
||||
#' [update()] (it returns a completed higher-timeframe bar, or `NULL` while the
|
||||
#' current bar is still open) and emit the final, still-open bar with [flush()].
|
||||
#'
|
||||
#' @param timeframe Integer number of input candles per higher-timeframe bar.
|
||||
#' @return A `wickra_indicator` resampler.
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
Resampler <- function(timeframe) {
|
||||
@@ -3487,7 +3501,15 @@ Thrusting <- function() {
|
||||
.wk_obj("thrusting", ptr, "Thrusting")
|
||||
}
|
||||
|
||||
#' TickAggregator indicator
|
||||
#' Aggregate trade ticks into time-bucketed candles
|
||||
#'
|
||||
#' Builds OHLCV candles from a stream of trade ticks. Feed ticks with [push()],
|
||||
#' which returns the candles closed by that tick.
|
||||
#'
|
||||
#' @param bucket Time-bucket width, in the same unit as the tick timestamps.
|
||||
#' @param gap_fill Logical; if `TRUE`, empty buckets with no trades are still
|
||||
#' emitted (carried forward) instead of skipped.
|
||||
#' @return A `wickra_indicator` tick aggregator; feed it ticks with [push()].
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
TickAggregator <- function(bucket, gap_fill) {
|
||||
@@ -4151,6 +4173,13 @@ Zlema <- function(period) {
|
||||
#' 15 = 1M). `base_url` overrides the endpoint (`NULL` = production). Not
|
||||
#' available in the wasm (r-universe/webR) build, which has no raw sockets.
|
||||
#'
|
||||
#' @param symbols Comma-separated trading symbols (case-insensitive), e.g.
|
||||
#' `"btcusdt,ethusdt"`.
|
||||
#' @param interval Integer interval code `0:15` (`0` = 1s, `1` = 1m, ...,
|
||||
#' `12` = 1d, `13` = 3d, `14` = 1w, `15` = 1M).
|
||||
#' @param base_url Optional endpoint override; `NULL` uses production.
|
||||
#' @return A `wickra_binance_feed`; poll it with [binance_next()] and close it
|
||||
#' with [binance_close()].
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
BinanceFeed <- function(symbols, interval, base_url = NULL) {
|
||||
@@ -4165,6 +4194,10 @@ BinanceFeed <- function(symbols, interval, base_url = NULL) {
|
||||
#' `high`, `low`, `close`, `volume`, `open_time`, `is_closed`) when an event
|
||||
#' arrives, or `NULL` on timeout. Errors once the stream is closed.
|
||||
#'
|
||||
#' @param feed A `wickra_binance_feed` created by [BinanceFeed()].
|
||||
#' @param timeout_ms Poll timeout in milliseconds.
|
||||
#' @return A named list (`symbol`, `open`, `high`, `low`, `close`, `volume`,
|
||||
#' `open_time`, `is_closed`) for an event, or `NULL` on timeout.
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
binance_next <- function(feed, timeout_ms = 1000) {
|
||||
@@ -4173,6 +4206,8 @@ binance_next <- function(feed, timeout_ms = 1000) {
|
||||
|
||||
#' Close a Binance feed
|
||||
#'
|
||||
#' @param feed A `wickra_binance_feed` created by [BinanceFeed()].
|
||||
#' @return `NULL`, invisibly.
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
binance_close <- function(feed) {
|
||||
@@ -4190,6 +4225,14 @@ binance_close <- function(feed) {
|
||||
#' `volume`, `timestamp`. Blocks until the response arrives. Not available in the
|
||||
#' wasm (r-universe/webR) build, which has no raw sockets.
|
||||
#'
|
||||
#' @param symbol Trading symbol (case-insensitive), e.g. `"btcusdt"`.
|
||||
#' @param interval Integer interval code `0:15` (see [BinanceFeed()]).
|
||||
#' @param limit Number of klines to fetch (`1:1000`).
|
||||
#' @param start_ms,end_ms Optional inclusive Unix-millisecond bounds; a negative
|
||||
#' value means unset.
|
||||
#' @param base_url Optional host override; `NULL` uses production.
|
||||
#' @return An `n x 6` numeric matrix with columns `open`, `high`, `low`,
|
||||
#' `close`, `volume`, `timestamp`.
|
||||
#' @keywords internal
|
||||
#' @export
|
||||
fetch_binance_klines <- function(symbol, interval, limit, start_ms = -1,
|
||||
|
||||
@@ -151,7 +151,7 @@ name.wickra_indicator <- function(object) {
|
||||
#' @param timestamp Trade timestamp, in the same unit as the aggregator bucket.
|
||||
#' @return A numeric matrix with six named columns (possibly zero rows).
|
||||
#' @examples
|
||||
#' agg <- TickAggregator(1000)
|
||||
#' agg <- TickAggregator(1000, FALSE)
|
||||
#' push(agg, 100, 1, 0)
|
||||
#' push(agg, 102, 1, 1000) # closes the first bucket
|
||||
#' @export
|
||||
|
||||
Vendored
+22
-4
@@ -14,6 +14,26 @@ set -e
|
||||
inc=""
|
||||
lib=""
|
||||
|
||||
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
|
||||
# across the CDN, and a transient network blip should not fail the build either.
|
||||
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
|
||||
# on the first miss.
|
||||
wickra_download() {
|
||||
_url="$1"
|
||||
_dest="$2"
|
||||
_attempt=1
|
||||
while [ "${_attempt}" -le 6 ]; do
|
||||
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
|
||||
return 0
|
||||
fi
|
||||
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
|
||||
sleep 20
|
||||
_attempt=$((_attempt + 1))
|
||||
done
|
||||
echo "wickra: failed to download ${_url} after 6 attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
# WebAssembly (r-universe / webR): there is no prebuilt wasm C ABI to download,
|
||||
# but the build image ships cargo (/usr/local/cargo/bin) and emscripten
|
||||
# (EMSDK on PATH), so build the C ABI staticlib from source for
|
||||
@@ -26,8 +46,7 @@ if [ "$(uname -s)" = "Emscripten" ]; then
|
||||
echo "wickra: building C ABI from source for wasm32-unknown-emscripten (v${version})"
|
||||
build=$(mktemp -d)
|
||||
url="https://github.com/wickra-lib/wickra/archive/refs/tags/v${version}.tar.gz"
|
||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', '${build}/src.tar.gz', mode = 'wb', quiet = TRUE)" \
|
||||
|| { echo "wickra: failed to download source ${url}"; exit 1; }
|
||||
wickra_download "${url}" "${build}/src.tar.gz" || exit 1
|
||||
"${R_HOME}/bin/Rscript" -e "untar('${build}/src.tar.gz', exdir = '${build}')"
|
||||
root="${build}/wickra-${version}"
|
||||
rustup target add wasm32-unknown-emscripten 2>/dev/null || true
|
||||
@@ -73,8 +92,7 @@ else
|
||||
esac
|
||||
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
||||
echo "wickra: downloading C ABI ${triple} for v${version}"
|
||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \
|
||||
|| { echo "wickra: failed to download ${url}"; exit 1; }
|
||||
wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|
||||
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
||||
inc="src/wickra-c/wickra-c-${triple}/include"
|
||||
lib="src/wickra-c/wickra-c-${triple}/lib"
|
||||
|
||||
@@ -10,6 +10,26 @@
|
||||
# WICKRA_LIB_DIR to build against a locally built C ABI instead (dev override).
|
||||
set -e
|
||||
|
||||
# A freshly-cut GitHub release can briefly return 404 while its assets propagate
|
||||
# across the CDN, and a transient network blip should not fail the build either.
|
||||
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
|
||||
# on the first miss.
|
||||
wickra_download() {
|
||||
_url="$1"
|
||||
_dest="$2"
|
||||
_attempt=1
|
||||
while [ "${_attempt}" -le 6 ]; do
|
||||
if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
|
||||
return 0
|
||||
fi
|
||||
echo "wickra: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating — retrying in 20s..."
|
||||
sleep 20
|
||||
_attempt=$((_attempt + 1))
|
||||
done
|
||||
echo "wickra: failed to download ${_url} after 6 attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ -n "${WICKRA_INCLUDE_DIR}" ] && [ -n "${WICKRA_LIB_DIR}" ]; then
|
||||
echo "wickra: using C ABI from WICKRA_INCLUDE_DIR / WICKRA_LIB_DIR (dev override)"
|
||||
inc="${WICKRA_INCLUDE_DIR}"
|
||||
@@ -24,8 +44,7 @@ else
|
||||
esac
|
||||
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
|
||||
echo "wickra: downloading C ABI ${triple} for v${version}"
|
||||
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \
|
||||
|| { echo "wickra: failed to download ${url}"; exit 1; }
|
||||
wickra_download "${url}" "src/wickra-c.tar.gz" || exit 1
|
||||
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
|
||||
inc="src/wickra-c/wickra-c-${triple}/include"
|
||||
lib="src/wickra-c/wickra-c-${triple}/lib"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
\alias{AwesomeOscillatorHistogram}
|
||||
\title{AwesomeOscillatorHistogram indicator}
|
||||
\usage{
|
||||
AwesomeOscillatorHistogram(fast, slow, sma_period)
|
||||
AwesomeOscillatorHistogram(fast, slow, lookback)
|
||||
}
|
||||
\description{
|
||||
AwesomeOscillatorHistogram indicator
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/indicators.R
|
||||
\name{BinanceFeed}
|
||||
\alias{BinanceFeed}
|
||||
\title{Connect to a live Binance kline feed}
|
||||
\usage{
|
||||
BinanceFeed(symbols, interval, base_url = NULL)
|
||||
}
|
||||
\arguments{
|
||||
\item{symbols}{Comma-separated trading symbols (case-insensitive), e.g.
|
||||
\code{"btcusdt,ethusdt"}.}
|
||||
|
||||
\item{interval}{Integer interval code \code{0:15} (\code{0} = 1s, \code{1} = 1m, ...,
|
||||
\code{12} = 1d, \code{13} = 3d, \code{14} = 1w, \code{15} = 1M).}
|
||||
|
||||
\item{base_url}{Optional endpoint override; \code{NULL} uses production.}
|
||||
}
|
||||
\value{
|
||||
A \code{wickra_binance_feed}; poll it with \code{\link[=binance_next]{binance_next()}} and close it
|
||||
with \code{\link[=binance_close]{binance_close()}}.
|
||||
}
|
||||
\description{
|
||||
Opens a live Binance kline stream for one or more comma-separated \code{symbols}
|
||||
(case-insensitive) at the given \code{interval} code (an integer \code{0:15}, the same
|
||||
order as the other bindings: 0 = 1s, 1 = 1m, ... 12 = 1d, 13 = 3d, 14 = 1w,
|
||||
15 = 1M). \code{base_url} overrides the endpoint (\code{NULL} = production). Not
|
||||
available in the wasm (r-universe/webR) build, which has no raw sockets.
|
||||
}
|
||||
\keyword{internal}
|
||||
@@ -0,0 +1,20 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/indicators.R
|
||||
\name{CandleReader}
|
||||
\alias{CandleReader}
|
||||
\title{Parse OHLCV candles from a CSV string}
|
||||
\usage{
|
||||
CandleReader(csv)
|
||||
}
|
||||
\arguments{
|
||||
\item{csv}{A length-one character string of CSV text (a header row followed
|
||||
by OHLCV data rows).}
|
||||
}
|
||||
\value{
|
||||
A \code{wickra_indicator} candle reader; read its candles with \code{\link[=read]{read()}}.
|
||||
}
|
||||
\description{
|
||||
Builds a reader over an in-memory CSV string with a header row and OHLCV
|
||||
columns. Pass the result to \code{\link[=read]{read()}} to get every parsed candle.
|
||||
}
|
||||
\keyword{internal}
|
||||
@@ -0,0 +1,20 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/indicators.R
|
||||
\name{Resampler}
|
||||
\alias{Resampler}
|
||||
\title{Resample candles to a higher timeframe}
|
||||
\usage{
|
||||
Resampler(timeframe)
|
||||
}
|
||||
\arguments{
|
||||
\item{timeframe}{Integer number of input candles per higher-timeframe bar.}
|
||||
}
|
||||
\value{
|
||||
A \code{wickra_indicator} resampler.
|
||||
}
|
||||
\description{
|
||||
Aggregates a stream of candles into higher-timeframe bars. Feed candles with
|
||||
\code{\link[=update]{update()}} (it returns a completed higher-timeframe bar, or \code{NULL} while the
|
||||
current bar is still open) and emit the final, still-open bar with \code{\link[=flush]{flush()}}.
|
||||
}
|
||||
\keyword{internal}
|
||||
@@ -0,0 +1,22 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/indicators.R
|
||||
\name{TickAggregator}
|
||||
\alias{TickAggregator}
|
||||
\title{Aggregate trade ticks into time-bucketed candles}
|
||||
\usage{
|
||||
TickAggregator(bucket, gap_fill)
|
||||
}
|
||||
\arguments{
|
||||
\item{bucket}{Time-bucket width, in the same unit as the tick timestamps.}
|
||||
|
||||
\item{gap_fill}{Logical; if \code{TRUE}, empty buckets with no trades are still
|
||||
emitted (carried forward) instead of skipped.}
|
||||
}
|
||||
\value{
|
||||
A \code{wickra_indicator} tick aggregator; feed it ticks with \code{\link[=push]{push()}}.
|
||||
}
|
||||
\description{
|
||||
Builds OHLCV candles from a stream of trade ticks. Feed ticks with \code{\link[=push]{push()}},
|
||||
which returns the candles closed by that tick.
|
||||
}
|
||||
\keyword{internal}
|
||||
@@ -0,0 +1,18 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/indicators.R
|
||||
\name{binance_close}
|
||||
\alias{binance_close}
|
||||
\title{Close a Binance feed}
|
||||
\usage{
|
||||
binance_close(feed)
|
||||
}
|
||||
\arguments{
|
||||
\item{feed}{A \code{wickra_binance_feed} created by \code{\link[=BinanceFeed]{BinanceFeed()}}.}
|
||||
}
|
||||
\value{
|
||||
\code{NULL}, invisibly.
|
||||
}
|
||||
\description{
|
||||
Close a Binance feed
|
||||
}
|
||||
\keyword{internal}
|
||||
@@ -0,0 +1,23 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/indicators.R
|
||||
\name{binance_next}
|
||||
\alias{binance_next}
|
||||
\title{Poll a Binance feed for the next kline event}
|
||||
\usage{
|
||||
binance_next(feed, timeout_ms = 1000)
|
||||
}
|
||||
\arguments{
|
||||
\item{feed}{A \code{wickra_binance_feed} created by \code{\link[=BinanceFeed]{BinanceFeed()}}.}
|
||||
|
||||
\item{timeout_ms}{Poll timeout in milliseconds.}
|
||||
}
|
||||
\value{
|
||||
A named list (\code{symbol}, \code{open}, \code{high}, \code{low}, \code{close}, \code{volume},
|
||||
\code{open_time}, \code{is_closed}) for an event, or \code{NULL} on timeout.
|
||||
}
|
||||
\description{
|
||||
Waits up to \code{timeout_ms} milliseconds. Returns a named list (\code{symbol}, \code{open},
|
||||
\code{high}, \code{low}, \code{close}, \code{volume}, \code{open_time}, \code{is_closed}) when an event
|
||||
arrives, or \code{NULL} on timeout. Errors once the stream is closed.
|
||||
}
|
||||
\keyword{internal}
|
||||
@@ -0,0 +1,41 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/indicators.R
|
||||
\name{fetch_binance_klines}
|
||||
\alias{fetch_binance_klines}
|
||||
\title{Fetch historical Binance klines over REST}
|
||||
\usage{
|
||||
fetch_binance_klines(
|
||||
symbol,
|
||||
interval,
|
||||
limit,
|
||||
start_ms = -1,
|
||||
end_ms = -1,
|
||||
base_url = NULL
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
\item{symbol}{Trading symbol (case-insensitive), e.g. \code{"btcusdt"}.}
|
||||
|
||||
\item{interval}{Integer interval code \code{0:15} (see \code{\link[=BinanceFeed]{BinanceFeed()}}).}
|
||||
|
||||
\item{limit}{Number of klines to fetch (\code{1:1000}).}
|
||||
|
||||
\item{start_ms, end_ms}{Optional inclusive Unix-millisecond bounds; a negative
|
||||
value means unset.}
|
||||
|
||||
\item{base_url}{Optional host override; \code{NULL} uses production.}
|
||||
}
|
||||
\value{
|
||||
An \verb{n x 6} numeric matrix with columns \code{open}, \code{high}, \code{low},
|
||||
\code{close}, \code{volume}, \code{timestamp}.
|
||||
}
|
||||
\description{
|
||||
Downloads up to \code{limit} (\code{1:1000}) historical klines for \code{symbol} at the given
|
||||
\code{interval} code (an integer \code{0:15}, the same order as the other bindings).
|
||||
\code{start_ms}/\code{end_ms} are optional inclusive Unix-millisecond bounds (a negative
|
||||
value means unset); \code{base_url} overrides the host (\code{NULL} = production). Returns
|
||||
an \verb{n x 6} numeric matrix with columns \code{open}, \code{high}, \code{low}, \code{close},
|
||||
\code{volume}, \code{timestamp}. Blocks until the response arrives. Not available in the
|
||||
wasm (r-universe/webR) build, which has no raw sockets.
|
||||
}
|
||||
\keyword{internal}
|
||||
@@ -0,0 +1,25 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/methods.R
|
||||
\name{flush.wickra_indicator}
|
||||
\alias{flush.wickra_indicator}
|
||||
\title{Flush a resampler's final candle}
|
||||
\usage{
|
||||
\method{flush}{wickra_indicator}(con)
|
||||
}
|
||||
\arguments{
|
||||
\item{con}{A \code{wickra_indicator} created by \code{\link[=Resampler]{Resampler()}}.}
|
||||
}
|
||||
\value{
|
||||
A named numeric vector (\code{open}, \code{high}, \code{low}, \code{close}, \code{volume},
|
||||
\code{timestamp}), or \code{NULL} if nothing is pending.
|
||||
}
|
||||
\description{
|
||||
Emit the final, still-open candle a \code{\link[=Resampler]{Resampler()}} is aggregating (the partial
|
||||
higher-timeframe bar that no later input has closed yet). Extends the base
|
||||
generic \code{\link[base:flush]{base::flush()}}.
|
||||
}
|
||||
\examples{
|
||||
r <- Resampler(5)
|
||||
for (t in 0:6) update(r, 100 + t, 101 + t, 99 + t, 100 + t, 10, t)
|
||||
flush(r)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/methods.R
|
||||
\name{is_ready}
|
||||
\alias{is_ready}
|
||||
\alias{is_ready.wickra_indicator}
|
||||
\title{Whether an indicator has consumed enough input to emit a value}
|
||||
\usage{
|
||||
is_ready(object)
|
||||
|
||||
\method{is_ready}{wickra_indicator}(object)
|
||||
}
|
||||
\arguments{
|
||||
\item{object}{A \code{wickra_indicator}.}
|
||||
}
|
||||
\value{
|
||||
A single logical.
|
||||
}
|
||||
\description{
|
||||
Not available for the alt-chart bar builders, which have no warmup.
|
||||
}
|
||||
\examples{
|
||||
sma <- Sma(3)
|
||||
is_ready(sma) # FALSE
|
||||
for (x in c(1, 2, 3)) update(sma, x)
|
||||
is_ready(sma) # TRUE
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/methods.R
|
||||
\name{name}
|
||||
\alias{name}
|
||||
\alias{name.wickra_indicator}
|
||||
\title{Canonical name of an indicator}
|
||||
\usage{
|
||||
name(object)
|
||||
|
||||
\method{name}{wickra_indicator}(object)
|
||||
}
|
||||
\arguments{
|
||||
\item{object}{A \code{wickra_indicator}.}
|
||||
}
|
||||
\value{
|
||||
A single character string.
|
||||
}
|
||||
\description{
|
||||
Returns the stable, human-readable name of the indicator (the same name
|
||||
reported by every other Wickra binding), e.g. \code{"SMA"} for \code{\link[=Sma]{Sma()}}.
|
||||
}
|
||||
\examples{
|
||||
name(Sma(14)) # "SMA"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/methods.R
|
||||
\name{push}
|
||||
\alias{push}
|
||||
\alias{push.wickra_indicator}
|
||||
\title{Push a trade tick into a tick aggregator}
|
||||
\usage{
|
||||
push(object, price, size, timestamp)
|
||||
|
||||
\method{push}{wickra_indicator}(object, price, size, timestamp)
|
||||
}
|
||||
\arguments{
|
||||
\item{object}{A \code{wickra_indicator} created by \code{\link[=TickAggregator]{TickAggregator()}}.}
|
||||
|
||||
\item{price}{Trade price.}
|
||||
|
||||
\item{size}{Trade size (volume).}
|
||||
|
||||
\item{timestamp}{Trade timestamp, in the same unit as the aggregator bucket.}
|
||||
}
|
||||
\value{
|
||||
A numeric matrix with six named columns (possibly zero rows).
|
||||
}
|
||||
\description{
|
||||
Feeds one trade tick to a \code{\link[=TickAggregator]{TickAggregator()}} and returns the candles it
|
||||
closed as a numeric matrix with columns \code{open}, \code{high}, \code{low}, \code{close},
|
||||
\code{volume}, \code{timestamp} (zero rows while the open bar merely grows).
|
||||
}
|
||||
\examples{
|
||||
agg <- TickAggregator(1000, FALSE)
|
||||
push(agg, 100, 1, 0)
|
||||
push(agg, 102, 1, 1000) # closes the first bucket
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/methods.R
|
||||
\name{read}
|
||||
\alias{read}
|
||||
\alias{read.wickra_indicator}
|
||||
\title{Read every candle parsed by a CSV candle reader}
|
||||
\usage{
|
||||
read(object)
|
||||
|
||||
\method{read}{wickra_indicator}(object)
|
||||
}
|
||||
\arguments{
|
||||
\item{object}{A \code{wickra_indicator} created by \code{\link[=CandleReader]{CandleReader()}}.}
|
||||
}
|
||||
\value{
|
||||
A numeric matrix with six named columns (zero rows for an empty CSV).
|
||||
}
|
||||
\description{
|
||||
Returns all the candles a \code{\link[=CandleReader]{CandleReader()}} parsed from its CSV, as a numeric
|
||||
matrix with columns \code{open}, \code{high}, \code{low}, \code{close}, \code{volume}, \code{timestamp}.
|
||||
}
|
||||
\examples{
|
||||
r <- CandleReader("timestamp,open,high,low,close,volume\n0,100,101,99,100.5,10\n")
|
||||
read(r)
|
||||
}
|
||||
@@ -7,12 +7,12 @@
|
||||
\format{
|
||||
A data frame with 250 rows and 6 columns:
|
||||
\describe{
|
||||
\item{date}{Trading date (\code{Date}).}
|
||||
\item{open}{Opening price.}
|
||||
\item{high}{Session high.}
|
||||
\item{low}{Session low.}
|
||||
\item{close}{Closing price.}
|
||||
\item{volume}{Traded volume.}
|
||||
\item{date}{Trading date (\code{Date}).}
|
||||
\item{open}{Opening price.}
|
||||
\item{high}{Session high.}
|
||||
\item{low}{Session low.}
|
||||
\item{close}{Closing price.}
|
||||
\item{volume}{Traded volume.}
|
||||
}
|
||||
}
|
||||
\usage{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/methods.R
|
||||
\name{warmup_period}
|
||||
\alias{warmup_period}
|
||||
\alias{warmup_period.wickra_indicator}
|
||||
\title{Number of updates an indicator needs before it produces a value}
|
||||
\usage{
|
||||
warmup_period(object)
|
||||
|
||||
\method{warmup_period}{wickra_indicator}(object)
|
||||
}
|
||||
\arguments{
|
||||
\item{object}{A \code{wickra_indicator}.}
|
||||
}
|
||||
\value{
|
||||
A single integer: the warmup period.
|
||||
}
|
||||
\description{
|
||||
Not available for the alt-chart bar builders (\code{\link[=RenkoBars]{RenkoBars()}}, \code{\link[=KagiBars]{KagiBars()}},
|
||||
\code{\link[=PointAndFigureBars]{PointAndFigureBars()}}, …), which have no warmup.
|
||||
}
|
||||
\examples{
|
||||
warmup_period(Sma(14)) # 14
|
||||
}
|
||||
@@ -18,6 +18,7 @@ Useful links:
|
||||
\itemize{
|
||||
\item \url{https://github.com/wickra-lib/wickra}
|
||||
\item \url{https://docs.wickra.org}
|
||||
\item \url{https://wickra-lib.r-universe.dev}
|
||||
\item Report bugs at \url{https://github.com/wickra-lib/wickra/issues}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,15 @@ default = []
|
||||
# want. `live-binance` covers both the live WebSocket feed and the historical
|
||||
# REST kline fetcher.
|
||||
live-binance = ["dep:tokio", "dep:tokio-tungstenite", "dep:futures-util", "dep:url", "dep:ureq", "dep:native-tls"]
|
||||
# `live-binance` with a statically built OpenSSL instead of the system one. The
|
||||
# native-tls stack (tokio-tungstenite + ureq, unified on the same `native-tls`
|
||||
# crate) links `openssl-sys`, which needs OpenSSL at build time. The manylinux
|
||||
# and musllinux wheel containers do not provide it — manylinux lacks the headers
|
||||
# and the musllinux build cross-compiles against a musl sysroot that has no
|
||||
# OpenSSL at all — so the Linux wheels are built with this feature, which
|
||||
# compiles OpenSSL from source and links it statically. No-op on macOS/Windows,
|
||||
# where native-tls uses Security.framework / SChannel and never pulls openssl-sys.
|
||||
vendored-tls = ["live-binance", "native-tls/vendored"]
|
||||
|
||||
[dev-dependencies]
|
||||
approx = { workspace = true }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.wickra.examples</groupId>
|
||||
<artifactId>wickra-examples</artifactId>
|
||||
<version>0.9.3</version>
|
||||
<version>0.9.6</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Wickra Java examples</name>
|
||||
@@ -21,7 +21,7 @@
|
||||
<dependency>
|
||||
<groupId>org.wickra</groupId>
|
||||
<artifactId>wickra</artifactId>
|
||||
<version>0.9.3</version>
|
||||
<version>0.9.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
Generated
+7
-7
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"../../bindings/node": {
|
||||
"name": "wickra",
|
||||
"version": "0.9.3",
|
||||
"version": "0.9.6",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.18.0"
|
||||
@@ -23,12 +23,12 @@
|
||||
"node": ">= 20"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"wickra-darwin-arm64": "0.9.3",
|
||||
"wickra-darwin-x64": "0.9.3",
|
||||
"wickra-linux-arm64-gnu": "0.9.3",
|
||||
"wickra-linux-x64-gnu": "0.9.3",
|
||||
"wickra-win32-arm64-msvc": "0.9.3",
|
||||
"wickra-win32-x64-msvc": "0.9.3"
|
||||
"wickra-darwin-arm64": "0.9.6",
|
||||
"wickra-darwin-x64": "0.9.6",
|
||||
"wickra-linux-arm64-gnu": "0.9.6",
|
||||
"wickra-linux-x64-gnu": "0.9.6",
|
||||
"wickra-win32-arm64-msvc": "0.9.6",
|
||||
"wickra-win32-x64-msvc": "0.9.6"
|
||||
}
|
||||
},
|
||||
"node_modules/wickra": {
|
||||
|
||||
Reference in New Issue
Block a user