Compare commits

..
8 Commits
Author SHA1 Message Date
kingchencandGitHub 87bb008aa1 release: bump 0.7.9 -> 0.8.0 + Go module mirror (#237)
Bumps the workspace from 0.7.9 to 0.8.0 and adds the release-time mirror of the Go module to a standalone `wickra-go` repository.

## release.yml: `go-mirror` job
Adds a `go-mirror` job (independent of `github-release`, `needs: c-abi-build`) that on every `v*` tag:
- assembles the standalone Go module from `bindings/go` (single-package source + the vendored `include/wickra.h`),
- stages the six prebuilt C ABI libraries from the `c-abi-build` artifacts under `lib/<goos>_<goarch>/` (committed in the mirror, unlike the in-repo `lib/.gitignore`),
- rewrites `go.mod` to `module github.com/wickra-lib/wickra-go`,
- commits and tags the result in `wickra-lib/wickra-go` using the `WICKRA_GO_MIRROR_TOKEN` fine-grained PAT.

This makes `go get github.com/wickra-lib/wickra-go` build with no extra steps, closing the gap where the in-repo `bindings/go` module only built inside a full repository checkout. The mirror is a derived artifact, so its bot commit is intentionally unsigned.

## Version bump 0.7.9 -> 0.8.0
Patch never reaches double digits (`0.7.9` -> `0.8.0`). Touchpoints: `Cargo.toml` (+ `Cargo.lock` via build), `bindings/python/pyproject.toml`, `bindings/node/package.json` + 6 platform `npm/*/package.json` + both `package-lock.json` files, `bindings/java/pom.xml` + `examples/java/pom.xml` + Maven/Gradle snippets in `bindings/java/README.md`, and `CHANGELOG.md`. The C# `Wickra.csproj` (version set per tag) and `bindings/c` (inherits the workspace version) are intentionally untouched.

Tagging `v0.8.0` (which triggers the publish + the new mirror) stays gated on explicit confirmation.
2026-06-09 23:50:48 +02:00
kingchencandGitHub b06ce2678a Restructure the Go binding for self-contained distribution (#236)
## Problem
Plain `go get` + `go build` of the Go binding never worked **as a dependency**:
- cgo `CFLAGS` pointed at `${SRCDIR}/../c/include` — the parent dir is **outside** the Go module, so a proxy-fetched module has no header.
- the library under `./lib` was git-ignored and never shipped; the README told users to `cargo build` it from the workspace, which only works inside a clone, not from the read-only module cache.

cgo has no build hook and Go has no registry, so the only way a consumer's `go get`+build can find the lib is for it to be committed **inside the module the consumer pulls**. Per the design decision, that module is a separate **`wickra-go`** repo (keeps this repo free of committed binaries), populated by the release pipeline — this PR is the in-repo restructure that makes that possible.

## Changes
- **Vendor the header** at `bindings/go/include/wickra.h` (committed copy of `bindings/c/include/wickra.h`); `CFLAGS` → `-I${SRCDIR}/include`. A **CI drift check** fails if the copy goes stale.
- **Per-platform libraries**: cgo `LDFLAGS` become per `GOOS`/`GOARCH`, linking `${SRCDIR}/lib/<goos>_<goarch>/`.
- **CI** stages the host library into `lib/<goos>_<goarch>/` (`RUNNER_OS`/`RUNNER_ARCH` — note `macos-latest` is arm64) and exports `WICKRA_GO_LIBDIR` for the Windows PATH; libraries stay git-ignored here.
- **README**: install via the `wickra-go` module + a contributor build section.

## Validation
- Local **windows/amd64**: `gofmt` clean, `go vet`, `go build`, `go test` all green against the staged library + vendored header.
- Linux/macOS arches → the 3-OS `Go on …` CI job.

Follow-up (Stage 2, separate): create `wickra-lib/wickra-go` + a `release.yml` mirror job (source + 6 platform libs → `lib/<goos>_<goarch>/`, commit + tag), and point the docs at the new import path. Part of the self-contained gap (`todo-11`).
2026-06-09 23:06:16 +02:00
kingchencandGitHub 5b7523265c Make the R binding self-contained (fetch the C ABI at install time) (#235)
## Problem
The R package built **only** inside the dev/CI workspace. `src/Makevars` and `configure.win` hard-required `WICKRA_INCLUDE_DIR` / `WICKRA_LIB_DIR` pointing at a pre-built `libwickra` (`configure.win` literally `: "${WICKRA_LIB_DIR:?...}"`), and there was no Unix `configure`. So **r-universe** and any plain `install.packages` / `install_github` failed — R had no working end-user install path.

## Fix
Fetch the prebuilt `wickra-c-<triple>.tar.gz` release asset matching the package version at install time and bundle the library into the package (same outcome as the C# / Java bindings, which bundle per-platform native libs):

- **New POSIX `configure`** (the Unix hook R lacked): detect OS/arch → triple, download + `untar` via **base R** (no curl/wget system dep), stage `wickra.h` + `libwickra.{so,dylib}` into `src/`, generate `src/Makevars` from `Makevars.in` with an rpath (`$ORIGIN` Linux, `@loader_path` + `install_name_tool` macOS) so the bundled lib resolves post-install.
- **`configure.win`**: drop the hard `WICKRA_LIB_DIR` requirement; download the Windows triple when unset, then keep the existing `wickra_abi.dll` rename + `objdump`/`dlltool` import-lib dance (sourcing the dll/header from the asset).
- **`install.libs.R`** also bundles `libwickra.dylib` (macOS); the `*.so`/`*.dll` globs already covered Linux/Windows.
- `WICKRA_INCLUDE_DIR`/`WICKRA_LIB_DIR` stay as an optional **dev override**.
- **CI (3 OS)** keeps building against the locally built C ABI (version-independent — avoids the chicken-egg of downloading the in-flight version) but **no longer exports `LD_LIBRARY_PATH`/`DYLD_LIBRARY_PATH`**, so it now verifies the bundled rpath — the real self-contained path users and r-universe get.

`Makevars` is now generated from `Makevars.in`; `SystemRequirements` + ignore/attributes files updated.

## Validation
- The Windows `objdump`/`dlltool` import-lib dance was smoke-tested locally against the real v0.7.9 asset (2412 `wickra_` exports → import lib built).
- Linux/macOS rpath bundling can't be tested on this Windows host → **the 3-OS `r` CI job is the gate** (now without the loader-path mask).
- Follow-up (separate, after release): set up `wickra-lib/wickra-lib.r-universe.dev` (`packages.json` → `bindings/r`).

Closes the R half of the self-contained-distribution gap (`todo-10`).
2026-06-09 22:11:50 +02:00
kingchencandGitHub d188959aab release: bump 0.7.8 -> 0.7.9 (#234)
Version bump 0.7.8 -> 0.7.9 for the Java binding release.
2026-06-09 20:33:17 +02:00
kingchencandGitHub 167f7b3ffe Add the Java binding over the C ABI hub (Panama/FFM) (#233)
Adds a Java binding (`bindings/java`) over the C ABI hub — the fourth language stecker after C#, Go and R, reaching the hub through the Java Foreign Function & Memory API (Panama, `java.lang.foreign`, final in Java 22) rather than JNI or jextract.

## What's here
- **`bindings/java`** — a Maven module (`org.wickra:wickra`) exposing all 514 indicators as idiomatic `AutoCloseable` classes. The downcall handles (`internal/NativeMethods.java`), the per-indicator wrappers and the output records are generated from `bindings/c/include/wickra.h` (same eight-archetype taxonomy as the C#/Go/R generators: scalar/batch, multi-output, bars, profile, values-profile, array-input). The opaque handle is a `MemorySegment` freed by a registered `java.lang.ref.Cleaner` action; multi-output returns a `record` (`null` at warmup), bars a `record[]`, profiles a record with a trailing `double[]`. The hand-written `WickraNative` resolves the native library (a bundled per-platform copy, or a `target/release` fallback for local development) and validates it against a sentinel symbol. repr(C) struct offsets are computed in the generator so the FFM reads land on the exact bytes.
- **`examples/java`** — the full example suite mirroring C/C#/Go/R: streaming, backtest, multi_timeframe, parallel_assets (parallel streams), three strategies, and `FetchBtcusdt`/`LiveBinance`.
- **CI** — a `java` job builds the C ABI library, sets up JDK 22 (Temurin, with a CDN-flake retry), runs the archetype test suite and the seven offline examples on Linux, macOS and Windows.
- **Release** — a gated `java-publish` job (skipped until the `JAVA_PUBLISH_ENABLED` repository variable is set) stages the native libraries from the `wickra-c-<triple>.tar.gz` assets into the binding's resources and deploys to Maven Central with GPG signing. Independent of the GitHub-release job, like the NuGet job.
- **Docs** — Java added to the README languages table, project layout, building/testing and comparison table, CONTRIBUTING, ARCHITECTURE, the examples index, the issue/PR templates, the About-description template, and the other binding READMEs.

## Requirements
Java 22+ (the FFM API is final since Java 22). The binding requires `--enable-native-access=ALL-UNNAMED` at runtime; the test and example runners pass it automatically.

No Rust crate or `Cargo.toml` change — the Java binding is standalone and additive. The generated `*.java` are committed (like the node `index.js`/`index.d.ts`); the generator stays private.
2026-06-09 20:30:29 +02:00
kingchencandGitHub 8659b42bef release: bump 0.7.7 -> 0.7.8 (#232)
Version bump 0.7.7 -> 0.7.8 for the R binding release.
2026-06-09 19:22:11 +02:00
kingchencandGitHub b7ef63400d Add the R binding over the C ABI hub (#230)
Adds an R binding (`bindings/r`) over the C ABI hub — the third language stecker after C# and Go, reaching the hub through R's native `.Call` interface (not extendr).

## What's here
- **`bindings/r`** — an R package exposing all 514 indicators as constructors that return a `wickra_indicator` object with generic `update`/`batch`/`reset` methods. The C glue (`src/wickra.c`) and R wrappers (`R/indicators.R`) are generated from `bindings/c/include/wickra.h` (same archetype taxonomy as the C#/Go generators: scalar/batch, multi-output, bars, profile, profile-values, array-input). The opaque handle is an R external pointer freed by a registered finalizer; multi-output returns a named vector (`NA` at warmup), bars a matrix, profiles a list.
- **`examples/r`** — the full example suite mirroring C/C#/Go: streaming, backtest, multi_timeframe, parallel_assets (`mclapply`), three strategies, and `fetch_btcusdt`/`live_binance`.
- **CI** — an `r` job builds the C ABI library, installs the package, runs the `testthat` suite and the offline examples on Linux, macOS and Windows (`R CMD check` is clean: 0 warnings, 0 notes).
- **Docs** — R added to the README languages table, project layout, building/testing, CONTRIBUTING binding table + regenerate note, ARCHITECTURE, examples index, issue/PR templates, the About-description template, and the other binding READMEs.

## Linking / distribution
The package compiles a thin `.Call` glue layer against the prebuilt C ABI library (header via `WICKRA_INCLUDE_DIR`, library via `WICKRA_LIB_DIR`). On Windows the package's own `wickra.dll` would collide with the C ABI's `wickra.dll`, so `configure.win` stages a renamed copy (`wickra_abi.dll`) and builds an import library referencing it; `install.libs.R` bundles the DLL and `.onLoad` puts it on the load path. On Linux/macOS the rpath locates the shared library. No `release.yml` change — R is distributed via r-universe / source install (gated).

No Rust crate or `Cargo.toml` change — the R package is standalone and additive.
2026-06-09 19:18:40 +02:00
kingchencandGitHub 8225e1ab91 Check out the PR head by SHA in the count-sync workflow (#231)
## Problem
The **Sync indicator count** check has failed on every release-bump PR since 0.7.5 (`release/0.7.6`, `release/0.7.7`, …). It is a race, not a counter mismatch.

The checkout step used the PR head **branch name**:
\`\`\`yaml
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }}
\`\`\`
Release PRs are merged with \`gh pr merge --squash --delete-branch\`, which deletes the head branch the instant the PR merges — usually before this queued read-only check reaches its checkout. Fetching the now-gone \`refs/heads/release/X.Y.Z\` then fails with exit 1 (3 retries, then error). Push-to-main, tag and slower feature PRs stayed green because their head branch still existed when the check ran.

## Fix
Check out \`github.event.pull_request.head.sha\` instead. The head SHA stays reachable via \`refs/pull/N/head\` after the branch is deleted, so an instant merge no longer red-Xes the run. It is still the author's head commit (not the merge ref), so the counter validates exactly what will land — the existing design intent is preserved.

Because \`pull_request\` runs the workflow definition from the merge commit, the fix already applies to this PR itself.
2026-06-09 18:59:09 +02:00
1225 changed files with 86031 additions and 109 deletions
+17 -1
View File
@@ -11,8 +11,24 @@ bindings/c/include/wickra.h text eol=lf
*.cs text eol=lf *.cs text eol=lf
# Go sources (including the generated binding) are pinned to LF so gofmt's CI # Go sources (including the generated binding) are pinned to LF so gofmt's CI
# check never trips on a CRLF checkout on Windows. # check never trips on a CRLF checkout on Windows. The vendored C ABI header is
# a committed copy of bindings/c/include/wickra.h (the parent dir is outside the
# Go module), pinned to LF so the drift check never trips on CRLF.
*.go text eol=lf *.go text eol=lf
go.mod text eol=lf go.mod text eol=lf
go.sum text eol=lf go.sum text eol=lf
bindings/go/include/wickra.h text eol=lf
# Java sources (including the generated binding) are pinned to LF so the
# committed files stay stable regardless of the committer's autocrlf setting.
*.java text eol=lf
# R binding: `R CMD check` requires LF in sources, Makevars and shell scripts.
*.R text eol=lf
*.Rd text eol=lf
bindings/r/configure text eol=lf
bindings/r/configure.win text eol=lf
bindings/r/src/Makevars.in text eol=lf
bindings/r/src/Makevars.win text eol=lf
bindings/r/src/wickra.c text eol=lf
+1 -1
View File
@@ -30,7 +30,7 @@ assignees: ""
## Environment ## Environment
- Wickra version: - Wickra version:
- Language / binding: <!-- Rust crate / Python / Node / WASM / C ABI / C# (.NET) / Go --> - Language / binding: <!-- Rust crate / Python / Node / WASM / C ABI / C# (.NET) / Go / Java / R -->
- OS and architecture: - OS and architecture:
- Rust / Python / Node / .NET version (If relevant): - Rust / Python / Node / .NET version (If relevant):
@@ -16,6 +16,11 @@ assignees: []
- [ ] Python (`pip install wickra`) - [ ] Python (`pip install wickra`)
- [ ] Node.js (`npm install wickra`) - [ ] Node.js (`npm install wickra`)
- [ ] WebAssembly - [ ] WebAssembly
- [ ] C ABI (`bindings/c`)
- [ ] C# / .NET (`Wickra` on NuGet)
- [ ] Go (`bindings/go`)
- [ ] Java (`org.wickra:wickra` on Maven Central)
- [ ] R (`bindings/r`)
- [ ] Docs / examples only - [ ] Docs / examples only
## Environment ## Environment
@@ -28,6 +28,8 @@ assignees: ""
- [ ] Should be exposed in the C ABI - [ ] Should be exposed in the C ABI
- [ ] Should be exposed in the C# / .NET binding - [ ] Should be exposed in the C# / .NET binding
- [ ] Should be exposed in the Go binding - [ ] Should be exposed in the Go binding
- [ ] Should be exposed in the Java binding
- [ ] Should be exposed in the R binding
## Additional context ## Additional context
@@ -13,7 +13,7 @@ assignees: []
## Affected code path ## Affected code path
- Indicator / API: `e.g. EMA.update` - Indicator / API: `e.g. EMA.update`
- Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go` - Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go / Java / R`
- Hot loop or one-shot call? - Hot loop or one-shot call?
## Versions compared ## Versions compared
+1 -1
View File
@@ -33,4 +33,4 @@ import wickra as ta
## Environment (Only if relevant) ## Environment (Only if relevant)
- Wickra version: `e.g. 0.4.2` - Wickra version: `e.g. 0.4.2`
- Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go` - Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go / Java / R`
+1 -1
View File
@@ -22,7 +22,7 @@
- [ ] `cargo clippy --workspace --all-targets -- -D warnings` is clean. - [ ] `cargo clippy --workspace --all-targets -- -D warnings` is clean.
- [ ] `cargo test --workspace` passes. - [ ] `cargo test --workspace` passes.
- [ ] New behaviour has tests; bug fixes have a regression test. - [ ] New behaviour has tests; bug fixes have a regression test.
- [ ] Public API changes are mirrored in the Python / Node / WASM bindings, and the C ABI + C# + Go bindings are regenerated - [ ] Public API changes are mirrored in the Python / Node / WASM bindings, and the C ABI + C# + Go + Java + R bindings are regenerated
and their type stubs (If applicable). and their type stubs (If applicable).
- [ ] The relevant page on the [documentation site](https://docs.wickra.org) - [ ] The relevant page on the [documentation site](https://docs.wickra.org)
and the `README.md` are updated (If applicable). Docs edits go to a and the `README.md` are updated (If applicable). Docs edits go to a
@@ -26,6 +26,8 @@ Please fill in the sections below. Delete any that don't apply.
- [ ] C ABI (`bindings/c`) - [ ] C ABI (`bindings/c`)
- [ ] C# / .NET binding (`bindings/csharp`) - [ ] C# / .NET binding (`bindings/csharp`)
- [ ] Go binding (`bindings/go`) - [ ] Go binding (`bindings/go`)
- [ ] Java binding (`bindings/java`)
- [ ] R binding (`bindings/r`)
- [ ] Examples / docs - [ ] Examples / docs
## Linked issues ## Linked issues
+174 -9
View File
@@ -778,15 +778,36 @@ jobs:
- name: Build the C ABI library - name: Build the C ABI library
run: cargo build -p wickra-c --release run: cargo build -p wickra-c --release
- name: Vendored header in sync with the C ABI
shell: bash
# bindings/go/include/wickra.h is a committed copy of the cbindgen header
# (the parent ../c/include is outside the Go module, so it must be
# vendored). Fail if it drifts from the source of truth.
run: |
if ! diff -u bindings/c/include/wickra.h bindings/go/include/wickra.h; then
echo "::error::bindings/go/include/wickra.h is stale — copy bindings/c/include/wickra.h over it"
exit 1
fi
- name: Stage the native library - name: Stage the native library
shell: bash shell: bash
# Stage into lib/<goos>_<goarch>/ to match the per-platform cgo LDFLAGS.
# CI builds the host target, so RUNNER_OS/ARCH give the right directory
# (note macos-latest is arm64).
run: | run: |
mkdir -p bindings/go/lib case "$RUNNER_ARCH" in
case "$RUNNER_OS" in X64) arch=amd64 ;;
Linux) cp target/release/libwickra.so bindings/go/lib/ ;; ARM64) arch=arm64 ;;
macOS) cp target/release/libwickra.dylib bindings/go/lib/ ;; *) echo "::error::unsupported RUNNER_ARCH '$RUNNER_ARCH'"; exit 1 ;;
Windows) cp target/release/wickra.dll bindings/go/lib/ ;;
esac esac
case "$RUNNER_OS" in
Linux) dir="linux_$arch"; lib=target/release/libwickra.so ;;
macOS) dir="darwin_$arch"; lib=target/release/libwickra.dylib ;;
Windows) dir="windows_$arch"; lib=target/release/wickra.dll ;;
esac
mkdir -p "bindings/go/lib/$dir"
cp "$lib" "bindings/go/lib/$dir/"
echo "WICKRA_GO_LIBDIR=$PWD/bindings/go/lib/$dir" >> "$GITHUB_ENV"
- name: Go info - name: Go info
run: go version run: go version
@@ -801,9 +822,11 @@ jobs:
- name: Vet and test the Go binding - name: Vet and test the Go binding
shell: bash shell: bash
# On Windows there is no rpath; the loader resolves wickra.dll via PATH. # On Windows there is no rpath; the loader resolves wickra.dll via PATH
# (WICKRA_GO_LIBDIR is the per-platform staged lib dir). Linux/macOS use
# the rpath baked by the per-platform cgo LDFLAGS.
run: | run: |
export PATH="$PWD/bindings/go/lib:$PATH" export PATH="$WICKRA_GO_LIBDIR:$PATH"
cd bindings/go cd bindings/go
go vet ./... go vet ./...
go test ./... go test ./...
@@ -811,7 +834,7 @@ jobs:
- name: Build the Go examples - name: Build the Go examples
shell: bash shell: bash
run: | run: |
export PATH="$PWD/bindings/go/lib:$PATH" export PATH="$WICKRA_GO_LIBDIR:$PATH"
cd examples/go cd examples/go
go build ./... go build ./...
@@ -819,13 +842,155 @@ jobs:
- name: Run the offline Go examples - name: Run the offline Go examples
shell: bash shell: bash
run: | run: |
export PATH="$PWD/bindings/go/lib:$PATH" export PATH="$WICKRA_GO_LIBDIR:$PATH"
cd examples/go cd examples/go
for d in streaming backtest multi_timeframe parallel_assets \ for d in streaming backtest multi_timeframe parallel_assets \
strategy_rsi_mean_reversion strategy_macd_adx strategy_bollinger_squeeze; do strategy_rsi_mean_reversion strategy_macd_adx strategy_bollinger_squeeze; do
go run "./$d" go run "./$d"
done done
r:
name: R on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
env:
WICKRA_INCLUDE_DIR: ${{ github.workspace }}/bindings/c/include
WICKRA_LIB_DIR: ${{ github.workspace }}/target/release
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27
- name: Cache cargo
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
continue-on-error: true
timeout-minutes: 6
# The binding compiles a thin .Call glue layer against the C ABI hub; build
# the library first. On Windows configure.win bundles a renamed copy
# (wickra_abi.dll) so the package's own wickra.dll does not collide with it.
- name: Build the C ABI library
run: cargo build -p wickra-c --release
- name: Set up R
uses: r-lib/actions/setup-r@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2
with:
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")'
- name: Install and test the R binding
shell: bash
# github.workspace is a backslash path on Windows; configure(.win) (sh) and
# mingw need forward slashes. WICKRA_*_DIR makes configure use the locally
# built C ABI (dev override) instead of downloading the release asset, so
# CI is version-independent. Deliberately do NOT set LD_LIBRARY_PATH /
# DYLD_LIBRARY_PATH: the lib is bundled into the package and must resolve
# via the rpath ($ORIGIN / @loader_path) baked by configure — that is the
# self-contained install path real users (and r-universe) get.
run: |
export WICKRA_INCLUDE_DIR="${WICKRA_INCLUDE_DIR//\\//}"
export WICKRA_LIB_DIR="${WICKRA_LIB_DIR//\\//}"
R CMD INSTALL bindings/r
Rscript -e 'library(testthat); library(wickra); test_dir("bindings/r/tests/testthat", stop_on_failure = TRUE)'
- name: Run the offline R examples
shell: bash
# No loader-path exports: the installed package is self-contained (bundled
# lib + rpath), so the examples exercise exactly what end users run.
run: |
cd examples/r
for f in streaming backtest multi_timeframe parallel_assets \
strategy_rsi_mean_reversion strategy_macd_adx strategy_bollinger_squeeze; do
Rscript "$f.R"
done
# fetch_btcusdt / live_binance need the network (and jsonlite / websocket);
# build-check that they parse without running them.
- name: Parse the network R examples
run: Rscript -e 'invisible(lapply(c("examples/r/fetch_btcusdt.R", "examples/r/live_binance.R"), parse)); cat("network R examples parse OK\n")'
java:
name: Java on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27
- name: Cache cargo
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
timeout-minutes: 6
# The binding links the C ABI hub at runtime through the Java FFM API; build
# it first so WickraNative's development fallback finds
# target/release/wickra.{so,dylib,dll}. JDK 22+ is required for the final FFM
# API, so it is installed explicitly (runners ship 17/21).
- name: Build the C ABI library
run: cargo build -p wickra-c --release
- name: Set up JDK 22
id: setup-java
continue-on-error: true
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
distribution: temurin
java-version: "22"
cache: maven
- name: Retry JDK setup (CDN flake)
if: steps.setup-java.outcome == 'failure'
shell: bash
run: |
echo "::warning::setup-java failed (likely CDN flake), waiting 30s before retry..."
sleep 30
- name: Set up JDK 22 (retry)
if: steps.setup-java.outcome == 'failure'
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
distribution: temurin
java-version: "22"
cache: maven
- name: Java info
run: java -version
# `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.
- name: Test and install the Java binding
run: mvn -B -f bindings/java install
- name: Build the Java examples
run: mvn -B -f examples/java compile
# Run only the offline examples (fetch_btcusdt / live_binance need network).
- name: Run the offline Java examples
shell: bash
run: |
for cls in Streaming Backtest MultiTimeframe ParallelAssets \
StrategyRsiMeanReversion StrategyMacdAdx StrategyBollingerSqueeze; do
mvn -B -q -f examples/java exec:exec -Dexec.mainClass="org.wickra.examples.$cls"
done
# The cross-library benchmark has moved to a dedicated scheduled workflow # The cross-library benchmark has moved to a dedicated scheduled workflow
# (.github/workflows/bench.yml) — see audit finding R10. It runs nightly # (.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 # at 03:00 UTC and on-demand via `workflow_dispatch`, and is no longer on
+158
View File
@@ -706,6 +706,164 @@ jobs:
path: nupkg/*.nupkg path: nupkg/*.nupkg
if-no-files-found: error if-no-files-found: error
# Publish the Java binding to Maven Central. Independent of the GitHub-release
# job so a Java hiccup never blocks the C/C++ asset release. The Maven Central
# namespace (org.wickra) is verified; authentication uses the Sonatype Central
# Portal token (CENTRAL_USERNAME / CENTRAL_PASSWORD) and artifacts are signed
# with the GPG key (GPG_PRIVATE_KEY / GPG_PASSPHRASE). The pom version must
# match the release tag (kept in sync by the version-bump checklist).
java-publish:
name: Publish to Maven Central
needs: c-abi-build
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Download the C ABI native libraries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: c-abi-*
path: c-abi-artifacts
- name: Stage native libraries into resources/native/<os>-<arch>
shell: bash
run: |
set -e
declare -A PLAT=(
[x86_64-unknown-linux-gnu]=linux-x64
[aarch64-unknown-linux-gnu]=linux-arm64
[x86_64-apple-darwin]=osx-x64
[aarch64-apple-darwin]=osx-arm64
[x86_64-pc-windows-msvc]=win-x64
[aarch64-pc-windows-msvc]=win-arm64
)
base=bindings/java/src/main/resources/native
for target in "${!PLAT[@]}"; do
archive=$(find c-abi-artifacts -name "wickra-c-$target.tar.gz" | head -1)
if [ -z "$archive" ]; then
echo "::error::missing native artifact for $target"; exit 1
fi
tmp=$(mktemp -d); tar -xzf "$archive" -C "$tmp"
dest="$base/${PLAT[$target]}"; mkdir -p "$dest"
for f in libwickra.so libwickra.dylib wickra.dll; do
src=$(find "$tmp" -name "$f" | head -1)
[ -n "$src" ] && cp "$src" "$dest/"
done
echo "staged ${PLAT[$target]}:"; ls -l "$dest"
done
# setup-java writes a settings.xml with the 'central' server credentials
# (mapped from the env vars below) and imports the GPG signing key.
- name: Set up JDK 22 + Maven Central credentials + GPG
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
distribution: temurin
java-version: "22"
server-id: central
server-username: CENTRAL_USERNAME
server-password: CENTRAL_PASSWORD
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg-passphrase: GPG_PASSPHRASE
- name: Deploy to Maven Central
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: mvn -B -f bindings/java -Prelease deploy -DskipTests
# Mirror the in-repo Go module (bindings/go) to the standalone wickra-go
# repository so `go get github.com/wickra-lib/wickra-go` builds with no extra
# steps. The in-repo module keeps the prebuilt libraries git-ignored; the
# mirror commits them per platform under lib/<goos>_<goarch>/ alongside the
# vendored header. Independent of the GitHub-release job so a Go hiccup never
# blocks the C/C++ asset release. The push uses a fine-grained PAT
# (WICKRA_GO_MIRROR_TOKEN, contents:write on wickra-go); the mirror is a
# derived artifact, so its bot commit is intentionally unsigned.
go-mirror:
name: Mirror the Go module to wickra-go
needs: c-abi-build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Download the C ABI native libraries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: c-abi-*
path: c-abi-artifacts
- name: Assemble the wickra-go module tree
shell: bash
run: |
set -e
out=wickra-go-module
mkdir -p "$out/include" "$out/lib"
# Single-package Go source + vendored C ABI header.
cp bindings/go/*.go "$out/"
cp bindings/go/include/wickra.h "$out/include/"
cp bindings/go/README.md "$out/"
# Standalone module path (the in-repo go.mod points at the subdir).
printf 'module github.com/wickra-lib/wickra-go\n\ngo 1.23\n' > "$out/go.mod"
# Point install instructions at the standalone module path.
sed -i 's#github.com/wickra-lib/wickra/bindings/go#github.com/wickra-lib/wickra-go#g' \
"$out/README.md" "$out"/*.go
# Stage each prebuilt library under lib/<goos>_<goarch>/ (committed in
# the mirror, unlike the in-repo lib/.gitignore). "<dir> <libfile>".
declare -A GO=(
[x86_64-unknown-linux-gnu]="linux_amd64 libwickra.so"
[aarch64-unknown-linux-gnu]="linux_arm64 libwickra.so"
[x86_64-apple-darwin]="darwin_amd64 libwickra.dylib"
[aarch64-apple-darwin]="darwin_arm64 libwickra.dylib"
[x86_64-pc-windows-msvc]="windows_amd64 wickra.dll"
[aarch64-pc-windows-msvc]="windows_arm64 wickra.dll"
)
for target in "${!GO[@]}"; do
read -r dir libfile <<< "${GO[$target]}"
archive=$(find c-abi-artifacts -name "wickra-c-$target.tar.gz" | head -1)
if [ -z "$archive" ]; then
echo "::error::missing native artifact for $target"; exit 1
fi
tmp=$(mktemp -d); tar -xzf "$archive" -C "$tmp"
src=$(find "$tmp" -name "$libfile" | head -1)
if [ -z "$src" ]; then
echo "::error::missing $libfile for $target"; exit 1
fi
mkdir -p "$out/lib/$dir"; cp "$src" "$out/lib/$dir/"
done
echo "assembled module:"; find "$out" -type f | sort
- name: Push to wickra-go and tag the release
shell: bash
env:
MIRROR_TOKEN: ${{ secrets.WICKRA_GO_MIRROR_TOKEN }}
run: |
set -e
version="${GITHUB_REF_NAME#v}"
remote="https://x-access-token:${MIRROR_TOKEN}@github.com/wickra-lib/wickra-go.git"
git clone -q "$remote" mirror-repo
cd mirror-repo
git config user.name "wickra-bot"
git config user.email "support@wickra.org"
git symbolic-ref HEAD refs/heads/main
# Replace all tracked content with the freshly assembled tree.
find . -mindepth 1 -maxdepth 1 -not -name .git -exec rm -rf {} +
cp -r ../wickra-go-module/. .
git add -A
if git diff --cached --quiet; then
echo "wickra-go already up to date; tagging only"
else
git -c commit.gpgsign=false commit -q -m "Release v$version"
fi
git push origin HEAD:refs/heads/main
git tag "v$version"
git push origin "v$version"
github-release: github-release:
name: Attach assets to the draft GitHub Release name: Attach assets to the draft GitHub Release
needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build] needs: [cargo-publish, python-publish, node-publish, wasm-publish, c-abi-build]
+9 -2
View File
@@ -86,10 +86,17 @@ jobs:
# merge ref) so the counter check validates exactly what will land. On # merge ref) so the counter check validates exactly what will land. On
# push events we check out the default ref. No push is made, so a shallow # push events we check out the default ref. No push is made, so a shallow
# checkout is enough. # checkout is enough.
#
# Check out by head SHA, not head ref (branch name): a fast `gh pr merge
# --squash --delete-branch` deletes the head branch the moment the PR
# merges, often before this queued read-only check reaches its checkout.
# Fetching the now-gone `refs/heads/<branch>` then fails the run (exit 1).
# The head SHA stays reachable via `refs/pull/N/head` after the branch is
# gone, so the checkout — and the run — survives an instant merge.
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: with:
fetch-depth: 1 fetch-depth: 1
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }} ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
repository: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} repository: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }}
- name: Count indicators - name: Count indicators
@@ -149,7 +156,7 @@ jobs:
# actually live (Cloudflare Pages, P8.1); merging this PR is therefore # actually live (Cloudflare Pages, P8.1); merging this PR is therefore
# gated on the domain resolving, otherwise the About link would 404. # gated on the domain resolving, otherwise the About link would 404.
homepage="https://docs.wickra.org" homepage="https://docs.wickra.org"
desc="Streaming-first technical indicators with a Rust core and Python, Node.js, WebAssembly, C ABI, .NET, and Go bindings. ${n} indicators, O(1) per-tick updates, no system dependencies. Drop-in TA-Lib replacement." desc="Streaming-first technical indicators with a Rust core and Python, Node.js, WebAssembly, C ABI, .NET, Go, Java, and R bindings. ${n} indicators, O(1) per-tick updates, no system dependencies. Drop-in TA-Lib replacement."
# Enforce the homepage unconditionally — it is a constant, so this both # Enforce the homepage unconditionally — it is a constant, so this both
# corrects the stale kingchenc URL and self-heals any future drift. # corrects the stale kingchenc URL and self-heals any future drift.
# Same Administration-write permission as --description (no extra scope). # Same Administration-write permission as --description (no extra scope).
+3 -2
View File
@@ -46,8 +46,9 @@ wasm-bindgen). The C ABI is the *hub* every other C-capable language links
against: it builds to a `cdylib`/`staticlib` plus a generated `wickra.h`, and against: it builds to a `cdylib`/`staticlib` plus a generated `wickra.h`, and
downstream languages link that one artifact rather than each re-wrapping the downstream languages link that one artifact rather than each re-wrapping the
core. C and C++ link it directly; the **C# / .NET** binding (`bindings/csharp`, core. C and C++ link it directly; the **C# / .NET** binding (`bindings/csharp`,
on NuGet) and the **Go** binding (`bindings/go`, cgo) are generated from on NuGet), the **Go** binding (`bindings/go`, cgo), the **R** binding
`wickra.h`, with Java / R planned the same way. (`bindings/r`, `.Call`) and the **Java** binding (`bindings/java`, the Java FFM
API / Panama, on Maven Central) are all generated from `wickra.h`.
| Crate | Path | What it owns | Public deps | | Crate | Path | What it owns | Public deps |
|---|---|---|---| |---|---|---|---|
+40 -2
View File
@@ -5,7 +5,42 @@ All notable changes to Wickra are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [0.8.0] - 2026-06-09
### Added
- **Standalone `wickra-go` module** — the Go binding is now mirrored to a
dedicated `github.com/wickra-lib/wickra-go` repository on every release, with
the prebuilt C ABI libraries committed per platform under
`lib/<goos>_<goarch>/` and the C ABI header vendored alongside the source, so
`go get github.com/wickra-lib/wickra-go` builds with no extra steps. The
in-repo `bindings/go` module is unchanged for repo-clone workflows.
### Changed
- **Go binding (`bindings/go`) is self-contained** — the C ABI header is now
vendored inside the module (`bindings/go/include/wickra.h`) instead of being
referenced from the parent `bindings/c` directory, and the cgo link flags
resolve the prebuilt library per `GOOS`/`GOARCH` under `lib/<goos>_<goarch>/`.
This removes the dependency on a full repository checkout for building the
module.
## [0.7.9] - 2026-06-09
### Added
- **Java binding (`bindings/java`)** — a Java binding reaching the C ABI hub
through the Java Foreign Function & Memory API (Panama, `java.lang.foreign`,
final in Java 22) rather than JNI or jextract, exposing all 514 indicators as
idiomatic `AutoCloseable` classes. The downcall handles, per-indicator
wrappers and output records are generated from `wickra.h`; the opaque handle is
a `MemorySegment` freed by a `java.lang.ref.Cleaner` action. Ships a full
example suite mirroring the C, C#, Go and R examples; published to Maven
Central as `org.wickra:wickra`.
## [0.7.8] - 2026-06-09
### Added
- **R binding (`bindings/r`)** — an R package reaching the C ABI hub through R's
native `.Call` interface, exposing all 514 indicators as constructors that
return a `wickra_indicator` object with `update`/`batch`/`reset` methods. The
C glue and R wrappers are generated from `wickra.h`; the native handle is freed
by a registered finalizer. Ships a full example suite mirroring the C, C# and
Go examples; distributed for r-universe / source install.
## [0.7.7] - 2026-06-09 ## [0.7.7] - 2026-06-09
### Added ### Added
@@ -1443,7 +1478,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
optional Binance live feed. optional Binance live feed.
- Bindings for Python, Node.js, and WebAssembly. - Bindings for Python, Node.js, and WebAssembly.
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.7.7...HEAD [Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.8.0...HEAD
[0.8.0]: https://github.com/wickra-lib/wickra/compare/v0.7.9...v0.8.0
[0.7.9]: https://github.com/wickra-lib/wickra/compare/v0.7.8...v0.7.9
[0.7.8]: https://github.com/wickra-lib/wickra/compare/v0.7.7...v0.7.8
[0.7.7]: https://github.com/wickra-lib/wickra/compare/v0.7.6...v0.7.7 [0.7.7]: https://github.com/wickra-lib/wickra/compare/v0.7.6...v0.7.7
[0.7.6]: https://github.com/wickra-lib/wickra/compare/v0.7.5...v0.7.6 [0.7.6]: https://github.com/wickra-lib/wickra/compare/v0.7.5...v0.7.6
[0.7.5]: https://github.com/wickra-lib/wickra/compare/v0.7.4...v0.7.5 [0.7.5]: https://github.com/wickra-lib/wickra/compare/v0.7.4...v0.7.5
+7 -1
View File
@@ -24,6 +24,8 @@ licensed as above, without any additional terms or conditions.
| `bindings/c` | C ABI — `cdylib` + `staticlib` + generated `include/wickra.h`. The hub for C / C++ and any C-capable language. | | `bindings/c` | C ABI — `cdylib` + `staticlib` + generated `include/wickra.h`. The hub for C / C++ and any C-capable language. |
| `bindings/csharp` | .NET binding over the C ABI (`Wickra` on NuGet) — `[LibraryImport]` P/Invoke generated from `wickra.h`. | | `bindings/csharp` | .NET binding over the C ABI (`Wickra` on NuGet) — `[LibraryImport]` P/Invoke generated from `wickra.h`. |
| `bindings/go` | Go binding over the C ABI via cgo (module tag `bindings/go/vX.Y.Z`) — wrappers generated from `wickra.h`. | | `bindings/go` | Go binding over the C ABI via cgo (module tag `bindings/go/vX.Y.Z`) — wrappers generated from `wickra.h`. |
| `bindings/r` | R binding over the C ABI via `.Call` (R package) — C glue + R wrappers generated from `wickra.h`. |
| `bindings/java` | Java binding over the C ABI via the FFM API (Panama, Maven Central) — wrappers generated from `wickra.h`. |
| `examples/` | Runnable examples. | | `examples/` | Runnable examples. |
| `docs/` | Pointer to the documentation site (docs.wickra.org); the docs live in the `wickra-lib/wickra-docs` repo. | | `docs/` | Pointer to the documentation site (docs.wickra.org); the docs live in the `wickra-lib/wickra-docs` repo. |
@@ -110,7 +112,11 @@ installed. Dependabot also keeps the `.github/requirements` pins current.
commit `src/lib.rs` + `include/wickra.h`. The C# binding (`bindings/csharp`) is commit `src/lib.rs` + `include/wickra.h`. The C# binding (`bindings/csharp`) is
generated from `wickra.h`, so regenerate and commit its `Generated/*.g.cs` too. generated from `wickra.h`, so regenerate and commit its `Generated/*.g.cs` too.
The Go binding (`bindings/go`) is likewise generated from `wickra.h`, so The Go binding (`bindings/go`) is likewise generated from `wickra.h`, so
regenerate and commit `indicators_gen.go` (`gofmt`-clean). regenerate and commit `indicators_gen.go` (`gofmt`-clean). The R binding
(`bindings/r`) is generated from `wickra.h` too, so regenerate and commit
`src/wickra.c` + `R/indicators.R`. The Java binding (`bindings/java`) is
generated from `wickra.h` as well, so regenerate and commit its
`src/main/java/org/wickra/*.java`.
- **Docs.** Update the relevant page on the - **Docs.** Update the relevant page on the
[documentation site](https://docs.wickra.org) and the [documentation site](https://docs.wickra.org) and the
`README.md` when behaviour or the public API changes. The docs live in `README.md` when behaviour or the public API changes. The docs live in
Generated
+9 -9
View File
@@ -1944,7 +1944,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra" name = "wickra"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"approx", "approx",
"criterion", "criterion",
@@ -1955,7 +1955,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-bench" name = "wickra-bench"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"criterion", "criterion",
"kand", "kand",
@@ -1967,14 +1967,14 @@ dependencies = [
[[package]] [[package]]
name = "wickra-c" name = "wickra-c"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"wickra-core", "wickra-core",
] ]
[[package]] [[package]]
name = "wickra-core" name = "wickra-core"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"approx", "approx",
"proptest", "proptest",
@@ -1984,7 +1984,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-data" name = "wickra-data"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"approx", "approx",
"csv", "csv",
@@ -2001,7 +2001,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-examples" name = "wickra-examples"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"serde_json", "serde_json",
"tokio", "tokio",
@@ -2011,7 +2011,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-node" name = "wickra-node"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"napi", "napi",
"napi-build", "napi-build",
@@ -2021,7 +2021,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-python" name = "wickra-python"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"numpy", "numpy",
"pyo3", "pyo3",
@@ -2030,7 +2030,7 @@ dependencies = [
[[package]] [[package]]
name = "wickra-wasm" name = "wickra-wasm"
version = "0.7.7" version = "0.8.0"
dependencies = [ dependencies = [
"console_error_panic_hook", "console_error_panic_hook",
"js-sys", "js-sys",
+2 -2
View File
@@ -14,7 +14,7 @@ members = [
exclude = ["fuzz"] exclude = ["fuzz"]
[workspace.package] [workspace.package]
version = "0.7.7" version = "0.8.0"
authors = ["kingchenc <support@wickra.org>"] authors = ["kingchenc <support@wickra.org>"]
edition = "2021" edition = "2021"
rust-version = "1.86" rust-version = "1.86"
@@ -26,7 +26,7 @@ keywords = ["finance", "trading", "indicators", "technical-analysis", "ta"]
categories = ["finance", "mathematics", "science"] categories = ["finance", "mathematics", "science"]
[workspace.dependencies] [workspace.dependencies]
wickra-core = { path = "crates/wickra-core", version = "0.7.7" } wickra-core = { path = "crates/wickra-core", version = "0.8.0" }
thiserror = "2" thiserror = "2"
rayon = "1.10" rayon = "1.10"
+25 -7
View File
@@ -20,7 +20,7 @@
Wickra is a multi-language technical-analysis library with a Rust core and Wickra is a multi-language technical-analysis library with a Rust core and
native bindings for Python, Node.js and WebAssembly, plus a C ABI that C, C++, native bindings for Python, Node.js and WebAssembly, plus a C ABI that C, C++,
C# / .NET, Go and any other C-capable language links against. Every indicator is a C# / .NET, Go, Java, R and any other C-capable language links against. Every indicator is a
state machine that updates in O(1) per new data point, so live trading bots and state machine that updates in O(1) per new data point, so live trading bots and
historical backtests share the exact same implementation. historical backtests share the exact same implementation.
@@ -51,7 +51,8 @@ Full documentation lives at **[docs.wickra.org](https://docs.wickra.org)**:
[WASM](https://docs.wickra.org/Quickstart-WASM), [WASM](https://docs.wickra.org/Quickstart-WASM),
[C](https://docs.wickra.org/Quickstart-C), [C](https://docs.wickra.org/Quickstart-C),
[C#](https://docs.wickra.org/Quickstart-CSharp), [C#](https://docs.wickra.org/Quickstart-CSharp),
[Go](https://docs.wickra.org/Quickstart-Go). [Go](https://docs.wickra.org/Quickstart-Go),
[R](https://docs.wickra.org/Quickstart-R).
- **Indicators** — a per-indicator deep dive (formula, parameters, warmup) for - **Indicators** — a per-indicator deep dive (formula, parameters, warmup) for
every one of the 514 indicators; start at the every one of the 514 indicators; start at the
[indicators overview](https://docs.wickra.org/Indicators-Overview). [indicators overview](https://docs.wickra.org/Indicators-Overview).
@@ -77,7 +78,7 @@ times to get there.
metrics — every single one updating in **O(1) per tick**. TA-Lib ships ~150 and metrics — every single one updating in **O(1) per tick**. TA-Lib ships ~150 and
none of them stream. none of them stream.
- **One Rust core, five first-class targets.** Native **Python · Node.js · - **One Rust core, five first-class targets.** Native **Python · Node.js ·
WebAssembly · Rust** plus a **C ABI** for C / C++, C# / .NET, Go and any other C-capable language — WebAssembly · Rust** plus a **C ABI** for C / C++, C# / .NET, Go, Java, R and any other C-capable language —
identical math, identical results, zero per-language reimplementation and zero identical math, identical results, zero per-language reimplementation and zero
GIL bottleneck. GIL bottleneck.
- **Correct by construction, not by hope.** Every `update` validates its input, - **Correct by construction, not by hope.** Every `update` validates its input,
@@ -102,7 +103,7 @@ Every other library forces one of those compromises. Wickra doesn't:
| Library | Install | Streaming | Languages | Indicators | Active | | Library | Install | Streaming | Languages | Indicators | Active |
|------------------|-------------|-------------|-----------------------------|-----------:|--------| |------------------|-------------|-------------|-----------------------------|-----------:|--------|
| **★&nbsp;Wickra**| **clean** | **yes, O(1)** | **Rust · Python · Node · WASM** | **514** | **yes** | | **★&nbsp;Wickra**| **clean** | **yes, O(1)** | **Rust · Python · Node · WASM** | **514** | **yes** |
| | | | **C · C# · Go** | | | | | | | **C · C# · Go · Java · R** | | |
| kand | clean | yes | Python · WASM · Rust | ~60 | yes | | kand | clean | yes | Python · WASM · Rust | ~60 | yes |
| ta-rs | clean | yes | Rust only | ~30 | stale | | ta-rs | clean | yes | Rust only | ~30 | stale |
| yata | clean | partial | Rust only | ~35 | yes | | yata | clean | partial | Rust only | ~35 | yes |
@@ -174,7 +175,7 @@ construct it in signed mode (`Doji::new().signed()`, `Doji(signed=True)`,
`new Doji(true)`) for a dragonfly / gravestone `±1` reading. `new Doji(true)`) for a dragonfly / gravestone `±1` reading.
Adding a new indicator means implementing one trait in Rust; every binding Adding a new indicator means implementing one trait in Rust; every binding
inherits it automatically (the C ABI — and the C# and Go bindings generated from inherits it automatically (the C ABI — and the C#, Go, Java and R bindings generated from
it — regenerate from the core). it — regenerate from the core).
## Languages ## Languages
@@ -188,6 +189,8 @@ it — regenerate from the core).
| C / C++ (C ABI) | header + library, see [`bindings/c`](bindings/c) | `examples/c/streaming.c` | | C / C++ (C ABI) | header + library, see [`bindings/c`](bindings/c) | `examples/c/streaming.c` |
| C# / .NET (C ABI) | `dotnet add package Wickra`, see [`bindings/csharp`](bindings/csharp) | `examples/csharp/streaming` | | C# / .NET (C ABI) | `dotnet add package Wickra`, see [`bindings/csharp`](bindings/csharp) | `examples/csharp/streaming` |
| Go (cgo, C ABI) | `go get github.com/wickra-lib/wickra/bindings/go`, see [`bindings/go`](bindings/go) | `examples/go/streaming` | | Go (cgo, C ABI) | `go get github.com/wickra-lib/wickra/bindings/go`, see [`bindings/go`](bindings/go) | `examples/go/streaming` |
| Java (FFM, C ABI) | Maven Central `org.wickra:wickra`, see [`bindings/java`](bindings/java) | `examples/java` (`Streaming`) |
| R (`.Call`, C ABI) | `R CMD INSTALL bindings/r`, see [`bindings/r`](bindings/r) | `examples/r/streaming.R` |
Each binding ships several runnable examples (streaming, backtest, live feed); Each binding ships several runnable examples (streaming, backtest, live feed);
[`examples/README.md`](examples/README.md) is the full cross-language index. [`examples/README.md`](examples/README.md) is the full cross-language index.
@@ -259,7 +262,9 @@ wickra/
│ ├── wasm/ wasm-bindgen (browsers, bundlers, Node) │ ├── wasm/ wasm-bindgen (browsers, bundlers, Node)
│ ├── c/ C ABI (cdylib + staticlib) + generated include/wickra.h │ ├── c/ C ABI (cdylib + staticlib) + generated include/wickra.h
│ ├── csharp/ .NET binding over the C ABI (publishes on NuGet) │ ├── csharp/ .NET binding over the C ABI (publishes on NuGet)
── go/ Go binding over the C ABI via cgo (module tag) ── go/ Go binding over the C ABI via cgo (module tag)
│ ├── r/ R binding over the C ABI via .Call (R package)
│ └── java/ Java binding over the C ABI via the FFM API (Maven Central)
├── examples/ examples/README.md indexes every language ├── examples/ examples/README.md indexes every language
│ ├── data/ real BTCUSDT OHLCV datasets, one per timeframe │ ├── data/ real BTCUSDT OHLCV datasets, one per timeframe
│ ├── rust/ Rust workspace member (`wickra-examples`) │ ├── rust/ Rust workspace member (`wickra-examples`)
@@ -268,7 +273,9 @@ wickra/
│ ├── wasm/ browser demo for `wickra-wasm` │ ├── wasm/ browser demo for `wickra-wasm`
│ ├── c/ C smoke + streaming, C++ RAII wrapper │ ├── c/ C smoke + streaming, C++ RAII wrapper
│ ├── csharp/ streaming, backtest, strategies (load `Wickra`) │ ├── csharp/ streaming, backtest, strategies (load `Wickra`)
── go/ streaming, backtest, strategies (cgo binding) ── go/ streaming, backtest, strategies (cgo binding)
│ ├── r/ streaming, backtest, strategies (.Call binding)
│ └── java/ streaming, backtest, strategies (FFM binding)
└── .github/workflows/ CI and release pipelines └── .github/workflows/ CI and release pipelines
``` ```
@@ -308,6 +315,13 @@ dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj
# Go binding (requires a C compiler for cgo; links the C ABI above) # Go binding (requires a C compiler for cgo; links the C ABI above)
cp target/release/libwickra.so bindings/go/lib/ # .dylib on macOS, wickra.dll on Windows cp target/release/libwickra.so bindings/go/lib/ # .dylib on macOS, wickra.dll on Windows
cd bindings/go && go test ./... cd bindings/go && go test ./...
# R binding (requires a C toolchain / Rtools; links the C ABI above)
WICKRA_INCLUDE_DIR="$PWD/bindings/c/include" WICKRA_LIB_DIR="$PWD/target/release" \
R CMD INSTALL bindings/r
# Java binding (requires JDK 22+ and Maven; links the C ABI above)
mvn -f bindings/java test
``` ```
## Testing ## Testing
@@ -329,6 +343,10 @@ Every layer is covered; run the suites with the commands in
and reference values. and reference values.
- `bindings/go`: `go test` cases covering one indicator per FFI archetype - `bindings/go`: `go test` cases covering one indicator per FFI archetype
(scalar/batch, multi-output, bars, profile, array input), reset, and lifecycle. (scalar/batch, multi-output, bars, profile, array input), reset, and lifecycle.
- `bindings/r`: `testthat` cases covering one indicator per FFI archetype
(scalar/batch, multi-output, bars, profile, array input), reset, and validation.
- `bindings/java`: JUnit cases covering one indicator per FFI archetype
(scalar/batch, multi-output, bars, profile, array input) plus batch equivalence.
## Contributing ## Contributing
+1 -1
View File
@@ -22,7 +22,7 @@ minor releases; breaking changes are called out in the changelog.
- **Performance.** Keep per-tick updates O(1) and maintain the benchmark suite; - **Performance.** Keep per-tick updates O(1) and maintain the benchmark suite;
investigate further allocation and cache improvements. investigate further allocation and cache improvements.
- **Bindings parity.** Keep the Python, Node.js and WebAssembly bindings — plus - **Bindings parity.** Keep the Python, Node.js and WebAssembly bindings — plus
the C ABI and the C# / .NET and Go bindings generated from it — in lockstep with the the C ABI and the C# / .NET, Go, Java and R bindings generated from it — in lockstep with the
Rust core, including type stubs and platform coverage. Rust core, including type stubs and platform coverage.
- **Documentation.** Maintain a deep-dive page per indicator on - **Documentation.** Maintain a deep-dive page per indicator on
<https://docs.wickra.org>, plus quickstarts and cookbook material. <https://docs.wickra.org>, plus quickstarts and cookbook material.
+1 -1
View File
@@ -7,7 +7,7 @@ Thanks for using Wickra! Here is where to get help, depending on what you need.
Most questions are answered in the documentation: Most questions are answered in the documentation:
- **Docs site:** <https://docs.wickra.org> — quickstarts for Rust, Python, - **Docs site:** <https://docs.wickra.org> — quickstarts for Rust, Python,
Node.js, WebAssembly, C, C# and Go, a per-indicator reference, warmup periods, the Node.js, WebAssembly, C, C#, Go, Java and R, a per-indicator reference, warmup periods, the
data layer, and an FAQ. data layer, and an FAQ.
- **README:** <https://github.com/wickra-lib/wickra#readme> — installation and a - **README:** <https://github.com/wickra-lib/wickra#readme> — installation and a
quick overview. quick overview.
+1 -1
View File
@@ -4,7 +4,7 @@ This document describes Wickra's attack surface and the threats considered,
together with their mitigations. It complements the security assurance case in together with their mitigations. It complements the security assurance case in
[`SECURITY.md`](SECURITY.md). Wickra is a computational technical-analysis [`SECURITY.md`](SECURITY.md). Wickra is a computational technical-analysis
library (a Rust core with Python, Node.js and WebAssembly bindings plus a C ABI library (a Rust core with Python, Node.js and WebAssembly bindings plus a C ABI
and the .NET and Go bindings built on it), and the .NET, Go, Java and R bindings built on it),
not a network service or trading system; the attack surface is correspondingly not a network service or trading system; the attack surface is correspondingly
small. small.
+1 -1
View File
@@ -9,7 +9,7 @@
library plus a generated `wickra.h` — no system dependencies.** library plus a generated `wickra.h` — no system dependencies.**
Wickra is a multi-language technical-analysis library with a Rust core and Wickra is a multi-language technical-analysis library with a Rust core and
bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go and any bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go, Java, R and any
other C-capable language. Every indicator is an O(1) other C-capable language. Every indicator is an O(1)
streaming state machine, so live trading bots and historical backtests share streaming state machine, so live trading bots and historical backtests share
the exact same implementation. This package is the **C ABI hub**: it compiles the the exact same implementation. This package is the **C ABI hub**: it compiles the
+1 -1
View File
@@ -9,7 +9,7 @@
prebuilt native library, no system dependencies.** prebuilt native library, no system dependencies.**
Wickra is a multi-language technical-analysis library with a Rust core and Wickra is a multi-language technical-analysis library with a Rust core and
bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go and any bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go, Java, R and any
other C-capable language. Every indicator is an O(1) other C-capable language. Every indicator is an O(1)
streaming state machine, so live trading bots and historical backtests share streaming state machine, so live trading bots and historical backtests share
the exact same implementation. This package is the .NET binding; it consumes the the exact same implementation. This package is the .NET binding; it consumes the
+1 -1
View File
@@ -11,7 +11,7 @@
<!-- NuGet package metadata --> <!-- NuGet package metadata -->
<PackageId>Wickra</PackageId> <PackageId>Wickra</PackageId>
<Version>0.7.7</Version> <Version>0.7.9</Version>
<Authors>kingchenc</Authors> <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> <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> <PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression>
+25 -11
View File
@@ -8,7 +8,7 @@
**Streaming-first technical indicators for Go, over the Wickra C ABI hub via cgo.** **Streaming-first technical indicators for Go, over the Wickra C ABI hub via cgo.**
Wickra is a multi-language technical-analysis library with a Rust core and Wickra is a multi-language technical-analysis library with a Rust core and
bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go and bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go, Java, R and
any other C-capable language. Every indicator is an O(1) streaming state machine, any other C-capable language. Every indicator is an O(1) streaming state machine,
so live trading bots and historical backtests share the exact same so live trading bots and historical backtests share the exact same
implementation. This package is the Go binding; it consumes the C ABI hub through implementation. This package is the Go binding; it consumes the C ABI hub through
@@ -16,24 +16,38 @@ cgo and exposes all 514 streaming-first indicators as idiomatic types.
## Install ## Install
Use the published **`wickra-go`** module, which bundles the prebuilt C ABI
library for every platform, so `go get` + `go build` works with no extra steps
(a C compiler is still required, as the binding uses cgo):
```bash ```bash
go get github.com/wickra-lib/wickra/bindings/go go get github.com/wickra-lib/wickra-go
``` ```
The binding uses cgo, so a C compiler is required, and it links against the ```go
prebuilt Wickra C ABI library. Build that library from the workspace and stage import wickra "github.com/wickra-lib/wickra-go"
it under this package's `lib/` directory: ```
`wickra-go` is generated from this directory by the release pipeline: it mirrors
the Go sources, the vendored C ABI header (`include/wickra.h`) and the prebuilt
libraries under `lib/<goos>_<goarch>/`. On Linux/macOS the library path is baked
in via rpath; on Windows the DLL must be discoverable at run time (next to the
executable or on `PATH`).
### Building from this repository (contributors)
This `bindings/go` directory is the development source. To build it directly,
compile the C ABI and stage the library into the per-platform directory cgo
links against:
```bash ```bash
cargo build -p wickra-c --release cargo build -p wickra-c --release
cp target/release/libwickra.so bindings/go/lib/ # Linux mkdir -p bindings/go/lib/linux_amd64 # match your GOOS_GOARCH
cp target/release/libwickra.dylib bindings/go/lib/ # macOS cp target/release/libwickra.so bindings/go/lib/linux_amd64/ # Linux
cp target/release/wickra.dll bindings/go/lib/ # Windows (also on PATH at run time) cp target/release/libwickra.dylib bindings/go/lib/darwin_arm64/ # macOS (arm64)
cp target/release/wickra.dll bindings/go/lib/windows_amd64/ # Windows
``` ```
On Linux and macOS the library path is baked in via rpath; on Windows the DLL
must be discoverable at run time (next to the executable or on `PATH`).
## Quick start ## Quick start
```go ```go
File diff suppressed because it is too large Load Diff
+12 -7
View File
@@ -4,16 +4,21 @@
// Each indicator is an opaque-handle type with a New<Indicator> constructor and // Each indicator is an opaque-handle type with a New<Indicator> constructor and
// Update/Batch/Reset/Close methods. Handles are freed by Close and, as a // Update/Batch/Reset/Close methods. Handles are freed by Close and, as a
// backstop, by a finalizer; call Close explicitly to release native memory // backstop, by a finalizer; call Close explicitly to release native memory
// promptly. The binding links against the prebuilt Wickra C ABI library // promptly. The binding links against the prebuilt Wickra C ABI library, staged
// (libwickra.so/.dylib or wickra.dll) staged under ./lib — see the package // per platform under ./lib/<goos>_<goarch>/, with the C ABI header vendored
// README for how to provision it. // under ./include. For distribution the libraries are committed alongside the
// source in the wickra-go module, so `go get` + `go build` works with no extra
// steps — see the package README.
package wickra package wickra
/* /*
#cgo CFLAGS: -I${SRCDIR}/../c/include #cgo CFLAGS: -I${SRCDIR}/include
#cgo linux LDFLAGS: -L${SRCDIR}/lib -lwickra -Wl,-rpath,${SRCDIR}/lib #cgo linux,amd64 LDFLAGS: -L${SRCDIR}/lib/linux_amd64 -lwickra -Wl,-rpath,${SRCDIR}/lib/linux_amd64
#cgo darwin LDFLAGS: -L${SRCDIR}/lib -lwickra -Wl,-rpath,${SRCDIR}/lib #cgo linux,arm64 LDFLAGS: -L${SRCDIR}/lib/linux_arm64 -lwickra -Wl,-rpath,${SRCDIR}/lib/linux_arm64
#cgo windows LDFLAGS: -L${SRCDIR}/lib -l:wickra.dll #cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/lib/darwin_amd64 -lwickra -Wl,-rpath,${SRCDIR}/lib/darwin_amd64
#cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/lib/darwin_arm64 -lwickra -Wl,-rpath,${SRCDIR}/lib/darwin_arm64
#cgo windows,amd64 LDFLAGS: -L${SRCDIR}/lib/windows_amd64 -l:wickra.dll
#cgo windows,arm64 LDFLAGS: -L${SRCDIR}/lib/windows_arm64 -l:wickra.dll
#include "wickra.h" #include "wickra.h"
*/ */
import "C" import "C"
+6
View File
@@ -0,0 +1,6 @@
# Maven build output
target/
# Native libraries staged for packaging (produced by the release pipeline from
# the wickra-c-<triple>.tar.gz assets; never committed to source).
src/main/resources/native/
+102
View File
@@ -0,0 +1,102 @@
# Wickra — Java
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![Maven Central](https://img.shields.io/maven-central/v/org.wickra/wickra.svg?logo=apache-maven&color=blue)](https://central.sonatype.com/artifact/org.wickra/wickra)
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](https://github.com/wickra-lib/wickra#license)
**Streaming-first technical indicators for the JVM, on the Java Foreign Function
& Memory API — prebuilt native library, no JNI, no system dependencies.**
Wickra is a multi-language technical-analysis library with a Rust core and
bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go, Java, R
and any other C-capable language. Every indicator is an O(1) streaming state
machine, so live trading bots and historical backtests share the exact same
implementation. This package is the Java binding; it consumes the C ABI hub
through the Panama FFM API (`java.lang.foreign`) and exposes all 514
streaming-first indicators as idiomatic `AutoCloseable` classes.
## Requirements
- **Java 22 or later** (the FFM API is final since Java 22; no preview flag).
- The FFM API is *restricted*: pass `--enable-native-access=ALL-UNNAMED` when you
run your application to silence the native-access warning.
## Install
Maven:
```xml
<dependency>
<groupId>org.wickra</groupId>
<artifactId>wickra</artifactId>
<version>0.8.0</version>
</dependency>
```
Gradle:
```kotlin
implementation("org.wickra:wickra:0.8.0")
```
The native library ships prebuilt per platform (Linux, macOS, Windows — x64 and
arm64) inside the jar and is extracted automatically on first use. There is
nothing to compile.
## Quick start
```java
import org.wickra.Ema;
import org.wickra.Rsi;
// Batch: run an indicator over a whole series (NaN at warmup positions).
double[] prices = new double[1000];
for (int i = 0; i < prices.length; i++) {
prices[i] = 100.0 + i * 0.1;
}
try (Ema ema = new Ema(20)) {
double[] values = ema.batch(prices);
}
// Streaming: the same indicator, fed tick by tick in O(1).
try (Rsi rsi = new Rsi(14)) {
for (double price : liveFeed) {
double value = rsi.update(price); // NaN during warmup, no recomputation
if (Double.isFinite(value) && value > 70) {
System.out.println("overbought");
}
}
}
```
`batch(prices)` and feeding the same prices through `update()` produce identical
values — the equivalence is enforced by the test suite. Multi-output indicators
(MACD, Bollinger, ADX, …) return a `record`, `null` while warming up. Each
indicator owns a native handle freed by a `Cleaner`; `close()` releases it
eagerly (use try-with-resources).
## Documentation
The full indicator catalogue, guides, quickstarts, and API reference live in
the main repository and documentation site:
- **Repository & full indicator list:** <https://github.com/wickra-lib/wickra>
- **Docs** (quickstarts, cookbook, TA-Lib migration): <https://docs.wickra.org>
- **Runnable examples:** [`examples/java/`](https://github.com/wickra-lib/wickra/tree/main/examples/java)
Wickra ships native bindings for Python, Node.js, WebAssembly and Rust, plus a
C ABI hub that any C-capable language (C, C++, Go, C#, Java, R) links against —
all exposing the same indicators from the shared, `unsafe`-forbidden Rust core.
## Disclaimer
Wickra is an indicator toolkit, not a trading system. The values it computes
are deterministic transforms of the input data — they are not financial advice
and do not predict the market. Any use in a live trading context is at your own
risk. The library is provided **as is**, without warranty of any kind.
## License
Licensed under either of [Apache-2.0](https://github.com/wickra-lib/wickra/blob/main/LICENSE-APACHE)
or [MIT](https://github.com/wickra-lib/wickra/blob/main/LICENSE-MIT) at your option.
+171
View File
@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.wickra</groupId>
<artifactId>wickra</artifactId>
<version>0.8.0</version>
<packaging>jar</packaging>
<name>Wickra</name>
<description>High-performance streaming technical-analysis indicators (514 indicators) for the
JVM, backed by the native Rust core through the Wickra C ABI via the Java FFM API (Panama).</description>
<url>https://github.com/wickra-lib/wickra</url>
<licenses>
<license>
<name>MIT</name>
<url>https://opensource.org/licenses/MIT</url>
<distribution>repo</distribution>
</license>
<license>
<name>Apache-2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>kingchenc</id>
<name>kingchenc</name>
<url>https://github.com/kingchenc</url>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/wickra-lib/wickra.git</connection>
<developerConnection>scm:git:https://github.com/wickra-lib/wickra.git</developerConnection>
<url>https://github.com/wickra-lib/wickra</url>
</scm>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>22</maven.compiler.release>
<junit.version>5.10.2</junit.version>
<!-- The FFM API is restricted; grant native access to the unnamed module so
tests and examples run without warnings. Consumers pass the same flag. -->
<native.access.arg>--enable-native-access=ALL-UNNAMED</native.access.arg>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<argLine>${native.access.arg}</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<archive>
<manifestEntries>
<!-- Grant native access when the jar is run directly. -->
<Enable-Native-Access>ALL-UNNAMED</Enable-Native-Access>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<!--
Release profile (CI only, gated): attaches source + javadoc jars, GPG-signs
every artifact, and publishes to Maven Central via the central-publishing
plugin. The native libraries are unpacked from the wickra-c-<triple>.tar.gz
release assets into src/main/resources/native/<os>-<arch>/ before `mvn deploy`,
so the published jar carries every platform's library.
-->
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals><goal>jar-no-fork</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<!-- Generated members are self-descriptive; do not fail on doclint. -->
<doclint>none</doclint>
<quiet>true</quiet>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals><goal>jar</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals><goal>sign</goal></goals>
<configuration>
<!-- Non-interactive signing on CI: modern GPG needs loopback
pinentry to take the passphrase from the env without a TTY. -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.5.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
<autoPublish>true</autoPublish>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AbandonedBaby indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AbandonedBaby implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AbandonedBaby() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ABANDONED_BABY_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AbandonedBaby parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ABANDONED_BABY_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ABANDONED_BABY_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ABANDONED_BABY_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ABANDONED_BABY_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Abcd indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Abcd implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Abcd() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ABCD_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Abcd parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ABCD_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ABCD_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ABCD_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ABCD_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AbsoluteBreadthIndex indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AbsoluteBreadthIndex implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AbsoluteBreadthIndex() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ABSOLUTE_BREADTH_INDEX_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AbsoluteBreadthIndex parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ABSOLUTE_BREADTH_INDEX_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double[] change, double[] volume, double[] newHigh, double[] newLow, double[] aboveMa, double[] onBuySignal, long timestamp) {
if (volume.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newHigh.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newLow.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (aboveMa.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (onBuySignal.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment changeSeg = a.allocateFrom(JAVA_DOUBLE, change);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment newHighSeg = a.allocateFrom(JAVA_DOUBLE, newHigh);
MemorySegment newLowSeg = a.allocateFrom(JAVA_DOUBLE, newLow);
MemorySegment aboveMaSeg = a.allocateFrom(JAVA_DOUBLE, aboveMa);
MemorySegment onBuySignalSeg = a.allocateFrom(JAVA_DOUBLE, onBuySignal);
return (double) NativeMethods.WICKRA_ABSOLUTE_BREADTH_INDEX_UPDATE.invokeExact(handle, changeSeg, volumeSeg, newHighSeg, newLowSeg, aboveMaSeg, onBuySignalSeg, (long) change.length, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ABSOLUTE_BREADTH_INDEX_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,62 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AccelerationBands indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AccelerationBands implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AccelerationBands(int period, double factor) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ACCELERATION_BANDS_NEW.invokeExact((long) period, factor);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AccelerationBands parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ACCELERATION_BANDS_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AccelerationBandsOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(24L);
byte ok = (byte) NativeMethods.WICKRA_ACCELERATION_BANDS_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AccelerationBandsOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ACCELERATION_BANDS_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AccelerationBandsOutput(double upper, double middle, double lower) {}
@@ -0,0 +1,95 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AcceleratorOscillator indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AcceleratorOscillator implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AcceleratorOscillator(int aoFast, int aoSlow, int signalPeriod) {
if (aoFast < 0) {
throw new IllegalArgumentException("aoFast must be non-negative");
}
if (aoSlow < 0) {
throw new IllegalArgumentException("aoSlow must be non-negative");
}
if (signalPeriod < 0) {
throw new IllegalArgumentException("signalPeriod must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ACCELERATOR_OSCILLATOR_NEW.invokeExact((long) aoFast, (long) aoSlow, (long) signalPeriod);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AcceleratorOscillator parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ACCELERATOR_OSCILLATOR_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ACCELERATOR_OSCILLATOR_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ACCELERATOR_OSCILLATOR_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ACCELERATOR_OSCILLATOR_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdOscillator indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdOscillator implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdOscillator() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AD_OSCILLATOR_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdOscillator parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AD_OSCILLATOR_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_AD_OSCILLATOR_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AD_OSCILLATOR_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AD_OSCILLATOR_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdVolumeLine indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdVolumeLine implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdVolumeLine() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AD_VOLUME_LINE_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdVolumeLine parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AD_VOLUME_LINE_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double[] change, double[] volume, double[] newHigh, double[] newLow, double[] aboveMa, double[] onBuySignal, long timestamp) {
if (volume.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newHigh.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newLow.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (aboveMa.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (onBuySignal.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment changeSeg = a.allocateFrom(JAVA_DOUBLE, change);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment newHighSeg = a.allocateFrom(JAVA_DOUBLE, newHigh);
MemorySegment newLowSeg = a.allocateFrom(JAVA_DOUBLE, newLow);
MemorySegment aboveMaSeg = a.allocateFrom(JAVA_DOUBLE, aboveMa);
MemorySegment onBuySignalSeg = a.allocateFrom(JAVA_DOUBLE, onBuySignal);
return (double) NativeMethods.WICKRA_AD_VOLUME_LINE_UPDATE.invokeExact(handle, changeSeg, volumeSeg, newHighSeg, newLowSeg, aboveMaSeg, onBuySignalSeg, (long) change.length, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AD_VOLUME_LINE_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,89 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdaptiveCci indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdaptiveCci implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdaptiveCci(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADAPTIVE_CCI_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdaptiveCci parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADAPTIVE_CCI_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ADAPTIVE_CCI_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ADAPTIVE_CCI_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADAPTIVE_CCI_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,66 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdaptiveCycle indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdaptiveCycle implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdaptiveCycle() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADAPTIVE_CYCLE_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdaptiveCycle parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADAPTIVE_CYCLE_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_ADAPTIVE_CYCLE_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ADAPTIVE_CYCLE_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADAPTIVE_CYCLE_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdaptiveLaguerreFilter indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdaptiveLaguerreFilter implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdaptiveLaguerreFilter(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADAPTIVE_LAGUERRE_FILTER_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdaptiveLaguerreFilter parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADAPTIVE_LAGUERRE_FILTER_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_ADAPTIVE_LAGUERRE_FILTER_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ADAPTIVE_LAGUERRE_FILTER_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADAPTIVE_LAGUERRE_FILTER_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdaptiveRsi indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdaptiveRsi implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdaptiveRsi(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADAPTIVE_RSI_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdaptiveRsi parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADAPTIVE_RSI_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_ADAPTIVE_RSI_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ADAPTIVE_RSI_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADAPTIVE_RSI_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Adl indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Adl implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Adl() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADL_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Adl parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADL_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ADL_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ADL_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADL_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdvanceBlock indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdvanceBlock implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdvanceBlock() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADVANCE_BLOCK_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdvanceBlock parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADVANCE_BLOCK_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ADVANCE_BLOCK_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ADVANCE_BLOCK_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADVANCE_BLOCK_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdvanceDecline indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdvanceDecline implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdvanceDecline() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADVANCE_DECLINE_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdvanceDecline parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADVANCE_DECLINE_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double[] change, double[] volume, double[] newHigh, double[] newLow, double[] aboveMa, double[] onBuySignal, long timestamp) {
if (volume.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newHigh.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newLow.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (aboveMa.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (onBuySignal.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment changeSeg = a.allocateFrom(JAVA_DOUBLE, change);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment newHighSeg = a.allocateFrom(JAVA_DOUBLE, newHigh);
MemorySegment newLowSeg = a.allocateFrom(JAVA_DOUBLE, newLow);
MemorySegment aboveMaSeg = a.allocateFrom(JAVA_DOUBLE, aboveMa);
MemorySegment onBuySignalSeg = a.allocateFrom(JAVA_DOUBLE, onBuySignal);
return (double) NativeMethods.WICKRA_ADVANCE_DECLINE_UPDATE.invokeExact(handle, changeSeg, volumeSeg, newHighSeg, newLowSeg, aboveMaSeg, onBuySignalSeg, (long) change.length, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADVANCE_DECLINE_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AdvanceDeclineRatio indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AdvanceDeclineRatio implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AdvanceDeclineRatio() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADVANCE_DECLINE_RATIO_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AdvanceDeclineRatio parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADVANCE_DECLINE_RATIO_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double[] change, double[] volume, double[] newHigh, double[] newLow, double[] aboveMa, double[] onBuySignal, long timestamp) {
if (volume.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newHigh.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newLow.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (aboveMa.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (onBuySignal.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment changeSeg = a.allocateFrom(JAVA_DOUBLE, change);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment newHighSeg = a.allocateFrom(JAVA_DOUBLE, newHigh);
MemorySegment newLowSeg = a.allocateFrom(JAVA_DOUBLE, newLow);
MemorySegment aboveMaSeg = a.allocateFrom(JAVA_DOUBLE, aboveMa);
MemorySegment onBuySignalSeg = a.allocateFrom(JAVA_DOUBLE, onBuySignal);
return (double) NativeMethods.WICKRA_ADVANCE_DECLINE_RATIO_UPDATE.invokeExact(handle, changeSeg, volumeSeg, newHighSeg, newLowSeg, aboveMaSeg, onBuySignalSeg, (long) change.length, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADVANCE_DECLINE_RATIO_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,62 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Adx indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Adx implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Adx(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADX_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Adx parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADX_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AdxOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(24L);
byte ok = (byte) NativeMethods.WICKRA_ADX_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AdxOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADX_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AdxOutput(double plusDi, double minusDi, double adx) {}
@@ -0,0 +1,89 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Adxr indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Adxr implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Adxr(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ADXR_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Adxr parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ADXR_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ADXR_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ADXR_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ADXR_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,68 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Alligator indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Alligator implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Alligator(int jawPeriod, int teethPeriod, int lipsPeriod) {
if (jawPeriod < 0) {
throw new IllegalArgumentException("jawPeriod must be non-negative");
}
if (teethPeriod < 0) {
throw new IllegalArgumentException("teethPeriod must be non-negative");
}
if (lipsPeriod < 0) {
throw new IllegalArgumentException("lipsPeriod must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ALLIGATOR_NEW.invokeExact((long) jawPeriod, (long) teethPeriod, (long) lipsPeriod);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Alligator parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ALLIGATOR_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AlligatorOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(24L);
byte ok = (byte) NativeMethods.WICKRA_ALLIGATOR_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AlligatorOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ALLIGATOR_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AlligatorOutput(double jaw, double teeth, double lips) {}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Alma indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Alma implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Alma(int period, double offset, double sigma) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ALMA_NEW.invokeExact((long) period, offset, sigma);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Alma parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ALMA_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_ALMA_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ALMA_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ALMA_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,73 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Alpha indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Alpha implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Alpha(int period, double riskFree) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ALPHA_NEW.invokeExact((long) period, riskFree);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Alpha parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ALPHA_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double x, double y) {
try {
return (double) NativeMethods.WICKRA_ALPHA_UPDATE.invokeExact(handle, x, y);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] x, double[] y) {
int n = x.length;
if (y.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment xSeg = a.allocateFrom(JAVA_DOUBLE, x);
MemorySegment ySeg = a.allocateFrom(JAVA_DOUBLE, y);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ALPHA_BATCH.invokeExact(handle, xSeg, ySeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ALPHA_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,54 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AmihudIlliquidity indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AmihudIlliquidity implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AmihudIlliquidity(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AMIHUD_ILLIQUIDITY_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AmihudIlliquidity parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AMIHUD_ILLIQUIDITY_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double price, double size, boolean isBuy, long timestamp) {
try {
return (double) NativeMethods.WICKRA_AMIHUD_ILLIQUIDITY_UPDATE.invokeExact(handle, price, size, (byte) (isBuy ? 1 : 0), timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AMIHUD_ILLIQUIDITY_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,66 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AnchoredRsi indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AnchoredRsi implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AnchoredRsi() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ANCHORED_RSI_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AnchoredRsi parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ANCHORED_RSI_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_ANCHORED_RSI_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ANCHORED_RSI_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ANCHORED_RSI_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AnchoredVwap indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AnchoredVwap implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AnchoredVwap() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ANCHORED_VWAP_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AnchoredVwap parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ANCHORED_VWAP_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ANCHORED_VWAP_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ANCHORED_VWAP_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ANCHORED_VWAP_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,62 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AndrewsPitchfork indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AndrewsPitchfork implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AndrewsPitchfork(int strength) {
if (strength < 0) {
throw new IllegalArgumentException("strength must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ANDREWS_PITCHFORK_NEW.invokeExact((long) strength);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AndrewsPitchfork parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ANDREWS_PITCHFORK_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AndrewsPitchforkOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(24L);
byte ok = (byte) NativeMethods.WICKRA_ANDREWS_PITCHFORK_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AndrewsPitchforkOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ANDREWS_PITCHFORK_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AndrewsPitchforkOutput(double median, double upper, double lower) {}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Apo indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Apo implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Apo(int fast, int slow) {
if (fast < 0) {
throw new IllegalArgumentException("fast must be non-negative");
}
if (slow < 0) {
throw new IllegalArgumentException("slow must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_APO_NEW.invokeExact((long) fast, (long) slow);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Apo parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_APO_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_APO_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_APO_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_APO_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,61 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Aroon indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Aroon implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Aroon(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AROON_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Aroon parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AROON_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AroonOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(16L);
byte ok = (byte) NativeMethods.WICKRA_AROON_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AroonOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AROON_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,89 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AroonOscillator indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AroonOscillator implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AroonOscillator(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AROON_OSCILLATOR_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AroonOscillator parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AROON_OSCILLATOR_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_AROON_OSCILLATOR_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AROON_OSCILLATOR_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AROON_OSCILLATOR_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AroonOutput(double up, double down) {}
@@ -0,0 +1,89 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Atr indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Atr implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Atr(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ATR_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Atr parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ATR_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ATR_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ATR_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ATR_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,62 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AtrBands indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AtrBands implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AtrBands(int period, double multiplier) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ATR_BANDS_NEW.invokeExact((long) period, multiplier);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AtrBands parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ATR_BANDS_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AtrBandsOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(24L);
byte ok = (byte) NativeMethods.WICKRA_ATR_BANDS_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AtrBandsOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ATR_BANDS_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AtrBandsOutput(double upper, double middle, double lower) {}
@@ -0,0 +1,61 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AtrRatchet indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AtrRatchet implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AtrRatchet(int atrPeriod, double startMult, double increment) {
if (atrPeriod < 0) {
throw new IllegalArgumentException("atrPeriod must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ATR_RATCHET_NEW.invokeExact((long) atrPeriod, startMult, increment);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AtrRatchet parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ATR_RATCHET_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AtrRatchetOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(16L);
byte ok = (byte) NativeMethods.WICKRA_ATR_RATCHET_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AtrRatchetOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ATR_RATCHET_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AtrRatchetOutput(double value, double direction) {}
@@ -0,0 +1,89 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AtrTrailingStop indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AtrTrailingStop implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AtrTrailingStop(int atrPeriod, double multiplier) {
if (atrPeriod < 0) {
throw new IllegalArgumentException("atrPeriod must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_ATR_TRAILING_STOP_NEW.invokeExact((long) atrPeriod, multiplier);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AtrTrailingStop parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_ATR_TRAILING_STOP_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_ATR_TRAILING_STOP_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_ATR_TRAILING_STOP_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_ATR_TRAILING_STOP_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,63 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AutoFib indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AutoFib implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AutoFib() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AUTO_FIB_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AutoFib parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AUTO_FIB_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public AutoFibOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(56L);
byte ok = (byte) NativeMethods.WICKRA_AUTO_FIB_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new AutoFibOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L),
out.get(JAVA_DOUBLE, 24L),
out.get(JAVA_DOUBLE, 32L),
out.get(JAVA_DOUBLE, 40L),
out.get(JAVA_DOUBLE, 48L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AUTO_FIB_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record AutoFibOutput(double level0, double level236, double level382, double level500, double level618, double level786, double level1000) {}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Autocorrelation indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Autocorrelation implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Autocorrelation(int period, int lag) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
if (lag < 0) {
throw new IllegalArgumentException("lag must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AUTOCORRELATION_NEW.invokeExact((long) period, (long) lag);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Autocorrelation parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AUTOCORRELATION_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_AUTOCORRELATION_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AUTOCORRELATION_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AUTOCORRELATION_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AutocorrelationPeriodogram indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AutocorrelationPeriodogram implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AutocorrelationPeriodogram(int minPeriod, int maxPeriod) {
if (minPeriod < 0) {
throw new IllegalArgumentException("minPeriod must be non-negative");
}
if (maxPeriod < 0) {
throw new IllegalArgumentException("maxPeriod must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AUTOCORRELATION_PERIODOGRAM_NEW.invokeExact((long) minPeriod, (long) maxPeriod);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AutocorrelationPeriodogram parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AUTOCORRELATION_PERIODOGRAM_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_AUTOCORRELATION_PERIODOGRAM_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AUTOCORRELATION_PERIODOGRAM_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AUTOCORRELATION_PERIODOGRAM_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,89 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AverageDailyRange indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AverageDailyRange implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AverageDailyRange(int period, int utcOffsetMinutes) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AVERAGE_DAILY_RANGE_NEW.invokeExact((long) period, utcOffsetMinutes);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AverageDailyRange parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AVERAGE_DAILY_RANGE_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_AVERAGE_DAILY_RANGE_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AVERAGE_DAILY_RANGE_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AVERAGE_DAILY_RANGE_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AverageDrawdown indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AverageDrawdown implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AverageDrawdown(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AVERAGE_DRAWDOWN_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AverageDrawdown parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AVERAGE_DRAWDOWN_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_AVERAGE_DRAWDOWN_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AVERAGE_DRAWDOWN_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AVERAGE_DRAWDOWN_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AvgPrice indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AvgPrice implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AvgPrice() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AVG_PRICE_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AvgPrice parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AVG_PRICE_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_AVG_PRICE_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AVG_PRICE_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AVG_PRICE_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,92 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AwesomeOscillator indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AwesomeOscillator implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AwesomeOscillator(int fast, int slow) {
if (fast < 0) {
throw new IllegalArgumentException("fast must be non-negative");
}
if (slow < 0) {
throw new IllegalArgumentException("slow must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AWESOME_OSCILLATOR_NEW.invokeExact((long) fast, (long) slow);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AwesomeOscillator parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AWESOME_OSCILLATOR_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_AWESOME_OSCILLATOR_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AWESOME_OSCILLATOR_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AWESOME_OSCILLATOR_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,95 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming AwesomeOscillatorHistogram indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class AwesomeOscillatorHistogram implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public AwesomeOscillatorHistogram(int fast, int slow, int smaPeriod) {
if (fast < 0) {
throw new IllegalArgumentException("fast must be non-negative");
}
if (slow < 0) {
throw new IllegalArgumentException("slow must be non-negative");
}
if (smaPeriod < 0) {
throw new IllegalArgumentException("smaPeriod must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_AWESOME_OSCILLATOR_HISTOGRAM_NEW.invokeExact((long) fast, (long) slow, (long) smaPeriod);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid AwesomeOscillatorHistogram parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_AWESOME_OSCILLATOR_HISTOGRAM_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_AWESOME_OSCILLATOR_HISTOGRAM_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_AWESOME_OSCILLATOR_HISTOGRAM_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_AWESOME_OSCILLATOR_HISTOGRAM_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BalanceOfPower indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BalanceOfPower implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BalanceOfPower() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BALANCE_OF_POWER_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BalanceOfPower parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BALANCE_OF_POWER_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_BALANCE_OF_POWER_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BALANCE_OF_POWER_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BALANCE_OF_POWER_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BandpassFilter indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BandpassFilter implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BandpassFilter(int period, double bandwidth) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BANDPASS_FILTER_NEW.invokeExact((long) period, bandwidth);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BandpassFilter parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BANDPASS_FILTER_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_BANDPASS_FILTER_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BANDPASS_FILTER_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BANDPASS_FILTER_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Bat indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Bat implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Bat() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BAT_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Bat parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BAT_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_BAT_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BAT_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BAT_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BeltHold indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BeltHold implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BeltHold() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BELT_HOLD_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BeltHold parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BELT_HOLD_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_BELT_HOLD_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BELT_HOLD_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BELT_HOLD_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,73 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Beta indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Beta implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Beta(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BETA_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Beta parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BETA_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double x, double y) {
try {
return (double) NativeMethods.WICKRA_BETA_UPDATE.invokeExact(handle, x, y);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] x, double[] y) {
int n = x.length;
if (y.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment xSeg = a.allocateFrom(JAVA_DOUBLE, x);
MemorySegment ySeg = a.allocateFrom(JAVA_DOUBLE, y);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BETA_BATCH.invokeExact(handle, xSeg, ySeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BETA_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,73 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BetaNeutralSpread indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BetaNeutralSpread implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BetaNeutralSpread(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BETA_NEUTRAL_SPREAD_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BetaNeutralSpread parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BETA_NEUTRAL_SPREAD_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double x, double y) {
try {
return (double) NativeMethods.WICKRA_BETA_NEUTRAL_SPREAD_UPDATE.invokeExact(handle, x, y);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] x, double[] y) {
int n = x.length;
if (y.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment xSeg = a.allocateFrom(JAVA_DOUBLE, x);
MemorySegment ySeg = a.allocateFrom(JAVA_DOUBLE, y);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BETA_NEUTRAL_SPREAD_BATCH.invokeExact(handle, xSeg, ySeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BETA_NEUTRAL_SPREAD_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,89 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BetterVolume indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BetterVolume implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BetterVolume(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BETTER_VOLUME_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BetterVolume parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BETTER_VOLUME_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_BETTER_VOLUME_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BETTER_VOLUME_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BETTER_VOLUME_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BipowerVariation indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BipowerVariation implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BipowerVariation(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BIPOWER_VARIATION_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BipowerVariation parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BIPOWER_VARIATION_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_BIPOWER_VARIATION_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BIPOWER_VARIATION_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BIPOWER_VARIATION_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BodySizePct indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BodySizePct implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BodySizePct() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BODY_SIZE_PCT_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BodySizePct parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BODY_SIZE_PCT_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_BODY_SIZE_PCT_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BODY_SIZE_PCT_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BODY_SIZE_PCT_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,63 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BollingerBands indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BollingerBands implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BollingerBands(int period, double multiplier) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BOLLINGER_BANDS_NEW.invokeExact((long) period, multiplier);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BollingerBands parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BOLLINGER_BANDS_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public BollingerOutput update(double value) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(32L);
byte ok = (byte) NativeMethods.WICKRA_BOLLINGER_BANDS_UPDATE.invokeExact(handle, value, out);
if (ok == 0) {
return null;
}
return new BollingerOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L),
out.get(JAVA_DOUBLE, 24L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BOLLINGER_BANDS_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BollingerBandwidth indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BollingerBandwidth implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BollingerBandwidth(int period, double multiplier) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BOLLINGER_BANDWIDTH_NEW.invokeExact((long) period, multiplier);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BollingerBandwidth parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BOLLINGER_BANDWIDTH_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_BOLLINGER_BANDWIDTH_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BOLLINGER_BANDWIDTH_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BOLLINGER_BANDWIDTH_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record BollingerOutput(double upper, double middle, double lower, double stddev) {}
@@ -0,0 +1,62 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BomarBands indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BomarBands implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BomarBands(int period, double coverage) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BOMAR_BANDS_NEW.invokeExact((long) period, coverage);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BomarBands parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BOMAR_BANDS_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public BomarBandsOutput update(double value) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(24L);
byte ok = (byte) NativeMethods.WICKRA_BOMAR_BANDS_UPDATE.invokeExact(handle, value, out);
if (ok == 0) {
return null;
}
return new BomarBandsOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BOMAR_BANDS_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record BomarBandsOutput(double upper, double middle, double lower) {}
@@ -0,0 +1,75 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BreadthThrust indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BreadthThrust implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BreadthThrust(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BREADTH_THRUST_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BreadthThrust parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BREADTH_THRUST_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double[] change, double[] volume, double[] newHigh, double[] newLow, double[] aboveMa, double[] onBuySignal, long timestamp) {
if (volume.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newHigh.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newLow.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (aboveMa.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (onBuySignal.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment changeSeg = a.allocateFrom(JAVA_DOUBLE, change);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment newHighSeg = a.allocateFrom(JAVA_DOUBLE, newHigh);
MemorySegment newLowSeg = a.allocateFrom(JAVA_DOUBLE, newLow);
MemorySegment aboveMaSeg = a.allocateFrom(JAVA_DOUBLE, aboveMa);
MemorySegment onBuySignalSeg = a.allocateFrom(JAVA_DOUBLE, onBuySignal);
return (double) NativeMethods.WICKRA_BREADTH_THRUST_UPDATE.invokeExact(handle, changeSeg, volumeSeg, newHighSeg, newLowSeg, aboveMaSeg, onBuySignalSeg, (long) change.length, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BREADTH_THRUST_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Breakaway indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Breakaway implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Breakaway() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BREAKAWAY_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Breakaway parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BREAKAWAY_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_BREAKAWAY_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BREAKAWAY_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BREAKAWAY_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,72 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BullishPercentIndex indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BullishPercentIndex implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BullishPercentIndex() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BULLISH_PERCENT_INDEX_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BullishPercentIndex parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BULLISH_PERCENT_INDEX_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double[] change, double[] volume, double[] newHigh, double[] newLow, double[] aboveMa, double[] onBuySignal, long timestamp) {
if (volume.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newHigh.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (newLow.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (aboveMa.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
if (onBuySignal.length != change.length) {
throw new IllegalArgumentException("input arrays in the same group must have equal length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment changeSeg = a.allocateFrom(JAVA_DOUBLE, change);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment newHighSeg = a.allocateFrom(JAVA_DOUBLE, newHigh);
MemorySegment newLowSeg = a.allocateFrom(JAVA_DOUBLE, newLow);
MemorySegment aboveMaSeg = a.allocateFrom(JAVA_DOUBLE, aboveMa);
MemorySegment onBuySignalSeg = a.allocateFrom(JAVA_DOUBLE, onBuySignal);
return (double) NativeMethods.WICKRA_BULLISH_PERCENT_INDEX_UPDATE.invokeExact(handle, changeSeg, volumeSeg, newHighSeg, newLowSeg, aboveMaSeg, onBuySignalSeg, (long) change.length, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BULLISH_PERCENT_INDEX_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming BurkeRatio indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class BurkeRatio implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public BurkeRatio(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BURKE_RATIO_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid BurkeRatio parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BURKE_RATIO_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_BURKE_RATIO_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BURKE_RATIO_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BURKE_RATIO_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,86 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Butterfly indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Butterfly implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Butterfly() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_BUTTERFLY_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Butterfly parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_BUTTERFLY_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double open, double high, double low, double close, double volume, long timestamp) {
try {
return (double) NativeMethods.WICKRA_BUTTERFLY_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] open, double[] high, double[] low, double[] close, double[] volume, double[] timestamp) {
int n = open.length;
if (high.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (low.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (close.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (volume.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
if (timestamp.length != n) {
throw new IllegalArgumentException("all input arrays must have the same length");
}
try (Arena a = Arena.ofConfined()) {
MemorySegment openSeg = a.allocateFrom(JAVA_DOUBLE, open);
MemorySegment highSeg = a.allocateFrom(JAVA_DOUBLE, high);
MemorySegment lowSeg = a.allocateFrom(JAVA_DOUBLE, low);
MemorySegment closeSeg = a.allocateFrom(JAVA_DOUBLE, close);
MemorySegment volumeSeg = a.allocateFrom(JAVA_DOUBLE, volume);
MemorySegment timestampSeg = a.allocateFrom(JAVA_DOUBLE, timestamp);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_BUTTERFLY_BATCH.invokeExact(handle, openSeg, highSeg, lowSeg, closeSeg, volumeSeg, timestampSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_BUTTERFLY_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,51 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming CalendarSpread indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class CalendarSpread implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public CalendarSpread() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_CALENDAR_SPREAD_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid CalendarSpread parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_CALENDAR_SPREAD_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) {
try {
return (double) NativeMethods.WICKRA_CALENDAR_SPREAD_UPDATE.invokeExact(handle, fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_CALENDAR_SPREAD_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,69 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming CalmarRatio indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class CalmarRatio implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public CalmarRatio(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_CALMAR_RATIO_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid CalmarRatio parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_CALMAR_RATIO_FREE);
}
/** Push one observation; returns the indicator value (NaN during warmup). */
public double update(double value) {
try {
return (double) NativeMethods.WICKRA_CALMAR_RATIO_UPDATE.invokeExact(handle, value);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Vectorized update over a whole series; NaN at warmup positions. */
public double[] batch(double[] input) {
int n = input.length;
try (Arena a = Arena.ofConfined()) {
MemorySegment inputSeg = a.allocateFrom(JAVA_DOUBLE, input);
MemorySegment outSeg = a.allocate(JAVA_DOUBLE.byteSize() * n);
NativeMethods.WICKRA_CALMAR_RATIO_BATCH.invokeExact(handle, inputSeg, outSeg, (long) n);
double[] out = new double[n];
MemorySegment.copy(outSeg, JAVA_DOUBLE, 0L, out, 0, n);
return out;
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_CALMAR_RATIO_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,65 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming Camarilla indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class Camarilla implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public Camarilla() {
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_CAMARILLA_NEW.invokeExact();
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid Camarilla parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_CAMARILLA_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public CamarillaPivotsOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(72L);
byte ok = (byte) NativeMethods.WICKRA_CAMARILLA_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new CamarillaPivotsOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L),
out.get(JAVA_DOUBLE, 16L),
out.get(JAVA_DOUBLE, 24L),
out.get(JAVA_DOUBLE, 32L),
out.get(JAVA_DOUBLE, 40L),
out.get(JAVA_DOUBLE, 48L),
out.get(JAVA_DOUBLE, 56L),
out.get(JAVA_DOUBLE, 64L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_CAMARILLA_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}
@@ -0,0 +1,5 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
/** Output record produced by the matching indicator. */
public record CamarillaPivotsOutput(double pp, double r1, double r2, double r3, double r4, double s1, double s2, double s3, double s4) {}
@@ -0,0 +1,61 @@
// Generated from bindings/c/include/wickra.h. Do not edit by hand.
package org.wickra;
import org.wickra.internal.NativeMethods;
import org.wickra.internal.WickraNative;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Cleaner;
import static java.lang.foreign.ValueLayout.*;
/** Streaming CandleVolume indicator over the Wickra C ABI. Not thread-safe; close when done. */
public final class CandleVolume implements AutoCloseable {
private final MemorySegment handle;
private final Cleaner.Cleanable cleanable;
public CandleVolume(int period) {
if (period < 0) {
throw new IllegalArgumentException("period must be non-negative");
}
MemorySegment h;
try {
h = (MemorySegment) NativeMethods.WICKRA_CANDLE_VOLUME_NEW.invokeExact((long) period);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
if (h.address() == 0L) {
throw new IllegalArgumentException("invalid CandleVolume parameters");
}
this.handle = h;
this.cleanable = WickraNative.register(this, h, NativeMethods.WICKRA_CANDLE_VOLUME_FREE);
}
/** Push one observation; returns the result, or null during warmup. */
public CandleVolumeOutput update(double open, double high, double low, double close, double volume, long timestamp) {
try (Arena a = Arena.ofConfined()) {
MemorySegment out = a.allocate(16L);
byte ok = (byte) NativeMethods.WICKRA_CANDLE_VOLUME_UPDATE.invokeExact(handle, open, high, low, close, volume, timestamp, out);
if (ok == 0) {
return null;
}
return new CandleVolumeOutput(
out.get(JAVA_DOUBLE, 0L),
out.get(JAVA_DOUBLE, 8L));
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
/** Reset to the just-constructed state. */
public void reset() {
try {
NativeMethods.WICKRA_CANDLE_VOLUME_RESET.invokeExact(handle);
} catch (Throwable t) {
throw WickraNative.rethrow(t);
}
}
@Override public void close() {
cleanable.clean();
}
}

Some files were not shown because too many files have changed in this diff Show More