Compare commits

..

7 Commits

Author SHA1 Message Date
kingchenc 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
kingchenc 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
kingchenc 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
kingchenc d0061c73b8 release: bump 0.7.6 -> 0.7.7 (#229)
Bumps the workspace to 0.7.7 to ship the Go binding.
2026-06-09 17:35:25 +02:00
kingchenc 23d636fd97 Add the Go binding over the C ABI hub (#228)
Adds a Go binding (`bindings/go`) over the C ABI hub — the second language stecker after C#.

## What's here
- **`bindings/go`** — a cgo binding exposing all 514 indicators as idiomatic Go types with `New<Indicator>` constructors and `Update`/`Batch`/`Reset`/`Close` methods. The wrappers in `indicators_gen.go` are generated from `bindings/c/include/wickra.h` (same archetype taxonomy as the C# generator: scalar/batch, multi-output, bars, profile, profile-values, array-input). Opaque handles are freed by `Close()` with a `runtime.SetFinalizer` backstop; pointer arguments are caller-owned, panics never cross the boundary.
- **`examples/go`** — the full example suite mirroring C/C#: streaming, backtest, multi_timeframe, parallel_assets (goroutine fan-out), three strategies, and `fetch_btcusdt`/`live_binance`.
- **CI** — a `go` job builds the C ABI library, stages it, and runs `gofmt`/`go vet`/`go test` plus the offline examples on Linux, macOS and Windows.
- **Docs** — Go 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 binding links the prebuilt C ABI library via cgo (`libwickra.so`/`.dylib`/`wickra.dll` staged under `bindings/go/lib`, gitignored). The native libraries are already shipped per target triple by the existing `c-abi-build` release job; distribution is via the subdirectory module tag `bindings/go/vX.Y.Z` (gated), so `release.yml` needs no new publish job.

No Rust crate or `Cargo.toml` change — the Go module is standalone and additive.

Not for merge yet (gated, per request).
2026-06-09 17:33:37 +02:00
kingchenc fce26cf881 release: bump 0.7.5 -> 0.7.6 (#227)
Bumps the workspace to 0.7.6 to ship the C# (.NET) binding to NuGet.
2026-06-09 14:34:18 +02:00
kingchenc 91f6f67257 Add C# (.NET) binding over the C ABI hub (#226)
The first language stecker on the C ABI hub: a .NET binding exposing all 514
indicators as idiomatic `IDisposable` classes, generated from `wickra.h`.

## What's here

- **`bindings/csharp/`** — the `Wickra` .NET 8 package. `[LibraryImport]`
  source-generated P/Invoke (`NativeMethods.g.cs`) plus idiomatic wrappers
  (`Indicators.g.cs`), both generated from the committed `bindings/c/include/wickra.h`.
  The binding owns no indicator maths — it only marshals types across the C ABI.
- **Marshalling, verified end-to-end against the native library.** Opaque handles
  cross as `nint` kept alive per call via a `SafeHandle`; `bool` as
  `[MarshalAs(U1)]` (Rust `bool` is one byte); a self-correcting
  `DllImportResolver` validates the loaded library actually exports the Wickra
  ABI. Tests cover one representative per FFI archetype (scalar, candle, pairwise,
  multi-output, bars, profile, values-profile, order-book / array-input) plus
  exact Sma reference values.
- **NuGet packaging** — `dotnet pack` produces `Wickra.<version>.nupkg`; the
  release pipeline stages prebuilt native libraries under `runtimes/<rid>/native/`
  for six target triples (win/linux/osx × x64/arm64).
- **`examples/csharp/`** — nine examples mirroring `examples/c/`: streaming,
  backtest, multi_timeframe, parallel_assets, three strategies, and
  fetch_btcusdt + live_binance.
- **CI** — a `csharp` job on the three OSes builds the C ABI, tests the binding,
  and runs the offline examples. **Release** — a gated `csharp-publish` job packs
  and pushes to NuGet (gated on `NUGET_API_KEY`, independent of the GitHub-release
  job so a C# hiccup never blocks the C/C++ asset release).
- **Docs consistency wave** — README, CONTRIBUTING, CHANGELOG, examples/README,
  the issue / PR templates, `sync-about.yml`, and `.gitattributes`.

The native Python / Node / WASM bindings and the C ABI are untouched; this is
additive. Publishing to NuGet stays gated behind the release tag and the secret.
2026-06-09 14:32:05 +02:00
637 changed files with 101470 additions and 142 deletions
+18
View File
@@ -6,3 +6,21 @@
# check (regenerate + `git diff`) never trips on a CRLF normalization.
bindings/c/include/wickra.h text eol=lf
# C# sources (including the generated binding) are pinned to LF so the committed
# files stay stable regardless of the committer's autocrlf setting.
*.cs text eol=lf
# Go sources (including the generated binding) are pinned to LF so gofmt's CI
# check never trips on a CRLF checkout on Windows.
*.go text eol=lf
go.mod text eol=lf
go.sum 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.win text eol=lf
bindings/r/src/Makevars text eol=lf
bindings/r/src/Makevars.win text eol=lf
bindings/r/src/wickra.c text eol=lf
+2 -2
View File
@@ -30,9 +30,9 @@ assignees: ""
## Environment
- Wickra version:
- Language / binding: <!-- Rust crate / Python / Node / WASM / C ABI -->
- Language / binding: <!-- Rust crate / Python / Node / WASM / C ABI / C# (.NET) / Go / R -->
- OS and architecture:
- Rust / Python / Node version (If relevant):
- Rust / Python / Node / .NET version (If relevant):
## Additional context
@@ -26,7 +26,7 @@ assignees: []
| Binding version | `e.g. python 0.4.2 / node 0.4.2` |
| OS / arch | `e.g. Windows 11 x86_64, Linux glibc` |
| Rust toolchain | `rustc --version` (If building from source) |
| Python / Node version | `python --version` / `node --version` |
| Python / Node / .NET version | `python --version` / `node --version` / `dotnet --version` |
## Minimal reproducer
@@ -25,6 +25,10 @@ assignees: ""
- [ ] Should be exposed in the Python binding
- [ ] Should be exposed in the Node binding
- [ ] Should be exposed in the WASM binding
- [ ] Should be exposed in the C ABI
- [ ] Should be exposed in the C# / .NET binding
- [ ] Should be exposed in the Go binding
- [ ] Should be exposed in the R binding
## Additional context
@@ -13,7 +13,7 @@ assignees: []
## Affected code path
- Indicator / API: `e.g. EMA.update`
- Binding: `Rust / Python / Node / Wasm / C ABI`
- Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go / R`
- Hot loop or one-shot call?
## Versions compared
+1 -1
View File
@@ -33,4 +33,4 @@ import wickra as ta
## Environment (Only if relevant)
- Wickra version: `e.g. 0.4.2`
- Binding: `Rust / Python / Node / Wasm / C ABI`
- Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go / R`
+1 -1
View File
@@ -22,7 +22,7 @@
- [ ] `cargo clippy --workspace --all-targets -- -D warnings` is clean.
- [ ] `cargo test --workspace` passes.
- [ ] 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 is regenerated
- [ ] Public API changes are mirrored in the Python / Node / WASM bindings, and the C ABI + C# + Go + R bindings are regenerated
and their type stubs (If applicable).
- [ ] The relevant page on the [documentation site](https://docs.wickra.org)
and the `README.md` are updated (If applicable). Docs edits go to a
@@ -23,6 +23,10 @@ Please fill in the sections below. Delete any that don't apply.
- [ ] Python binding (`bindings/python`)
- [ ] Node.js binding (`bindings/node`)
- [ ] WebAssembly binding (`bindings/wasm`)
- [ ] C ABI (`bindings/c`)
- [ ] C# / .NET binding (`bindings/csharp`)
- [ ] Go binding (`bindings/go`)
- [ ] R binding (`bindings/r`)
- [ ] Examples / docs
## Linked issues
+219
View File
@@ -677,6 +677,225 @@ jobs:
cmake --build examples/c/build --config Release
ctest --test-dir examples/c/build -C Release --output-on-failure
csharp:
name: C# 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 against the C ABI hub at runtime; build it first so the
# DllImportResolver finds target/release/wickra.{dll,so,dylib}. .NET 8 SDK is
# preinstalled on the GitHub runners, so no setup-dotnet step is needed.
- name: Build the C ABI library
run: cargo build -p wickra-c --release
- name: .NET info
run: dotnet --info
- name: Test the C# binding
run: dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj -c Release
- name: Build the C# examples
shell: bash
run: |
for d in streaming backtest multi_timeframe parallel_assets \
strategy_rsi_mean_reversion strategy_macd_adx strategy_bollinger_squeeze \
fetch_btcusdt live_binance; do
dotnet build "examples/csharp/$d" -c Release
done
# Run only the offline examples (fetch_btcusdt / live_binance need network).
- name: Run the offline C# examples
shell: bash
run: |
for d in streaming backtest multi_timeframe parallel_assets \
strategy_rsi_mean_reversion strategy_macd_adx strategy_bollinger_squeeze; do
dotnet run --project "examples/csharp/$d" -c Release --no-build
done
go:
name: Go 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
# Go is not reliably on PATH on every runner image, so install it
# explicitly. cache: false — the cargo build dominates and the modules
# have no external Go deps worth caching.
- name: Set up Go
id: setup-go
continue-on-error: true
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: "stable"
cache: false
- name: Retry Go setup (CDN flake)
if: steps.setup-go.outcome == 'failure'
shell: bash
run: |
echo "::warning::setup-go failed (likely CDN flake), waiting 30s before retry..."
sleep 30
- name: Set up Go (retry)
if: steps.setup-go.outcome == 'failure'
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: "stable"
cache: 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 against the C ABI hub via cgo; build it first and stage
# the platform library under bindings/go/lib so cgo's LDFLAGS find it. Go is
# preinstalled on the GitHub runners, so no setup-go step is needed.
- name: Build the C ABI library
run: cargo build -p wickra-c --release
- name: Stage the native library
shell: bash
run: |
mkdir -p bindings/go/lib
case "$RUNNER_OS" in
Linux) cp target/release/libwickra.so bindings/go/lib/ ;;
macOS) cp target/release/libwickra.dylib bindings/go/lib/ ;;
Windows) cp target/release/wickra.dll bindings/go/lib/ ;;
esac
- name: Go info
run: go version
- name: Check gofmt
shell: bash
run: |
unformatted="$(gofmt -l bindings/go examples/go)"
if [ -n "$unformatted" ]; then
echo "gofmt needed on:"; echo "$unformatted"; exit 1
fi
- name: Vet and test the Go binding
shell: bash
# On Windows there is no rpath; the loader resolves wickra.dll via PATH.
run: |
export PATH="$PWD/bindings/go/lib:$PATH"
cd bindings/go
go vet ./...
go test ./...
- name: Build the Go examples
shell: bash
run: |
export PATH="$PWD/bindings/go/lib:$PATH"
cd examples/go
go build ./...
# Run only the offline examples (fetch_btcusdt / live_binance need network).
- name: Run the offline Go examples
shell: bash
run: |
export PATH="$PWD/bindings/go/lib:$PATH"
cd examples/go
for d in streaming backtest multi_timeframe parallel_assets \
strategy_rsi_mean_reversion strategy_macd_adx strategy_bollinger_squeeze; do
go run "./$d"
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. On Linux/macOS the rpath points at
# WICKRA_LIB_DIR; export the loader path too as a belt-and-suspenders.
run: |
export WICKRA_INCLUDE_DIR="${WICKRA_INCLUDE_DIR//\\//}"
export WICKRA_LIB_DIR="${WICKRA_LIB_DIR//\\//}"
export LD_LIBRARY_PATH="$WICKRA_LIB_DIR:$LD_LIBRARY_PATH"
export DYLD_LIBRARY_PATH="$WICKRA_LIB_DIR:$DYLD_LIBRARY_PATH"
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
run: |
export WICKRA_LIB_DIR="${WICKRA_LIB_DIR//\\//}"
export LD_LIBRARY_PATH="$WICKRA_LIB_DIR:$LD_LIBRARY_PATH"
export DYLD_LIBRARY_PATH="$WICKRA_LIB_DIR:$DYLD_LIBRARY_PATH"
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")'
# The cross-library benchmark has moved to a dedicated scheduled workflow
# (.github/workflows/bench.yml) — see audit finding R10. It runs nightly
# at 03:00 UTC and on-demand via `workflow_dispatch`, and is no longer on
+82
View File
@@ -624,6 +624,88 @@ jobs:
path: wickra-c-${{ matrix.target }}.tar.gz
if-no-files-found: error
# Pack and publish the .NET binding to NuGet. Independent of the GitHub-release
# job so a C# hiccup never blocks the C/C++ asset release. Authentication uses
# NuGet Trusted Publishing (OIDC) — no long-lived API key. The 'wickra-release'
# trusted-publishing policy on nuget.org (owner KingchenC, repo wickra-lib/wickra,
# workflow release.yml) exchanges the GitHub OIDC token for a short-lived key.
csharp-publish:
name: Publish to NuGet
needs: c-abi-build
runs-on: ubuntu-latest
environment: release
permissions:
contents: read
id-token: write # request the GitHub OIDC token for trusted publishing
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 runtimes/<rid>/native
shell: bash
run: |
set -e
declare -A RID=(
[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/csharp/Wickra/runtimes
for target in "${!RID[@]}"; 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/${RID[$target]}/native"; 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 ${RID[$target]}:"; ls -l "$dest"
done
- name: Pack
shell: bash
run: |
version="${GITHUB_REF_NAME#v}"
dotnet pack bindings/csharp/Wickra/Wickra.csproj -c Release -p:Version="$version" -o nupkg
# Exchange the GitHub OIDC token for a short-lived (~1h) NuGet API key.
# 'user' is the nuget.org profile name (the package owner), not an email.
- name: NuGet login (OIDC -> temporary API key)
uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0
id: nuget_login
with:
user: KingchenC
# Pass the temporary key through the environment (not string-interpolated
# into the script) so it cannot be parsed as shell — avoids template injection.
- name: Push to NuGet
shell: bash
env:
NUGET_API_KEY: ${{ steps.nuget_login.outputs.NUGET_API_KEY }}
run: |
dotnet nuget push "nupkg/*.nupkg" --api-key "$NUGET_API_KEY" \
--source https://api.nuget.org/v3/index.json --skip-duplicate
- name: Upload the NuGet package as a build artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: nuget-package
path: nupkg/*.nupkg
if-no-files-found: error
github-release:
name: Attach assets to the draft GitHub Release
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
# push events we check out the default ref. No push is made, so a shallow
# 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
with:
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 }}
- name: Count indicators
@@ -149,7 +156,7 @@ jobs:
# actually live (Cloudflare Pages, P8.1); merging this PR is therefore
# gated on the domain resolving, otherwise the About link would 404.
homepage="https://docs.wickra.org"
desc="Streaming-first technical indicators with a Rust core and Python, Node.js, WebAssembly, and C ABI 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, 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
# corrects the stale kingchenc URL and self-heals any future drift.
# Same Administration-write permission as --description (no extra scope).
+17 -10
View File
@@ -27,21 +27,28 @@ or replace lives behind a separate crate boundary.
│ no I/O, no deps │ │ optional features │
└──────────────────────┘ └────────────────────┘
(every binding wraps the same core)
┌───────────┬────────────┴┬──────────────┬──────────────────────┐
│ │ │ │ │
┌──▼─────┐ ┌───▼────┐ ┌──────▼──────┐ ┌─────▼──────────────┐
Python │ │ Node │ │ WASM │ │ C ABI (cbindgen)
│ (PyO3) │ │(napi-rs)│ │(wasm-bindgen)│ │ cdylib + header │
└────────┘ └────────┘ └─────────────┘ └────────────────────┘
every binding wraps the same core
┌────────────┼────────────┬────────────────┐
│ │ │ │
┌──▼───────┐ ┌──▼───────┐ ┌──▼───────────┐ ┌──▼──────────────────┐
│ Python │ │ Node │ │ WASM │ │ C ABI (cbindgen) │
(PyO3) │ │ (napi-rs)│ │(wasm-bindgen)│ │ cdylib + header
└──────────┘ └──────────┘ └──────────────┘ └─────────┬───────────┘
│ linked by
┌──────────▼──────────┐
│ C · C++ · C# · Go │
│ · Java · R │
└─────────────────────┘
```
Python, Node and WASM are *native* Rust bindings (PyO3 / napi-rs /
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
C / C++ / Go / C# / Java / R consume that one artifact rather than each
re-wrapping the core.
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`,
on NuGet), the **Go** binding (`bindings/go`, cgo) and the **R** binding
(`bindings/r`, `.Call`) are generated from `wickra.h`, with Java planned the
same way.
| Crate | Path | What it owns | Public deps |
|---|---|---|---|
+29 -2
View File
@@ -5,7 +5,31 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [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
### Added
- **Go binding (`bindings/go`)** — a cgo binding over the C ABI hub exposing all
514 indicators as idiomatic types with `New<Indicator>` constructors and
`Update`/`Batch`/`Reset`/`Close` methods, generated from `wickra.h`. Handles are
freed by `Close()` with a `runtime.SetFinalizer` backstop. Ships a full example
suite mirroring the C and C# examples; distributed as a subdirectory module
(`go get github.com/wickra-lib/wickra/bindings/go`).
## [0.7.6] - 2026-06-09
### Added
- **C# / .NET binding (`bindings/csharp`)** — the first language stecker on the
C ABI hub. Exposes all 514 indicators as idiomatic `IDisposable` classes via
`[LibraryImport]` source-generated P/Invoke, generated from `wickra.h`. Ships
on NuGet as `Wickra` with prebuilt native libraries for six target triples
(win/linux/osx × x64/arm64), plus a full example suite mirroring the C examples.
## [0.7.5] - 2026-06-09
### Added
@@ -1426,7 +1450,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
optional Binance live feed.
- Bindings for Python, Node.js, and WebAssembly.
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.7.5...HEAD
[Unreleased]: https://github.com/wickra-lib/wickra/compare/v0.7.8...HEAD
[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.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.4]: https://github.com/wickra-lib/wickra/compare/v0.7.3...v0.7.4
[0.7.3]: https://github.com/wickra-lib/wickra/compare/v0.7.2...v0.7.3
+9 -1
View File
@@ -22,6 +22,9 @@ licensed as above, without any additional terms or conditions.
| `bindings/node` | napi-rs bindings (`wickra` on npm). |
| `bindings/wasm` | wasm-bindgen bindings (`wickra-wasm` on npm). |
| `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/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`. |
| `examples/` | Runnable examples. |
| `docs/` | Pointer to the documentation site (docs.wickra.org); the docs live in the `wickra-lib/wickra-docs` repo. |
@@ -105,7 +108,12 @@ installed. Dependabot also keeps the `.github/requirements` pins current.
- **Bindings.** A change to a public indicator API must be mirrored across the
Python, Node, and WASM bindings, including their type stubs / `.d.ts`. The C ABI
(`bindings/c`) is generated from the core, so regenerate it from the core and
commit `src/lib.rs` + `include/wickra.h`.
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.
The Go binding (`bindings/go`) is likewise generated from `wickra.h`, so
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`.
- **Docs.** Update the relevant page on the
[documentation site](https://docs.wickra.org) and the
`README.md` when behaviour or the public API changes. The docs live in
Generated
+9 -9
View File
@@ -1944,7 +1944,7 @@ dependencies = [
[[package]]
name = "wickra"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"approx",
"criterion",
@@ -1955,7 +1955,7 @@ dependencies = [
[[package]]
name = "wickra-bench"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"criterion",
"kand",
@@ -1967,14 +1967,14 @@ dependencies = [
[[package]]
name = "wickra-c"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"wickra-core",
]
[[package]]
name = "wickra-core"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"approx",
"proptest",
@@ -1984,7 +1984,7 @@ dependencies = [
[[package]]
name = "wickra-data"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"approx",
"csv",
@@ -2001,7 +2001,7 @@ dependencies = [
[[package]]
name = "wickra-examples"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"serde_json",
"tokio",
@@ -2011,7 +2011,7 @@ dependencies = [
[[package]]
name = "wickra-node"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"napi",
"napi-build",
@@ -2021,7 +2021,7 @@ dependencies = [
[[package]]
name = "wickra-python"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"numpy",
"pyo3",
@@ -2030,7 +2030,7 @@ dependencies = [
[[package]]
name = "wickra-wasm"
version = "0.7.5"
version = "0.7.8"
dependencies = [
"console_error_panic_hook",
"js-sys",
+2 -2
View File
@@ -14,7 +14,7 @@ members = [
exclude = ["fuzz"]
[workspace.package]
version = "0.7.5"
version = "0.7.8"
authors = ["kingchenc <support@wickra.org>"]
edition = "2021"
rust-version = "1.86"
@@ -26,7 +26,7 @@ keywords = ["finance", "trading", "indicators", "technical-analysis", "ta"]
categories = ["finance", "mathematics", "science"]
[workspace.dependencies]
wickra-core = { path = "crates/wickra-core", version = "0.7.5" }
wickra-core = { path = "crates/wickra-core", version = "0.7.8" }
thiserror = "2"
rayon = "1.10"
+52 -21
View File
@@ -2,24 +2,25 @@
<a href="https://wickra.org"><img src="https://raw.githubusercontent.com/wickra-lib/.github/main/profile/wickra-banner.webp?v=514" alt="Wickra — streaming-first technical indicators" width="100%"></a>
</p>
[![CI](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![CodeQL](https://github.com/wickra-lib/wickra/actions/workflows/codeql.yml/badge.svg)](https://github.com/wickra-lib/wickra/actions/workflows/codeql.yml)
[![codecov](https://codecov.io/gh/wickra-lib/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![GitHub release](https://img.shields.io/github/v/release/wickra-lib/wickra?logo=github&color=green)](https://github.com/wickra-lib/wickra/releases/latest)
[![crates.io](https://img.shields.io/crates/v/wickra.svg?logo=rust&color=orange)](https://crates.io/crates/wickra)
[![PyPI](https://img.shields.io/pypi/v/wickra.svg?logo=pypi&color=blue)](https://pypi.org/project/wickra/)
[![npm](https://img.shields.io/npm/v/wickra.svg?logo=npm&color=red)](https://www.npmjs.com/package/wickra)
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue)](#license)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/wickra-lib/wickra/badge)](https://scorecard.dev/viewer/?uri=github.com/wickra-lib/wickra)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/13094/badge)](https://www.bestpractices.dev/projects/13094)
[![Build provenance](https://img.shields.io/badge/provenance-attested-brightgreen?logo=github)](https://github.com/wickra-lib/wickra/attestations)
[![Docs](https://img.shields.io/badge/docs-docs.wickra.org-0ea5e9?logo=readthedocs&logoColor=white)](https://docs.wickra.org)
[![CI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/ci.svg)](https://github.com/wickra-lib/wickra/actions/workflows/ci.yml)
[![CodeQL](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codeql.svg)](https://github.com/wickra-lib/wickra/actions/workflows/codeql.yml)
[![codecov](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/codecov.svg)](https://codecov.io/gh/wickra-lib/wickra)
[![GitHub release](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/release.svg)](https://github.com/wickra-lib/wickra/releases/latest)
[![crates.io](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/crates.svg)](https://crates.io/crates/wickra)
[![PyPI](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/pypi.svg)](https://pypi.org/project/wickra/)
[![npm](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/npm.svg)](https://www.npmjs.com/package/wickra)
[![NuGet](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/nuget.svg)](https://www.nuget.org/packages/Wickra)
[![License: MIT OR Apache-2.0](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/license.svg)](#license)
[![OpenSSF Scorecard](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/scorecard.svg)](https://scorecard.dev/viewer/?uri=github.com/wickra-lib/wickra)
[![OpenSSF Best Practices](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/best-practices.svg)](https://www.bestpractices.dev/projects/13094)
[![Build provenance](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/provenance.svg)](https://github.com/wickra-lib/wickra/attestations)
[![Docs](https://raw.githubusercontent.com/wickra-lib/.github/main/profile/badges/docs.svg)](https://docs.wickra.org)
**Streaming-first technical indicators. Install with `pip install wickra` — no system dependencies.**
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 any
C-capable language (C, C++, and beyond) links against. Every indicator is a
native bindings for Python, Node.js and WebAssembly, plus a C ABI that C, C++,
C# / .NET, Go, 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
historical backtests share the exact same implementation.
@@ -47,7 +48,11 @@ Full documentation lives at **[docs.wickra.org](https://docs.wickra.org)**:
- **Quickstarts** — [Rust](https://docs.wickra.org/Quickstart-Rust),
[Python](https://docs.wickra.org/Quickstart-Python),
[Node](https://docs.wickra.org/Quickstart-Node),
[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-CSharp),
[Go](https://docs.wickra.org/Quickstart-Go),
[R](https://docs.wickra.org/Quickstart-R).
- **Indicators** — a per-indicator deep dive (formula, parameters, warmup) for
every one of the 514 indicators; start at the
[indicators overview](https://docs.wickra.org/Indicators-Overview).
@@ -73,7 +78,7 @@ times to get there.
metrics — every single one updating in **O(1) per tick**. TA-Lib ships ~150 and
none of them stream.
- **One Rust core, five first-class targets.** Native **Python · Node.js ·
WebAssembly · Rust** plus a **C ABI** for C / C++ and any C-capable language —
WebAssembly · Rust** plus a **C ABI** for C / C++, C# / .NET, Go, R and any other C-capable language —
identical math, identical results, zero per-language reimplementation and zero
GIL bottleneck.
- **Correct by construction, not by hope.** Every `update` validates its input,
@@ -97,7 +102,8 @@ Every other library forces one of those compromises. Wickra doesn't:
| Library | Install | Streaming | Languages | Indicators | Active |
|------------------|-------------|-------------|-----------------------------|-----------:|--------|
| **★&nbsp;Wickra**| **clean** | **yes, O(1)** | **Python · Node · WASM · Rust · C** | **514** | **yes** |
| **★&nbsp;Wickra**| **clean** | **yes, O(1)** | **Rust · Python · Node · WASM** | **514** | **yes** |
| | | | **C · C# · Go · R** | | |
| kand | clean | yes | Python · WASM · Rust | ~60 | yes |
| ta-rs | clean | yes | Rust only | ~30 | stale |
| yata | clean | partial | Rust only | ~35 | yes |
@@ -168,8 +174,9 @@ as one column each. `Doji` is direction-less by default (`+1.0` / `0.0`);
construct it in signed mode (`Doji::new().signed()`, `Doji(signed=True)`,
`new Doji(true)`) for a dragonfly / gravestone `±1` reading.
Adding a new indicator means implementing one trait in Rust; all five bindings
inherit it automatically (the C ABI is generated from the core).
Adding a new indicator means implementing one trait in Rust; every binding
inherits it automatically (the C ABI — and the C#, Go and R bindings generated from
it — regenerate from the core).
## Languages
@@ -180,6 +187,9 @@ inherit it automatically (the C ABI is generated from the core).
| Browser / WASM | `npm install wickra-wasm` | `examples/wasm/index.html` |
| Rust | `cargo add wickra` | `examples/rust/src/bin/backtest.rs` |
| 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` |
| Go (cgo, C ABI) | `go get github.com/wickra-lib/wickra/bindings/go`, see [`bindings/go`](bindings/go) | `examples/go/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);
[`examples/README.md`](examples/README.md) is the full cross-language index.
@@ -249,14 +259,20 @@ wickra/
│ ├── python/ PyO3 + maturin (publishes on PyPI)
│ ├── node/ napi-rs (publishes on npm)
│ ├── 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)
│ ├── go/ Go binding over the C ABI via cgo (module tag)
│ └── r/ R binding over the C ABI via .Call (R package)
├── examples/ examples/README.md indexes every language
│ ├── data/ real BTCUSDT OHLCV datasets, one per timeframe
│ ├── rust/ Rust workspace member (`wickra-examples`)
│ ├── python/ backtest, live trading, parallel assets, multi-tf
│ ├── node/ streaming, backtest, live trading (load `wickra`)
│ ├── 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`)
│ ├── go/ streaming, backtest, strategies (cgo binding)
│ └── r/ streaming, backtest, strategies (.Call binding)
└── .github/workflows/ CI and release pipelines
```
@@ -289,6 +305,17 @@ cd bindings/node && npm install && npm run build && npm test
cargo build -p wickra-c --release
cmake -S examples/c -B examples/c/build -DWICKRA_LIB_DIR="$PWD/target/release"
cmake --build examples/c/build && ctest --test-dir examples/c/build --output-on-failure
# C# / .NET binding (requires the .NET 8 SDK; links the C ABI above)
dotnet test bindings/csharp/Wickra.Tests/Wickra.Tests.csproj
# 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
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
```
## Testing
@@ -308,6 +335,10 @@ Every layer is covered; run the suites with the commands in
values across all indicators.
- `bindings/wasm`: `wasm-bindgen-test` cases for constructors, equivalence,
and reference values.
- `bindings/go`: `go test` cases covering one indicator per FFI archetype
(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.
## Contributing
+3 -2
View File
@@ -21,8 +21,9 @@ minor releases; breaking changes are called out in the changelog.
versioning stability for a 1.0 release.
- **Performance.** Keep per-tick updates O(1) and maintain the benchmark suite;
investigate further allocation and cache improvements.
- **Bindings parity.** Keep the Python, Node.js and WebAssembly bindings in
lockstep with the Rust core, including type stubs and platform coverage.
- **Bindings parity.** Keep the Python, Node.js and WebAssembly bindings — plus
the C ABI and the C# / .NET, Go and R bindings generated from it — in lockstep with the
Rust core, including type stubs and platform coverage.
- **Documentation.** Maintain a deep-dive page per indicator on
<https://docs.wickra.org>, plus quickstarts and cookbook material.
- **Project health.** Maintain test coverage, static and dynamic analysis,
+2 -2
View File
@@ -7,8 +7,8 @@ Thanks for using Wickra! Here is where to get help, depending on what you need.
Most questions are answered in the documentation:
- **Docs site:** <https://docs.wickra.org> — quickstarts for Rust, Python,
Node.js and WebAssembly, a per-indicator reference, warmup periods, the data
layer, and an FAQ.
Node.js, WebAssembly, C, C#, Go and R, a per-indicator reference, warmup periods, the
data layer, and an FAQ.
- **README:** <https://github.com/wickra-lib/wickra#readme> — installation and a
quick overview.
- **API docs (Rust):** <https://docs.rs/wickra>.
+2 -1
View File
@@ -3,7 +3,8 @@
This document describes Wickra's attack surface and the threats considered,
together with their mitigations. It complements the security assurance case in
[`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, Go and R bindings built on it),
not a network service or trading system; the attack surface is correspondingly
small.
+57 -36
View File
@@ -1,59 +1,80 @@
# wickra-c
# Wickra — C / C++
C ABI for [Wickra](https://github.com/wickra-lib/wickra) — streaming-first
technical indicators with a Rust core. This crate is the **hub**: it compiles the
[![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)
[![GitHub release](https://img.shields.io/github/v/release/wickra-lib/wickra?logo=github&color=green)](https://github.com/wickra-lib/wickra/releases/latest)
[![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 C and C++. A prebuilt shared/static
library plus a generated `wickra.h` — 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, 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 **C ABI hub**: it compiles the
core to a C-compatible shared/static library plus a generated header, so any
C-capable language (C, C++, Go, C#, Java, R) links against one artifact instead
of re-wiring every indicator natively.
of re-wrapping every indicator natively.
The native Python, Node, and WebAssembly bindings are unaffected — this is
additive, for the ecosystems without first-class Rust tooling.
## Install
## Artifacts
Grab the prebuilt header + library for your platform from the
[GitHub releases](https://github.com/wickra-lib/wickra/releases) — each archive
has `wickra.h`, the optional `wickra.hpp` C++ wrapper, and the shared/static
library — or build from source:
```sh
```bash
cargo build -p wickra-c --release
# -> target/release/libwickra.{so,dylib} or wickra.dll (+ import lib) + a staticlib
```
- `target/release/libwickra.{so,dylib}` / `wickra.dll` (+ `wickra.dll.lib` import lib on Windows)
- `target/release/libwickra.a` / `wickra.lib` (static)
- [`include/wickra.h`](include/wickra.h) — generated by cbindgen, committed.
Then compile against the header and link the library
(`cc app.c -I include -L lib -lwickra -lm -o app`).
## API shape
Each indicator is exposed as five `extern "C"` functions over an opaque handle:
## Quick start
```c
struct Sma *wickra_sma_new(uintptr_t period); /* NULL on bad params */
double wickra_sma_update(struct Sma *h, double value); /* NaN during warmup */
void wickra_sma_batch(struct Sma *h, const double *in, double *out, uintptr_t n);
void wickra_sma_reset(struct Sma *h);
void wickra_sma_free(struct Sma *h); /* exactly once per _new */
#include "wickra.h"
struct Rsi *rsi = wickra_rsi_new(14); /* NULL on invalid params */
for (size_t i = 0; i < n; ++i) {
double v = wickra_rsi_update(rsi, prices[i]); /* NaN during warmup */
if (v == v && v > 70.0) /* v == v is the NaN check */
printf("overbought\n");
}
wickra_rsi_free(rsi); /* exactly once per _new */
```
Conventions:
Every indicator is an opaque handle with the same five functions
`_new` / `_update` / `_batch` / `_reset` / `_free`. `update` is O(1); there is no
RAII across the C boundary, so each `_new` needs exactly one `_free`, and every
function is NULL-safe (a NULL handle yields `NaN` or a no-op, never a crash).
Multi-output indicators (MACD, Bollinger, ADX, …) take a pointer to a `#[repr(C)]`
struct and return a `bool`. The optional `wickra.hpp` wraps any handle in a
move-only `wickra::Handle` for exception-safe C++ lifetimes.
- **Opaque handles.** `wickra_<ind>_new` returns a `T *` you must release with
exactly one `wickra_<ind>_free`. There is no RAII across the boundary.
- **NaN sentinel.** Scalar outputs return `NaN` while warming up or on a `NULL`
handle, mirroring the other bindings — no error codes for the common path.
- **Caller-owned batch buffers.** `wickra_<ind>_batch` writes one output per
input into a buffer you provide; nothing is allocated across the boundary.
- **NULL-safe.** Every function tolerates a `NULL` handle without crashing.
## Documentation
## Header regeneration
The full indicator catalogue, guides, quickstarts, and API reference live in
the main repository and documentation site:
The header is generated and committed; CI checks it is in sync:
- **Repository & full indicator list:** <https://github.com/wickra-lib/wickra>
- **Docs** (C quickstart, cookbook, TA-Lib migration): <https://docs.wickra.org/Quickstart-C>
- **Runnable examples:** [`examples/c/`](https://github.com/wickra-lib/wickra/tree/main/examples/c)
```sh
cbindgen --config bindings/c/cbindgen.toml --crate wickra-c --output bindings/c/include/wickra.h
```
Wickra ships native bindings for Python, Node.js, WebAssembly and Rust, plus this
C ABI hub that any C-capable language (C, C++, Go, C#, Java, R) links against —
all exposing the same indicators from the shared Rust core.
## Examples
## Disclaimer
Runnable C examples (build via CMake or a direct compiler invocation) live in
[`examples/c`](../../examples/c).
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
`MIT OR Apache-2.0`, the same as the rest of Wickra.
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.
+12
View File
@@ -0,0 +1,12 @@
# .NET build output
bin/
obj/
*.user
# NuGet packaging output
*.nupkg
*.snupkg
# Native libraries staged for packaging (produced by the release pipeline from
# the wickra-c-<triple>.tar.gz assets; never committed to source).
Wickra/runtimes/
+78
View File
@@ -0,0 +1,78 @@
# Wickra — .NET
[![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)
[![NuGet](https://img.shields.io/nuget/v/Wickra.svg?logo=nuget&color=blue)](https://www.nuget.org/packages/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 .NET. `dotnet add package Wickra`
prebuilt native library, 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, 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 .NET binding; it consumes the
C ABI hub through `[LibraryImport]` P/Invoke and exposes all 514 streaming-first
indicators as idiomatic `IDisposable` classes.
## Install
```bash
dotnet add package Wickra
```
The native library ships prebuilt per platform (Linux, macOS, Windows — x64 and
arm64) under `runtimes/<rid>/native/`, selected automatically. There is nothing
to compile. Targets .NET 8 and later.
## Quick start
```csharp
using Wickra;
// Batch: run an indicator over a whole series (NaN at warmup positions).
var prices = Enumerable.Range(0, 1000).Select(i => 100.0 + i * 0.1).ToArray();
using var sma = new Sma(20);
double[] values = sma.Batch(prices);
// Streaming: the same indicator, fed tick by tick in O(1).
using var rsi = new Rsi(14);
foreach (var price in liveFeed)
{
var value = rsi.Update(price); // NaN during warmup, no recomputation
if (double.IsFinite(value) && value > 70)
{
Console.WriteLine("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 nullable `record struct`, `null` while warming up.
## 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/csharp/`](https://github.com/wickra-lib/wickra/tree/main/examples/csharp)
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.
@@ -0,0 +1,144 @@
using Wickra;
using Xunit;
namespace Wickra.Tests;
/// <summary>
/// One representative per FFI archetype, exercising every marshalling path the
/// generator produces (scalar, candle, pairwise, multi-output, bars, profile,
/// values-profile, array-input). Garbage marshalling surfaces as NaN, wild
/// values, or crashes — so finite/sane assertions are the real check.
/// </summary>
public class ArchetypeTests
{
private static (double open, double high, double low, double close, double volume, long ts) Candle(int i)
{
var close = 100.0 + 10.0 * Math.Sin(i * 0.3);
var open = 100.0 + 10.0 * Math.Sin((i - 1) * 0.3);
var high = Math.Max(open, close) + 1.0;
var low = Math.Min(open, close) - 1.0;
return (open, high, low, close, 1_000.0, i * 60_000L);
}
[Fact]
public void Scalar_Ema_IsFiniteAfterWarmup()
{
using var ema = new Ema(3);
double last = double.NaN;
for (var i = 1; i <= 10; i++)
{
last = ema.Update(i);
}
Assert.True(double.IsFinite(last));
Assert.InRange(last, 1.0, 10.0);
}
[Fact]
public void Candle_Atr_IsFinitePositive()
{
using var atr = new Atr(3);
double last = double.NaN;
for (var i = 0; i < 20; i++)
{
var (o, h, l, c, v, ts) = Candle(i);
last = atr.Update(o, h, l, c, v, ts);
}
Assert.True(double.IsFinite(last));
Assert.True(last > 0.0);
}
[Fact]
public void Pairwise_Beta_IsFinite()
{
using var beta = new Beta(5);
double last = double.NaN;
for (var i = 0; i < 30; i++)
{
var market = 100.0 + 10.0 * Math.Sin(i * 0.5);
var asset = 50.0 + 6.0 * Math.Sin(i * 0.5 + 0.2);
last = beta.Update(market, asset);
}
Assert.True(double.IsFinite(last));
}
[Fact]
public void MultiOutput_Adx_ReturnsFiniteStruct()
{
using var adx = new Adx(5);
AdxOutput? result = null;
for (var i = 0; i < 60; i++)
{
var (o, h, l, c, v, ts) = Candle(i);
result = adx.Update(o, h, l, c, v, ts);
}
Assert.NotNull(result);
Assert.True(double.IsFinite(result!.Value.Adx));
Assert.True(double.IsFinite(result.Value.PlusDi));
Assert.True(double.IsFinite(result.Value.MinusDi));
}
[Fact]
public void Bars_DollarBars_EmitsBars()
{
using var bars = new DollarBars(5_000.0);
var total = 0;
for (var i = 0; i < 200; i++)
{
var (o, h, l, c, v, ts) = Candle(i);
total += bars.Update(o, h, l, c, v, ts).Length;
}
Assert.True(total > 0);
}
[Fact]
public void Profile_VolumeProfile_ReturnsValues()
{
using var profile = new VolumeProfile(20, 8);
VolumeProfileOutputScalars? result = null;
for (var i = 0; i < 60; i++)
{
var (o, h, l, c, v, ts) = Candle(i);
result = profile.Update(o, h, l, c, v, ts);
}
Assert.NotNull(result);
Assert.NotNull(result!.Value.Values);
Assert.True(result.Value.PriceLow <= result.Value.PriceHigh);
}
[Fact]
public void ProfileValues_DayOfWeekProfile_NoCrash()
{
using var profile = new DayOfWeekProfile(0);
double[]? result = null;
for (var i = 0; i < 60; i++)
{
var close = 100.0 + 5.0 * Math.Sin(i * 0.2);
// one day apart so the day-of-week buckets fill
result = profile.Update(close, close + 1, close - 1, close, 1_000.0, i * 86_400_000L);
}
if (result is not null)
{
Assert.All(result, v => Assert.True(double.IsFinite(v)));
}
}
[Fact]
public void ArrayInput_DepthSlope_IsFinite()
{
using var slope = new DepthSlope();
ReadOnlySpan<double> bidPrice = stackalloc double[] { 99.0, 98.0, 97.0 };
ReadOnlySpan<double> bidSize = stackalloc double[] { 10.0, 20.0, 30.0 };
ReadOnlySpan<double> askPrice = stackalloc double[] { 101.0, 102.0, 103.0 };
ReadOnlySpan<double> askSize = stackalloc double[] { 12.0, 22.0, 32.0 };
var result = slope.Update(bidPrice, bidSize, askPrice, askSize);
Assert.True(double.IsFinite(result));
}
}
+51
View File
@@ -0,0 +1,51 @@
using Wickra;
using Xunit;
namespace Wickra.Tests;
public class SmaTests
{
[Fact]
public void StreamingMatchesReference()
{
using var sma = new Sma(3);
Assert.True(double.IsNaN(sma.Update(1)));
Assert.True(double.IsNaN(sma.Update(2)));
Assert.Equal(2.0, sma.Update(3), 9);
Assert.Equal(3.0, sma.Update(4), 9);
Assert.Equal(4.0, sma.Update(5), 9);
}
[Fact]
public void BatchMatchesStreaming()
{
using var sma = new Sma(3);
var output = sma.Batch(new double[] { 1, 2, 3, 4, 5 });
Assert.True(double.IsNaN(output[0]));
Assert.True(double.IsNaN(output[1]));
Assert.Equal(2.0, output[2], 9);
Assert.Equal(3.0, output[3], 9);
Assert.Equal(4.0, output[4], 9);
}
[Fact]
public void ResetClearsState()
{
using var sma = new Sma(3);
sma.Update(1);
sma.Update(2);
sma.Update(3);
sma.Reset();
Assert.True(double.IsNaN(sma.Update(10)));
}
[Fact]
public void ZeroPeriodThrows()
{
// Zero is rejected by the native constructor (returns NULL) -> ArgumentException;
// a negative period is caught earlier by the wrapper guard.
Assert.Throws<ArgumentException>(() => new Sma(0));
Assert.Throws<ArgumentOutOfRangeException>(() => new Sma(-1));
}
}
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Wickra\Wickra.csproj" />
</ItemGroup>
</Project>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RootNamespace>Wickra</RootNamespace>
<AssemblyName>Wickra</AssemblyName>
<!-- NuGet package metadata -->
<PackageId>Wickra</PackageId>
<Version>0.7.8</Version>
<Authors>kingchenc</Authors>
<Description>High-performance streaming technical-analysis indicators (514 indicators) for .NET, backed by the native Rust core via the Wickra C ABI.</Description>
<PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/wickra-lib/wickra</PackageProjectUrl>
<RepositoryUrl>https://github.com/wickra-lib/wickra</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>technical-analysis;indicators;trading;finance;streaming;ffi;native</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!-- A managed package carrying per-RID native assets; not built per-RID itself. -->
<IncludeBuildOutput>true</IncludeBuildOutput>
<!-- NU5128: managed package carrying only per-RID native assets.
CS1591: generated members are self-descriptive; hand-written API is documented. -->
<NoWarn>$(NoWarn);NU5128;CS1591</NoWarn>
</PropertyGroup>
<!--
Supported native runtime identifiers. The release pipeline builds the C ABI
per target triple and stages the libraries under
Wickra/runtimes/<rid>/native/ before `dotnet pack`:
win-x64 win-arm64 linux-x64 linux-arm64 osx-x64 osx-arm64
-->
<PropertyGroup>
<WickraRuntimeIdentifiers>win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</WickraRuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<!--
Native libraries are packed under runtimes/<rid>/native/ by the release pipeline,
which unpacks the wickra-c-<triple>.tar.gz assets into the matching RID folders.
For local development and tests the natives are resolved from the cargo target dir
via WickraNative's DllImportResolver.
-->
<ItemGroup>
<None Include="runtimes/**/native/*" Pack="true" PackagePath="runtimes" Condition="Exists('runtimes')" />
</ItemGroup>
</Project>
+26
View File
@@ -0,0 +1,26 @@
using Microsoft.Win32.SafeHandles;
namespace Wickra;
/// <summary>
/// Owns an opaque native indicator handle and releases it via the indicator's
/// <c>_free</c> function. One generic handle type backs every indicator; the
/// correct free routine is captured at construction time.
/// </summary>
internal sealed class WickraHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private readonly Action<nint> _free;
internal WickraHandle(nint handle, Action<nint> free)
: base(ownsHandle: true)
{
_free = free;
SetHandle(handle);
}
protected override bool ReleaseHandle()
{
_free(handle);
return true;
}
}
+87
View File
@@ -0,0 +1,87 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Wickra;
/// <summary>
/// Native library resolution for the Wickra C ABI.
/// </summary>
/// <remarks>
/// When consumed as a NuGet package the native library ships under
/// <c>runtimes/&lt;rid&gt;/native/</c> and the default runtime resolver finds it
/// automatically. For local development (project reference against a cargo build)
/// the resolver additionally walks up the directory tree to locate
/// <c>target/release</c> or <c>target/debug</c>. Every candidate is validated to
/// actually export the Wickra ABI before it is accepted, so an unrelated library
/// of the same name cannot shadow the real one.
/// </remarks>
internal static class WickraNative
{
/// <summary>The library name passed to <c>[LibraryImport]</c>.</summary>
internal const string LibraryName = "wickra";
// Any exported symbol works as a fingerprint; sma_new exists in every build.
private const string SentinelSymbol = "wickra_sma_new";
[ModuleInitializer]
internal static void Register()
{
NativeLibrary.SetDllImportResolver(typeof(WickraNative).Assembly, Resolve);
}
private static nint Resolve(string libraryName, System.Reflection.Assembly assembly, DllImportSearchPath? searchPath)
{
if (libraryName != LibraryName)
{
return nint.Zero;
}
// 1. Default resolution (NuGet runtimes/ layout, app-local copies). Accept
// only if it is genuinely the Wickra ABI; otherwise discard and fall through.
if (NativeLibrary.TryLoad(libraryName, assembly, searchPath, out var handle))
{
if (Exports(handle))
{
return handle;
}
NativeLibrary.Free(handle);
}
// 2. Development fallback: locate the cargo build output.
var fileName = NativeFileName();
var dir = AppContext.BaseDirectory;
for (var i = 0; i < 16 && dir is not null; i++)
{
foreach (var profile in new[] { "release", "debug" })
{
var candidate = Path.Combine(dir, "target", profile, fileName);
if (File.Exists(candidate) && NativeLibrary.TryLoad(candidate, out var devHandle))
{
if (Exports(devHandle))
{
return devHandle;
}
NativeLibrary.Free(devHandle);
}
}
dir = Path.GetDirectoryName(dir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
}
return nint.Zero;
}
private static bool Exports(nint handle) => NativeLibrary.TryGetExport(handle, SentinelSymbol, out _);
private static string NativeFileName()
{
if (OperatingSystem.IsWindows())
{
return "wickra.dll";
}
return OperatingSystem.IsMacOS() ? "libwickra.dylib" : "libwickra.so";
}
}
+100
View File
@@ -0,0 +1,100 @@
# Wickra — Go
[![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)
[![Go Reference](https://pkg.go.dev/badge/github.com/wickra-lib/wickra/bindings/go.svg)](https://pkg.go.dev/github.com/wickra-lib/wickra/bindings/go)
[![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 Go, over the Wickra C ABI hub via cgo.**
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 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 Go binding; it consumes the C ABI hub through
cgo and exposes all 514 streaming-first indicators as idiomatic types.
## Install
```bash
go get github.com/wickra-lib/wickra/bindings/go
```
The binding uses cgo, so a C compiler is required, and it links against the
prebuilt Wickra C ABI library. Build that library from the workspace and stage
it under this package's `lib/` directory:
```bash
cargo build -p wickra-c --release
cp target/release/libwickra.so bindings/go/lib/ # Linux
cp target/release/libwickra.dylib bindings/go/lib/ # macOS
cp target/release/wickra.dll bindings/go/lib/ # Windows (also on PATH at run time)
```
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
```go
package main
import (
"fmt"
wickra "github.com/wickra-lib/wickra/bindings/go"
)
func main() {
// Batch: run an indicator over a whole series (NaN at warmup positions).
prices := make([]float64, 1000)
for i := range prices {
prices[i] = 100.0 + float64(i)*0.1
}
sma, _ := wickra.NewSma(20)
defer sma.Close()
values := sma.Batch(prices)
// Streaming: the same indicator, fed tick by tick in O(1).
rsi, _ := wickra.NewRsi(14)
defer rsi.Close()
for _, price := range prices {
value := rsi.Update(price) // NaN during warmup, no recomputation
if value > 70 {
fmt.Println("overbought")
}
}
_ = values
}
```
`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 `(Output, bool)`, with `false` while warming up.
Every indicator owns a native handle freed by `Close()`; a finalizer is wired as
a backstop, but call `Close()` (e.g. with `defer`) to release memory promptly.
## 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/go/`](https://github.com/wickra-lib/wickra/tree/main/examples/go)
Wickra ships native bindings for Python, Node.js, WebAssembly and Rust, plus a
C ABI hub that any C-capable language (C, C++, C#, Go, 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.
+3
View File
@@ -0,0 +1,3 @@
module github.com/wickra-lib/wickra/bindings/go
go 1.23
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
# Prebuilt Wickra C ABI libraries are provisioned locally / in CI, not committed.
*.so
*.dylib
*.dll
*.a
*.lib
*.exp
+25
View File
@@ -0,0 +1,25 @@
// Package wickra provides idiomatic Go bindings for the Wickra
// technical-analysis library over its C ABI hub.
//
// 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
// backstop, by a finalizer; call Close explicitly to release native memory
// promptly. The binding links against the prebuilt Wickra C ABI library
// (libwickra.so/.dylib or wickra.dll) staged under ./lib — see the package
// README for how to provision it.
package wickra
/*
#cgo CFLAGS: -I${SRCDIR}/../c/include
#cgo linux LDFLAGS: -L${SRCDIR}/lib -lwickra -Wl,-rpath,${SRCDIR}/lib
#cgo darwin LDFLAGS: -L${SRCDIR}/lib -lwickra -Wl,-rpath,${SRCDIR}/lib
#cgo windows LDFLAGS: -L${SRCDIR}/lib -l:wickra.dll
#include "wickra.h"
*/
import "C"
import "errors"
// ErrInvalidParams is returned by a New<Indicator> constructor when the native
// constructor rejects the supplied parameters (for example a zero period).
var ErrInvalidParams = errors.New("wickra: invalid indicator parameters")
+151
View File
@@ -0,0 +1,151 @@
package wickra
import (
"math"
"testing"
)
// One indicator per FFI archetype, exercising the full New/Update/Batch/Reset/
// Close surface against the real native library.
func TestScalarKnownValue(t *testing.T) {
s, err := NewSma(3)
if err != nil {
t.Fatalf("NewSma: %v", err)
}
defer s.Close()
var last float64
for _, v := range []float64{1, 2, 3, 4, 5} {
last = s.Update(v)
}
if math.Abs(last-4.0) > 1e-9 {
t.Fatalf("sma(3) last = %v, want 4.0", last)
}
}
func TestScalarBatchMatchesStreaming(t *testing.T) {
input := []float64{1, 2, 3, 4, 5, 6, 7, 8}
stream, _ := NewSma(3)
defer stream.Close()
want := make([]float64, len(input))
for i, v := range input {
want[i] = stream.Update(v)
}
batchInd, _ := NewSma(3)
defer batchInd.Close()
got := batchInd.Batch(input)
if len(got) != len(want) {
t.Fatalf("batch len = %d, want %d", len(got), len(want))
}
for i := range want {
if math.IsNaN(want[i]) && math.IsNaN(got[i]) {
continue
}
if math.Abs(got[i]-want[i]) > 1e-9 {
t.Fatalf("batch[%d] = %v, streaming = %v", i, got[i], want[i])
}
}
}
func TestMultiOutput(t *testing.T) {
m, err := NewMacdIndicator(3, 6, 3)
if err != nil {
t.Fatalf("NewMacdIndicator: %v", err)
}
defer m.Close()
var ok bool
var out MacdOutput
for i := 0; i < 30; i++ {
out, ok = m.Update(100 + float64(i))
}
if !ok {
t.Fatal("macd never produced a value after warmup")
}
if math.IsNaN(out.Macd) {
t.Fatal("macd value is NaN after warmup")
}
}
func TestBars(t *testing.T) {
rb, err := NewRangeBars(2.0)
if err != nil {
t.Fatalf("NewRangeBars: %v", err)
}
defer rb.Close()
total := 0
for _, p := range []float64{100, 101, 103, 104, 99, 96, 102, 108, 95, 110} {
bars := rb.Update(p, p, p, p, 1, 0)
total += len(bars)
}
if total == 0 {
t.Fatal("range bars produced no bars over a 15-point move")
}
}
func TestProfile(t *testing.T) {
vp, err := NewVolumeProfile(10, 24)
if err != nil {
t.Fatalf("NewVolumeProfile: %v", err)
}
defer vp.Close()
var ok bool
var snap VolumeProfileOutputScalars
for i := 0; i < 50; i++ {
price := 100 + 5*math.Sin(float64(i)*0.3)
snap, ok = vp.Update(price, price+1, price-1, price, 1000, int64(i))
}
if !ok {
t.Fatal("volume profile never produced a snapshot")
}
if len(snap.Values) == 0 {
t.Fatal("volume profile returned an empty values buffer")
}
}
func TestArrayInput(t *testing.T) {
ob, err := NewOrderBookImbalanceFull()
if err != nil {
t.Fatalf("NewOrderBookImbalanceFull: %v", err)
}
defer ob.Close()
bidPrice := []float64{99.9, 99.8, 99.7}
bidSize := []float64{5, 3, 2}
askPrice := []float64{100.1, 100.2, 100.3}
askSize := []float64{1, 1, 1}
v := ob.Update(bidPrice, bidSize, askPrice, askSize)
if math.IsNaN(v) {
t.Fatal("order-book imbalance is NaN on a populated book")
}
}
func TestResetReturnsToWarmup(t *testing.T) {
s, _ := NewSma(3)
defer s.Close()
for _, v := range []float64{1, 2, 3} {
s.Update(v)
}
s.Reset()
if got := s.Update(10); !math.IsNaN(got) {
t.Fatalf("after reset first update = %v, want NaN (warmup)", got)
}
}
func TestInvalidParams(t *testing.T) {
if _, err := NewSma(0); err == nil {
t.Fatal("NewSma(0) should return ErrInvalidParams")
}
}
func TestCloseIsIdempotent(t *testing.T) {
s, _ := NewSma(3)
s.Close()
s.Close() // must not panic or double-free
}
+1 -1
View File
@@ -9,7 +9,7 @@
prebuilt native binary, 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++ and any
bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go, 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 Node.js binding (napi-rs);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wickra-darwin-arm64",
"version": "0.7.5",
"version": "0.7.8",
"description": "Native binding for wickra (macOS Apple Silicon). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.darwin-arm64.node",
"files": [
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wickra-darwin-x64",
"version": "0.7.5",
"version": "0.7.8",
"description": "Native binding for wickra (macOS Intel). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.darwin-x64.node",
"files": [
@@ -1,6 +1,6 @@
{
"name": "wickra-linux-arm64-gnu",
"version": "0.7.5",
"version": "0.7.8",
"description": "Native binding for wickra (linux arm64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.linux-arm64-gnu.node",
"files": [
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wickra-linux-x64-gnu",
"version": "0.7.5",
"version": "0.7.8",
"description": "Native binding for wickra (linux x64 GNU). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.linux-x64-gnu.node",
"files": [
@@ -1,6 +1,6 @@
{
"name": "wickra-win32-arm64-msvc",
"version": "0.7.5",
"version": "0.7.8",
"description": "Native binding for wickra (Windows arm64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.win32-arm64-msvc.node",
"files": [
@@ -1,6 +1,6 @@
{
"name": "wickra-win32-x64-msvc",
"version": "0.7.5",
"version": "0.7.8",
"description": "Native binding for wickra (Windows x64 MSVC). Installed automatically as an optional dependency of wickra on matching platforms.",
"main": "wickra.win32-x64-msvc.node",
"files": [
+20 -20
View File
@@ -1,12 +1,12 @@
{
"name": "wickra",
"version": "0.7.5",
"version": "0.7.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wickra",
"version": "0.7.5",
"version": "0.7.8",
"license": "MIT OR Apache-2.0",
"devDependencies": {
"@napi-rs/cli": "^2.18.0"
@@ -15,12 +15,12 @@
"node": ">= 18"
},
"optionalDependencies": {
"wickra-darwin-arm64": "0.7.5",
"wickra-darwin-x64": "0.7.5",
"wickra-linux-arm64-gnu": "0.7.5",
"wickra-linux-x64-gnu": "0.7.5",
"wickra-win32-arm64-msvc": "0.7.5",
"wickra-win32-x64-msvc": "0.7.5"
"wickra-darwin-arm64": "0.7.8",
"wickra-darwin-x64": "0.7.8",
"wickra-linux-arm64-gnu": "0.7.8",
"wickra-linux-x64-gnu": "0.7.8",
"wickra-win32-arm64-msvc": "0.7.8",
"wickra-win32-x64-msvc": "0.7.8"
}
},
"node_modules/@napi-rs/cli": {
@@ -41,8 +41,8 @@
}
},
"node_modules/wickra-darwin-arm64": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/wickra-darwin-arm64/-/wickra-darwin-arm64-0.7.5.tgz",
"version": "0.7.8",
"resolved": "https://registry.npmjs.org/wickra-darwin-arm64/-/wickra-darwin-arm64-0.7.8.tgz",
"integrity": "sha512-4eZiBR/yGUdr4nzhEUFy2i69XgNx64iI2ax/LPamsThgylC0KpHOZKK19QzJ2d9KbK4C8nMjME5FLuR+4GNEwQ==",
"cpu": [
"arm64"
@@ -57,8 +57,8 @@
}
},
"node_modules/wickra-darwin-x64": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/wickra-darwin-x64/-/wickra-darwin-x64-0.7.5.tgz",
"version": "0.7.8",
"resolved": "https://registry.npmjs.org/wickra-darwin-x64/-/wickra-darwin-x64-0.7.8.tgz",
"integrity": "sha512-6hf8zI3QPjTFp4zCpmgUwDvNtu6jHqNUHKD5e55POo0CgA52HkpyxSPtVm8TGTIZDI7kPjlbOdBM8CJ76mmXwA==",
"cpu": [
"x64"
@@ -73,8 +73,8 @@
}
},
"node_modules/wickra-linux-arm64-gnu": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/wickra-linux-arm64-gnu/-/wickra-linux-arm64-gnu-0.7.5.tgz",
"version": "0.7.8",
"resolved": "https://registry.npmjs.org/wickra-linux-arm64-gnu/-/wickra-linux-arm64-gnu-0.7.8.tgz",
"integrity": "sha512-kSe6y0xBMSiqdPLXNjwop5WZdHtvdBNKSEBCwZ4hFq33p4apW25/wrlzv9/oDuyD4kuPabJEhCCnFOplh58CUg==",
"cpu": [
"arm64"
@@ -89,8 +89,8 @@
}
},
"node_modules/wickra-linux-x64-gnu": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/wickra-linux-x64-gnu/-/wickra-linux-x64-gnu-0.7.5.tgz",
"version": "0.7.8",
"resolved": "https://registry.npmjs.org/wickra-linux-x64-gnu/-/wickra-linux-x64-gnu-0.7.8.tgz",
"integrity": "sha512-tWBWS4qz7hxM4xnpFb59bhf6TaLwXq0Z3jEa/2l7r8PiHA94g8r8S53NRMiT+4yiL5hSWe/nUiC/YXdRrhEZ4g==",
"cpu": [
"x64"
@@ -105,8 +105,8 @@
}
},
"node_modules/wickra-win32-arm64-msvc": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/wickra-win32-arm64-msvc/-/wickra-win32-arm64-msvc-0.7.5.tgz",
"version": "0.7.8",
"resolved": "https://registry.npmjs.org/wickra-win32-arm64-msvc/-/wickra-win32-arm64-msvc-0.7.8.tgz",
"integrity": "sha512-EXIckHxAtF75PUGDKRzXyqMe9ldP0JjSdu68WFN6iJfp+McYrGu6h40TEJlQ/oUEIoPqiZB/xhVyo/el5Lg7zw==",
"cpu": [
"arm64"
@@ -121,8 +121,8 @@
}
},
"node_modules/wickra-win32-x64-msvc": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/wickra-win32-x64-msvc/-/wickra-win32-x64-msvc-0.7.5.tgz",
"version": "0.7.8",
"resolved": "https://registry.npmjs.org/wickra-win32-x64-msvc/-/wickra-win32-x64-msvc-0.7.8.tgz",
"integrity": "sha512-Yfsqq1Xwp6hdxMyLze411vNdo7BDwI6+lPSe7A9XdqyPecNDbtKwYLpsal2r8EHbNzqM+R8XnuRtUaEQS5VlUQ==",
"cpu": [
"x64"
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "wickra",
"version": "0.7.5",
"version": "0.7.8",
"description": "Streaming-first technical indicators: incremental, fast, install-free. Node bindings powered by Rust.",
"author": "kingchenc <support@wickra.org>",
"main": "index.js",
@@ -47,12 +47,12 @@
"node": ">= 18"
},
"optionalDependencies": {
"wickra-linux-x64-gnu": "0.7.5",
"wickra-linux-arm64-gnu": "0.7.5",
"wickra-darwin-x64": "0.7.5",
"wickra-darwin-arm64": "0.7.5",
"wickra-win32-x64-msvc": "0.7.5",
"wickra-win32-arm64-msvc": "0.7.5"
"wickra-linux-x64-gnu": "0.7.8",
"wickra-linux-arm64-gnu": "0.7.8",
"wickra-darwin-x64": "0.7.8",
"wickra-darwin-arm64": "0.7.8",
"wickra-win32-x64-msvc": "0.7.8",
"wickra-win32-arm64-msvc": "0.7.8"
},
"scripts": {
"build": "napi build --platform --release",
+1 -1
View File
@@ -9,7 +9,7 @@
system dependencies, no C build tooling.**
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++ and any
bindings for Python, Node.js and WebAssembly, plus a C ABI for C/C++, C#, Go, 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 Python binding (PyO3); it
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "maturin"
[project]
name = "wickra"
version = "0.7.5"
version = "0.7.8"
description = "Streaming-first technical indicators: incremental, fast, install-free."
readme = "README.md"
license = "MIT OR Apache-2.0"
+8
View File
@@ -0,0 +1,8 @@
^src/wickra_abi\.dll$
^src/wickra_abi\.def$
^src/libwickra_abi\.dll\.a$
^src/.*\.o$
^src/wickra\.dll$
^src/wickra\.so$
^src/symbols\.rds$
^\.gitignore$
+20
View File
@@ -0,0 +1,20 @@
Package: wickra
Type: Package
Title: Streaming-First Technical Indicators
Version: 0.7.8
Authors@R: person("Wickra contributors", role = c("aut", "cre"), email = "support@wickra.org")
Description: R bindings for the Wickra technical-analysis library over its C ABI
hub. Exposes 514 indicators, each an O(1) streaming state machine shared with
the Rust core and the other language bindings, so that live and historical
evaluation use the exact same implementation.
License: MIT + file LICENSE | Apache License 2.0
URL: https://github.com/wickra-lib/wickra, https://docs.wickra.org
BugReports: https://github.com/wickra-lib/wickra/issues
Encoding: UTF-8
NeedsCompilation: yes
SystemRequirements: the Wickra C ABI library (libwickra); set WICKRA_INCLUDE_DIR
and WICKRA_LIB_DIR when installing from source.
Roxygen: list(markdown = TRUE)
Suggests: testthat (>= 3.0.0)
Config/testthat/edition: 3
Config/roxygen2/version: 8.0.0
+2
View File
@@ -0,0 +1,2 @@
YEAR: 2026
COPYRIGHT HOLDER: Wickra contributors
+522
View File
@@ -0,0 +1,522 @@
# Generated by roxygen2: do not edit by hand
S3method(batch,wickra_indicator)
S3method(reset,wickra_indicator)
S3method(update,wickra_indicator)
export(AbandonedBaby)
export(Abcd)
export(AbsoluteBreadthIndex)
export(AccelerationBands)
export(AcceleratorOscillator)
export(AdOscillator)
export(AdVolumeLine)
export(AdaptiveCci)
export(AdaptiveCycle)
export(AdaptiveLaguerreFilter)
export(AdaptiveRsi)
export(Adl)
export(AdvanceBlock)
export(AdvanceDecline)
export(AdvanceDeclineRatio)
export(Adx)
export(Adxr)
export(Alligator)
export(Alma)
export(Alpha)
export(AmihudIlliquidity)
export(AnchoredRsi)
export(AnchoredVwap)
export(AndrewsPitchfork)
export(Apo)
export(Aroon)
export(AroonOscillator)
export(Atr)
export(AtrBands)
export(AtrRatchet)
export(AtrTrailingStop)
export(AutoFib)
export(Autocorrelation)
export(AutocorrelationPeriodogram)
export(AverageDailyRange)
export(AverageDrawdown)
export(AvgPrice)
export(AwesomeOscillator)
export(AwesomeOscillatorHistogram)
export(BalanceOfPower)
export(BandpassFilter)
export(Bat)
export(BeltHold)
export(Beta)
export(BetaNeutralSpread)
export(BetterVolume)
export(BipowerVariation)
export(BodySizePct)
export(BollingerBands)
export(BollingerBandwidth)
export(BomarBands)
export(BreadthThrust)
export(Breakaway)
export(BullishPercentIndex)
export(BurkeRatio)
export(Butterfly)
export(CalendarSpread)
export(CalmarRatio)
export(Camarilla)
export(CandleVolume)
export(Cci)
export(CenterOfGravity)
export(CentralPivotRange)
export(Cfo)
export(ChaikinMoneyFlow)
export(ChaikinOscillator)
export(ChaikinVolatility)
export(ChandeKrollStop)
export(ChandelierExit)
export(ChoppinessIndex)
export(ClassicPivots)
export(CloseVsOpen)
export(ClosingMarubozu)
export(Cmo)
export(CoefficientOfVariation)
export(Cointegration)
export(CommonSenseRatio)
export(CompositeProfile)
export(ConcealingBabySwallow)
export(ConditionalValueAtRisk)
export(ConnorsRsi)
export(Coppock)
export(CorrelationTrendIndicator)
export(Counterattack)
export(Crab)
export(CumulativeVolumeDelta)
export(CumulativeVolumeIndex)
export(CupAndHandle)
export(CyberneticCycle)
export(Cypher)
export(DayOfWeekProfile)
export(Decycler)
export(DecyclerOscillator)
export(Dema)
export(DemandIndex)
export(DemarkPivots)
export(DepthSlope)
export(DerivativeOscillator)
export(DetrendedStdDev)
export(DisparityIndex)
export(DistanceSsd)
export(Doji)
export(DojiStar)
export(DollarBars)
export(Donchian)
export(DonchianStop)
export(DoubleBollinger)
export(DoubleTopBottom)
export(DownsideGapThreeMethods)
export(Dpo)
export(DragonflyDoji)
export(DrawdownDuration)
export(DumplingTop)
export(Dx)
export(DynamicMomentumIndex)
export(EaseOfMovement)
export(EffectiveSpread)
export(EhlersStochastic)
export(Ehma)
export(ElderImpulse)
export(ElderRay)
export(ElderSafeZone)
export(Ema)
export(EmpiricalModeDecomposition)
export(Engulfing)
export(Equivolume)
export(EstimatedLeverageRatio)
export(EvenBetterSinewave)
export(EveningDojiStar)
export(Evwma)
export(EwmaVolatility)
export(Expectancy)
export(FallingThreeMethods)
export(Fama)
export(FibArcs)
export(FibChannel)
export(FibConfluence)
export(FibExtension)
export(FibFan)
export(FibProjection)
export(FibRetracement)
export(FibTimeZones)
export(FibonacciPivots)
export(FisherRsi)
export(FisherTransform)
export(FlagPennant)
export(Footprint)
export(ForceIndex)
export(FractalChaosBands)
export(Frama)
export(FryPanBottom)
export(FundingBasis)
export(FundingImpliedApr)
export(FundingRate)
export(FundingRateMean)
export(FundingRateZScore)
export(GainLossRatio)
export(GainToPainRatio)
export(GapSideBySideWhite)
export(Garch11)
export(GarmanKlassVolatility)
export(Gartley)
export(GatorOscillator)
export(GeneralizedDema)
export(GeometricMa)
export(GoldenPocket)
export(GrangerCausality)
export(GravestoneDoji)
export(Hammer)
export(HangingMan)
export(Harami)
export(HaramiCross)
export(HasbrouckInformationShare)
export(HeadAndShoulders)
export(HeikinAshi)
export(HeikinAshiOscillator)
export(HiLoActivator)
export(HighLowIndex)
export(HighLowRange)
export(HighLowVolumeNodes)
export(HighWave)
export(HighpassFilter)
export(Hikkake)
export(HikkakeModified)
export(HilbertDominantCycle)
export(HistoricalVolatility)
export(Hma)
export(HoltWinters)
export(HomingPigeon)
export(HtDcPhase)
export(HtPhasor)
export(HtTrendMode)
export(HurstChannel)
export(HurstExponent)
export(Ichimoku)
export(IdenticalThreeCrows)
export(ImbalanceBars)
export(InNeck)
export(Inertia)
export(InformationRatio)
export(InitialBalance)
export(InstantaneousTrendline)
export(IntradayIntensity)
export(IntradayMomentumIndex)
export(IntradayVolatilityProfile)
export(InverseFisherTransform)
export(InvertedHammer)
export(JarqueBera)
export(Jma)
export(JumpIndicator)
export(KRatio)
export(KagiBars)
export(KalmanHedgeRatio)
export(Kama)
export(KaseDevStop)
export(KasePermissionStochastic)
export(KellyCriterion)
export(Keltner)
export(KendallTau)
export(Kicking)
export(KickingByLength)
export(Kst)
export(Kurtosis)
export(Kvo)
export(KylesLambda)
export(LadderBottom)
export(LaguerreRsi)
export(LeadLagCrossCorrelation)
export(LinRegAngle)
export(LinRegChannel)
export(LinRegIntercept)
export(LinRegSlope)
export(LinearRegression)
export(LiquidationFeatures)
export(LogReturn)
export(LongLeggedDoji)
export(LongLine)
export(LongShortRatio)
export(M2Measure)
export(MaEnvelope)
export(MacdExt)
export(MacdFix)
export(MacdHistogram)
export(MacdIndicator)
export(Mama)
export(MarketFacilitationIndex)
export(MartinRatio)
export(Marubozu)
export(MassIndex)
export(MatHold)
export(MatchingLow)
export(MaxDrawdown)
export(McClellanOscillator)
export(McClellanSummationIndex)
export(McGinleyDynamic)
export(MedianAbsoluteDeviation)
export(MedianChannel)
export(MedianMa)
export(MedianPrice)
export(Mfi)
export(Microprice)
export(MidPoint)
export(MidPrice)
export(MinusDi)
export(MinusDm)
export(ModifiedMaStop)
export(Mom)
export(MorningDojiStar)
export(MorningEveningStar)
export(MurreyMathLines)
export(NakedPoc)
export(Natr)
export(NewHighsNewLows)
export(NewPriceLines)
export(Nrtr)
export(Nvi)
export(OIPriceDivergence)
export(OIWeighted)
export(Obv)
export(OiToVolumeRatio)
export(OmegaRatio)
export(OnNeck)
export(OpenInterestDelta)
export(OpenInterestMomentum)
export(OpeningMarubozu)
export(OpeningRange)
export(OrderBookImbalanceFull)
export(OrderBookImbalanceTop1)
export(OrderBookImbalanceTopN)
export(OrderFlowImbalance)
export(OuHalfLife)
export(OvernightGap)
export(OvernightIntradayReturn)
export(PainIndex)
export(PairSpreadZScore)
export(PairwiseBeta)
export(ParkinsonVolatility)
export(PearsonCorrelation)
export(PercentAboveMa)
export(PercentB)
export(PercentageTrailingStop)
export(PerpetualPremiumIndex)
export(Pgo)
export(PiercingDarkCloud)
export(Pin)
export(PivotReversal)
export(PlusDi)
export(PlusDm)
export(Pmo)
export(PointAndFigureBars)
export(PolarizedFractalEfficiency)
export(Ppo)
export(PpoHistogram)
export(ProfileShape)
export(ProfitFactor)
export(ProjectionBands)
export(ProjectionOscillator)
export(Psar)
export(Pvi)
export(Qqe)
export(Qstick)
export(QuartileBands)
export(QuotedSpread)
export(RSquared)
export(RangeBars)
export(RealizedSpread)
export(RealizedVolatility)
export(RecoveryFactor)
export(RectangleRange)
export(Reflex)
export(RegimeLabel)
export(RelativeStrengthAB)
export(RenkoBars)
export(RenkoTrailingStop)
export(RickshawMan)
export(RisingThreeMethods)
export(Rmi)
export(Roc)
export(Rocp)
export(Rocr)
export(Rocr100)
export(RogersSatchellVolatility)
export(RollMeasure)
export(RollingCorrelation)
export(RollingCovariance)
export(RollingIqr)
export(RollingMinMaxScaler)
export(RollingPercentileRank)
export(RollingQuantile)
export(RollingVwap)
export(RoofingFilter)
export(Rsi)
export(Rsx)
export(RunBars)
export(Rvi)
export(RviVolatility)
export(Rwi)
export(SampleEntropy)
export(SarExt)
export(SeasonalZScore)
export(SeparatingLines)
export(SessionHighLow)
export(SessionRange)
export(SessionVwap)
export(ShannonEntropy)
export(Shark)
export(SharpeRatio)
export(ShootingStar)
export(ShortLine)
export(SignedVolume)
export(SineWave)
export(SineWeightedMa)
export(SinglePrints)
export(Skewness)
export(Sma)
export(Smi)
export(Smma)
export(SmoothedHeikinAshi)
export(SortinoRatio)
export(SpearmanCorrelation)
export(SpinningTop)
export(SpreadAr1Coefficient)
export(SpreadBollingerBands)
export(SpreadHurst)
export(StalledPattern)
export(StandardError)
export(StandardErrorBands)
export(StarcBands)
export(Stc)
export(StdDev)
export(StepTrailingStop)
export(SterlingRatio)
export(StickSandwich)
export(StochRsi)
export(Stochastic)
export(StochasticCci)
export(SuperSmoother)
export(SuperTrend)
export(T3)
export(TailRatio)
export(TakerBuySellRatio)
export(Takuri)
export(TasukiGap)
export(TdCamouflage)
export(TdClop)
export(TdClopwin)
export(TdCombo)
export(TdCountdown)
export(TdDWave)
export(TdDeMarker)
export(TdDifferential)
export(TdLines)
export(TdMovingAverage)
export(TdOpen)
export(TdPressure)
export(TdPropulsion)
export(TdRangeProjection)
export(TdRei)
export(TdRiskLevel)
export(TdSequential)
export(TdSetup)
export(TdTrap)
export(Tema)
export(TermStructureBasis)
export(ThreeDrives)
export(ThreeInside)
export(ThreeLineBreak)
export(ThreeLineBreakBars)
export(ThreeLineStrike)
export(ThreeOutside)
export(ThreeSoldiersOrCrows)
export(ThreeStarsInSouth)
export(Thrusting)
export(TickBars)
export(TickIndex)
export(Tii)
export(TimeBasedStop)
export(TimeOfDayReturnProfile)
export(TowerTopBottom)
export(TpoProfile)
export(TradeImbalance)
export(TradeSignAutocorrelation)
export(TradeVolumeIndex)
export(TrendLabel)
export(TrendStrengthIndex)
export(Trendflex)
export(TreynorRatio)
export(Triangle)
export(Trima)
export(Trin)
export(TripleTopBottom)
export(Tristar)
export(Trix)
export(TrueRange)
export(Tsf)
export(TsfOscillator)
export(Tsi)
export(Tsv)
export(TtmSqueeze)
export(TtmTrend)
export(TurnOfMonth)
export(Tweezer)
export(TwiggsMoneyFlow)
export(TwoCrows)
export(TypicalPrice)
export(UlcerIndex)
export(UltimateOscillator)
export(UniqueThreeRiver)
export(UniversalOscillator)
export(UpDownVolumeRatio)
export(UpsideGapThreeMethods)
export(UpsideGapTwoCrows)
export(UpsidePotentialRatio)
export(ValueArea)
export(ValueAtRisk)
export(Variance)
export(VarianceRatio)
export(VerticalHorizontalFilter)
export(Vidya)
export(VolatilityCone)
export(VolatilityOfVolatility)
export(VolatilityRatio)
export(VoltyStop)
export(VolumeBars)
export(VolumeByTimeProfile)
export(VolumeOscillator)
export(VolumePriceTrend)
export(VolumeProfile)
export(VolumeRsi)
export(VolumeWeightedMacd)
export(VolumeWeightedSr)
export(Vortex)
export(Vpin)
export(Vwap)
export(VwapStdDevBands)
export(Vwma)
export(Vzo)
export(Wad)
export(WavePm)
export(WaveTrend)
export(Wedge)
export(WeightedClose)
export(WickRatio)
export(WilliamsFractals)
export(WilliamsR)
export(WinRate)
export(Wma)
export(WoodiePivots)
export(YangZhangVolatility)
export(YoyoExit)
export(ZScore)
export(ZeroLagMacd)
export(ZigZag)
export(Zlema)
export(batch)
export(reset)
importFrom(stats,update)
File diff suppressed because it is too large Load Diff
+78
View File
@@ -0,0 +1,78 @@
#' wickra: streaming-first technical indicators
#'
#' R bindings for the Wickra technical-analysis library over its C ABI hub. Each
#' indicator is a constructor (for example [Sma()], [Rsi()], [MacdIndicator()])
#' returning a `wickra_indicator` object; feed it one observation at a time with
#' [update()], run a whole series in one call with [batch()], and clear its
#' state with [reset()]. The native handle is freed automatically when the object
#' is garbage-collected.
#'
#' @keywords internal
#' @importFrom stats update
"_PACKAGE"
#' Update an indicator with one observation
#'
#' @param object A `wickra_indicator` created by an indicator constructor.
#' @param ... The observation: a single value for scalar indicators, the OHLCV
#' fields plus a timestamp for candle indicators, or two values for pairwise
#' indicators.
#' @return The indicator value: a numeric scalar; a named numeric vector for
#' multi-output indicators (`NA` during warmup); a matrix of completed bars for
#' bar builders; or a list / numeric vector for profile indicators
#' (`NULL` during warmup).
#' @examples
#' sma <- Sma(3)
#' for (x in c(1, 2, 3, 4, 5)) v <- update(sma, x)
#' v # 4
#' @export
update.wickra_indicator <- function(object, ...) {
args <- list(object$ptr, ...)
if (!is.na(object$values_cap)) {
args <- c(args, object$values_cap)
}
do.call(".Call", c(list(paste0("wk_", object$prefix, "_update")), args,
list(PACKAGE = "wickra")))
}
#' Run an indicator over a whole series in one call
#'
#' Available for scalar indicators. The result is identical to feeding the same
#' inputs through [update()] one at a time, with `NA` at warmup positions.
#'
#' @param object A `wickra_indicator`.
#' @param ... The input vector(s).
#' @return A numeric vector the same length as the input.
#' @examples
#' batch(Sma(3), c(1, 2, 3, 4, 5)) # NA NA 2 3 4
#' @export
batch <- function(object, ...) {
UseMethod("batch")
}
#' @rdname batch
#' @export
batch.wickra_indicator <- function(object, ...) {
do.call(".Call", c(list(paste0("wk_", object$prefix, "_batch"), object$ptr),
list(...), list(PACKAGE = "wickra")))
}
#' Reset an indicator to its warmup state
#'
#' @param object A `wickra_indicator`.
#' @return The indicator, invisibly.
#' @examples
#' sma <- Sma(3)
#' update(sma, 1)
#' reset(sma)
#' @export
reset <- function(object) {
UseMethod("reset")
}
#' @rdname reset
#' @export
reset.wickra_indicator <- function(object) {
.Call(paste0("wk_", object$prefix, "_reset"), object$ptr, PACKAGE = "wickra")
invisible(object)
}
+18
View File
@@ -0,0 +1,18 @@
.onLoad <- function(libname, pkgname) {
# On Windows the package's wickra.dll depends on the bundled C ABI
# wickra_abi.dll; the loader searches PATH for it, so prepend the package's own
# libs directory. On Linux/macOS the rpath baked at build time locates the
# shared library, so no PATH change is needed.
if (.Platform$OS.type == "windows") {
libs <- system.file(paste0("libs", .Platform$r_arch),
package = pkgname, lib.loc = libname)
if (nzchar(libs)) {
Sys.setenv(PATH = paste(libs, Sys.getenv("PATH"), sep = .Platform$path.sep))
}
}
library.dynam("wickra", pkgname, libname)
}
.onUnload <- function(libpath) {
library.dynam.unload("wickra", libpath)
}
+85
View File
@@ -0,0 +1,85 @@
# Wickra — R
[![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)
[![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 R, over the Wickra C ABI hub via `.Call`.**
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, R
and any other C-capable language. Every indicator is an O(1) streaming state
machine, so live trading and historical backtests share the exact same
implementation. This package is the R binding; it reaches the C ABI hub through
R's native `.Call` interface and exposes all 514 indicators as constructors that
return a lightweight `wickra_indicator` object.
## Install
The package compiles a thin C glue layer (`.Call`) against the prebuilt Wickra
C ABI library, so a C toolchain (Rtools on Windows) is required, plus the C ABI
header and library. Build the library from the workspace, then install the
package pointing at it:
```bash
cargo build -p wickra-c --release
WICKRA_INCLUDE_DIR="$PWD/bindings/c/include" \
WICKRA_LIB_DIR="$PWD/target/release" \
R CMD INSTALL bindings/r
```
On Windows the C ABI DLL is bundled into the package and put on the load path
automatically; on Linux and macOS the library path is baked in via rpath.
## Quick start
```r
library(wickra)
# Batch: run an indicator over a whole series (NaN at warmup positions).
prices <- 100 + (0:999) * 0.1
sma <- Sma(20)
values <- batch(sma, prices)
# Streaming: the same indicator, fed one observation at a time in O(1).
rsi <- Rsi(14)
for (price in prices) {
v <- update(rsi, price) # NaN during warmup
if (!is.na(v) && v > 70) message("overbought")
}
# Multi-output indicators return a named vector (NA while warming up).
macd <- MacdIndicator(12, 26, 9)
update(macd, 42) # c(macd = NA, signal = NA, histogram = NA)
```
`batch(ind, prices)` and feeding the same prices through `update()` produce
identical values — the equivalence is enforced by the test suite. Candle-input
indicators take the OHLCV fields plus a timestamp, e.g.
`update(atr, open, high, low, close, volume, timestamp)`. The native handle is
freed automatically when the object is garbage-collected.
## 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/r/`](https://github.com/wickra-lib/wickra/tree/main/examples/r)
Wickra ships native bindings for Python, Node.js, WebAssembly and Rust, plus a
C ABI hub that any C-capable language (C, C++, C#, Go, 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.
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
# Windows build: the package compiles to wickra.dll, which would collide with the
# C ABI's own wickra.dll (the loader would resolve the import to the package
# itself). Stage a renamed copy, wickra_abi.dll, into src/ and build a mingw
# import library that references it by that name (objdump + dlltool, both shipped
# with Rtools — no gendef/pexports needed). install.libs.R then bundles the DLL.
set -e
: "${WICKRA_LIB_DIR:?set WICKRA_LIB_DIR to the directory containing wickra.dll}"
cp "${WICKRA_LIB_DIR}/wickra.dll" src/wickra_abi.dll
{
echo 'LIBRARY wickra_abi.dll'
echo 'EXPORTS'
objdump -p src/wickra_abi.dll | awk '/\[ *[0-9]+\]/ {print $NF}' | grep '^wickra_'
} > src/wickra_abi.def
dlltool --input-def src/wickra_abi.def --dllname wickra_abi.dll \
--output-lib src/libwickra_abi.dll.a
exit 0
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AbandonedBaby}
\alias{AbandonedBaby}
\title{AbandonedBaby indicator}
\usage{
AbandonedBaby()
}
\description{
AbandonedBaby indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Abcd}
\alias{Abcd}
\title{Abcd indicator}
\usage{
Abcd()
}
\description{
Abcd indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AbsoluteBreadthIndex}
\alias{AbsoluteBreadthIndex}
\title{AbsoluteBreadthIndex indicator}
\usage{
AbsoluteBreadthIndex()
}
\description{
AbsoluteBreadthIndex indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AccelerationBands}
\alias{AccelerationBands}
\title{AccelerationBands indicator}
\usage{
AccelerationBands(period, factor)
}
\description{
AccelerationBands indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AcceleratorOscillator}
\alias{AcceleratorOscillator}
\title{AcceleratorOscillator indicator}
\usage{
AcceleratorOscillator(ao_fast, ao_slow, signal_period)
}
\description{
AcceleratorOscillator indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdOscillator}
\alias{AdOscillator}
\title{AdOscillator indicator}
\usage{
AdOscillator()
}
\description{
AdOscillator indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdVolumeLine}
\alias{AdVolumeLine}
\title{AdVolumeLine indicator}
\usage{
AdVolumeLine()
}
\description{
AdVolumeLine indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdaptiveCci}
\alias{AdaptiveCci}
\title{AdaptiveCci indicator}
\usage{
AdaptiveCci(period)
}
\description{
AdaptiveCci indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdaptiveCycle}
\alias{AdaptiveCycle}
\title{AdaptiveCycle indicator}
\usage{
AdaptiveCycle()
}
\description{
AdaptiveCycle indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdaptiveLaguerreFilter}
\alias{AdaptiveLaguerreFilter}
\title{AdaptiveLaguerreFilter indicator}
\usage{
AdaptiveLaguerreFilter(period)
}
\description{
AdaptiveLaguerreFilter indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdaptiveRsi}
\alias{AdaptiveRsi}
\title{AdaptiveRsi indicator}
\usage{
AdaptiveRsi(period)
}
\description{
AdaptiveRsi indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Adl}
\alias{Adl}
\title{Adl indicator}
\usage{
Adl()
}
\description{
Adl indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdvanceBlock}
\alias{AdvanceBlock}
\title{AdvanceBlock indicator}
\usage{
AdvanceBlock()
}
\description{
AdvanceBlock indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdvanceDecline}
\alias{AdvanceDecline}
\title{AdvanceDecline indicator}
\usage{
AdvanceDecline()
}
\description{
AdvanceDecline indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AdvanceDeclineRatio}
\alias{AdvanceDeclineRatio}
\title{AdvanceDeclineRatio indicator}
\usage{
AdvanceDeclineRatio()
}
\description{
AdvanceDeclineRatio indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Adx}
\alias{Adx}
\title{Adx indicator}
\usage{
Adx(period)
}
\description{
Adx indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Adxr}
\alias{Adxr}
\title{Adxr indicator}
\usage{
Adxr(period)
}
\description{
Adxr indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Alligator}
\alias{Alligator}
\title{Alligator indicator}
\usage{
Alligator(jaw_period, teeth_period, lips_period)
}
\description{
Alligator indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Alma}
\alias{Alma}
\title{Alma indicator}
\usage{
Alma(period, offset, sigma)
}
\description{
Alma indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Alpha}
\alias{Alpha}
\title{Alpha indicator}
\usage{
Alpha(period, risk_free)
}
\description{
Alpha indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AmihudIlliquidity}
\alias{AmihudIlliquidity}
\title{AmihudIlliquidity indicator}
\usage{
AmihudIlliquidity(period)
}
\description{
AmihudIlliquidity indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AnchoredRsi}
\alias{AnchoredRsi}
\title{AnchoredRsi indicator}
\usage{
AnchoredRsi()
}
\description{
AnchoredRsi indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AnchoredVwap}
\alias{AnchoredVwap}
\title{AnchoredVwap indicator}
\usage{
AnchoredVwap()
}
\description{
AnchoredVwap indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AndrewsPitchfork}
\alias{AndrewsPitchfork}
\title{AndrewsPitchfork indicator}
\usage{
AndrewsPitchfork(strength)
}
\description{
AndrewsPitchfork indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Apo}
\alias{Apo}
\title{Apo indicator}
\usage{
Apo(fast, slow)
}
\description{
Apo indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Aroon}
\alias{Aroon}
\title{Aroon indicator}
\usage{
Aroon(period)
}
\description{
Aroon indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AroonOscillator}
\alias{AroonOscillator}
\title{AroonOscillator indicator}
\usage{
AroonOscillator(period)
}
\description{
AroonOscillator indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Atr}
\alias{Atr}
\title{Atr indicator}
\usage{
Atr(period)
}
\description{
Atr indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AtrBands}
\alias{AtrBands}
\title{AtrBands indicator}
\usage{
AtrBands(period, multiplier)
}
\description{
AtrBands indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AtrRatchet}
\alias{AtrRatchet}
\title{AtrRatchet indicator}
\usage{
AtrRatchet(atr_period, start_mult, increment)
}
\description{
AtrRatchet indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AtrTrailingStop}
\alias{AtrTrailingStop}
\title{AtrTrailingStop indicator}
\usage{
AtrTrailingStop(atr_period, multiplier)
}
\description{
AtrTrailingStop indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AutoFib}
\alias{AutoFib}
\title{AutoFib indicator}
\usage{
AutoFib()
}
\description{
AutoFib indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Autocorrelation}
\alias{Autocorrelation}
\title{Autocorrelation indicator}
\usage{
Autocorrelation(period, lag)
}
\description{
Autocorrelation indicator
}
\keyword{internal}
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AutocorrelationPeriodogram}
\alias{AutocorrelationPeriodogram}
\title{AutocorrelationPeriodogram indicator}
\usage{
AutocorrelationPeriodogram(min_period, max_period)
}
\description{
AutocorrelationPeriodogram indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AverageDailyRange}
\alias{AverageDailyRange}
\title{AverageDailyRange indicator}
\usage{
AverageDailyRange(period, utc_offset_minutes)
}
\description{
AverageDailyRange indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AverageDrawdown}
\alias{AverageDrawdown}
\title{AverageDrawdown indicator}
\usage{
AverageDrawdown(period)
}
\description{
AverageDrawdown indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AvgPrice}
\alias{AvgPrice}
\title{AvgPrice indicator}
\usage{
AvgPrice()
}
\description{
AvgPrice indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AwesomeOscillator}
\alias{AwesomeOscillator}
\title{AwesomeOscillator indicator}
\usage{
AwesomeOscillator(fast, slow)
}
\description{
AwesomeOscillator indicator
}
\keyword{internal}
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{AwesomeOscillatorHistogram}
\alias{AwesomeOscillatorHistogram}
\title{AwesomeOscillatorHistogram indicator}
\usage{
AwesomeOscillatorHistogram(fast, slow, sma_period)
}
\description{
AwesomeOscillatorHistogram indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{BalanceOfPower}
\alias{BalanceOfPower}
\title{BalanceOfPower indicator}
\usage{
BalanceOfPower()
}
\description{
BalanceOfPower indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{BandpassFilter}
\alias{BandpassFilter}
\title{BandpassFilter indicator}
\usage{
BandpassFilter(period, bandwidth)
}
\description{
BandpassFilter indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{Bat}
\alias{Bat}
\title{Bat indicator}
\usage{
Bat()
}
\description{
Bat indicator
}
\keyword{internal}
+12
View File
@@ -0,0 +1,12 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/indicators.R
\name{BeltHold}
\alias{BeltHold}
\title{BeltHold indicator}
\usage{
BeltHold()
}
\description{
BeltHold indicator
}
\keyword{internal}

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