diff --git a/.gitattributes b/.gitattributes index 1c53277a..b82e6a46 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,3 +10,9 @@ bindings/c/include/wickra.h text eol=lf # 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 + diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d0df5ebf..ad5dc8a9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -30,7 +30,7 @@ assignees: "" ## Environment - Wickra version: -- Language / binding: +- Language / binding: - OS and architecture: - Rust / Python / Node / .NET version (If relevant): diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 8b48ce2d..fe6b4dcd 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -27,6 +27,7 @@ assignees: "" - [ ] 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 ## Additional context diff --git a/.github/ISSUE_TEMPLATE/performance_regression.md b/.github/ISSUE_TEMPLATE/performance_regression.md index eb971488..136d1dfb 100644 --- a/.github/ISSUE_TEMPLATE/performance_regression.md +++ b/.github/ISSUE_TEMPLATE/performance_regression.md @@ -13,7 +13,7 @@ assignees: [] ## Affected code path - Indicator / API: `e.g. EMA.update` -- Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET)` +- Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go` - Hot loop or one-shot call? ## Versions compared diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 2942b179..77b07a7a 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -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 / C# (.NET)` +- Binding: `Rust / Python / Node / Wasm / C ABI / C# (.NET) / Go` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f49a3d2a..addcfff2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -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 + C# binding are regenerated +- [ ] Public API changes are mirrored in the Python / Node / WASM bindings, and the C ABI + C# + Go 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 diff --git a/.github/PULL_REQUEST_TEMPLATE/detailed.md b/.github/PULL_REQUEST_TEMPLATE/detailed.md index cdebdebb..018eaa94 100644 --- a/.github/PULL_REQUEST_TEMPLATE/detailed.md +++ b/.github/PULL_REQUEST_TEMPLATE/detailed.md @@ -25,6 +25,7 @@ Please fill in the sections below. Delete any that don't apply. - [ ] WebAssembly binding (`bindings/wasm`) - [ ] C ABI (`bindings/c`) - [ ] C# / .NET binding (`bindings/csharp`) +- [ ] Go binding (`bindings/go`) - [ ] Examples / docs ## Linked issues diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d66588b..f2a405d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -727,6 +727,105 @@ jobs: 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 + # 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 diff --git a/.github/workflows/sync-about.yml b/.github/workflows/sync-about.yml index 09632959..4650f547 100644 --- a/.github/workflows/sync-about.yml +++ b/.github/workflows/sync-about.yml @@ -149,7 +149,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, C ABI, and .NET 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, and Go 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). diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 424f8fb9..3046d88d 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -46,7 +46,8 @@ 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 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) is generated from `wickra.h`, with Go / Java / R planned the same way. +on NuGet) and the **Go** binding (`bindings/go`, cgo) are generated from +`wickra.h`, with Java / R planned the same way. | Crate | Path | What it owns | Public deps | |---|---|---|---| diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d09315b..bf22759d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ 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] +### Added +- **Go binding (`bindings/go`)** — a cgo binding over the C ABI hub exposing all + 514 indicators as idiomatic types with `New` 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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9de81cc..cf22cff4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,6 +23,7 @@ licensed as above, without any additional terms or conditions. | `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`. | | `examples/` | Runnable examples. | | `docs/` | Pointer to the documentation site (docs.wickra.org); the docs live in the `wickra-lib/wickra-docs` repo. | @@ -108,6 +109,8 @@ installed. Dependabot also keeps the `.github/requirements` pins current. (`bindings/c`) is generated from the core, so regenerate it from the core and 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). - **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 diff --git a/README.md b/README.md index d374d332..e2ee9295 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Wickra is a multi-language technical-analysis library with a Rust core and native bindings for Python, Node.js and WebAssembly, plus a C ABI that C, C++, -C# / .NET and any other C-capable language links against. Every indicator is a +C# / .NET, Go 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. @@ -50,7 +50,8 @@ Full documentation lives at **[docs.wickra.org](https://docs.wickra.org)**: [Node](https://docs.wickra.org/Quickstart-Node), [WASM](https://docs.wickra.org/Quickstart-WASM), [C](https://docs.wickra.org/Quickstart-C), - [C#](https://docs.wickra.org/Quickstart-CSharp). + [C#](https://docs.wickra.org/Quickstart-CSharp), + [Go](https://docs.wickra.org/Quickstart-Go). - **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). @@ -76,7 +77,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++, C# / .NET and any other C-capable language — + WebAssembly · Rust** plus a **C ABI** for C / C++, C# / .NET, Go 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, @@ -101,7 +102,7 @@ Every other library forces one of those compromises. Wickra doesn't: | Library | Install | Streaming | Languages | Indicators | Active | |------------------|-------------|-------------|-----------------------------|-----------:|--------| | **★ Wickra**| **clean** | **yes, O(1)** | **Rust · Python · Node · WASM** | **514** | **yes** | -| | | | **C · C#** | | | +| | | | **C · C# · Go** | | | | kand | clean | yes | Python · WASM · Rust | ~60 | yes | | ta-rs | clean | yes | Rust only | ~30 | stale | | yata | clean | partial | Rust only | ~35 | yes | @@ -173,8 +174,8 @@ 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; every binding -inherits it automatically (the C ABI — and the C# binding generated from it — -regenerate from the core). +inherits it automatically (the C ABI — and the C# and Go bindings generated from +it — regenerate from the core). ## Languages @@ -186,6 +187,7 @@ regenerate from the core). | 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` | Each binding ships several runnable examples (streaming, backtest, live feed); [`examples/README.md`](examples/README.md) is the full cross-language index. @@ -256,7 +258,8 @@ wickra/ │ ├── node/ napi-rs (publishes on npm) │ ├── wasm/ wasm-bindgen (browsers, bundlers, Node) │ ├── c/ C ABI (cdylib + staticlib) + generated include/wickra.h -│ └── csharp/ .NET binding over the C ABI (publishes on NuGet) +│ ├── csharp/ .NET binding over the C ABI (publishes on NuGet) +│ └── go/ Go binding over the C ABI via cgo (module tag) ├── examples/ examples/README.md indexes every language │ ├── data/ real BTCUSDT OHLCV datasets, one per timeframe │ ├── rust/ Rust workspace member (`wickra-examples`) @@ -264,7 +267,8 @@ wickra/ │ ├── node/ streaming, backtest, live trading (load `wickra`) │ ├── wasm/ browser demo for `wickra-wasm` │ ├── c/ C smoke + streaming, C++ RAII wrapper -│ └── csharp/ streaming, backtest, strategies (load `Wickra`) +│ ├── csharp/ streaming, backtest, strategies (load `Wickra`) +│ └── go/ streaming, backtest, strategies (cgo binding) └── .github/workflows/ CI and release pipelines ``` @@ -300,6 +304,10 @@ cmake --build examples/c/build && ctest --test-dir examples/c/build --output-on- # 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 ./... ``` ## Testing @@ -319,6 +327,8 @@ 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. ## Contributing diff --git a/ROADMAP.md b/ROADMAP.md index ed2ae445..df89ff78 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -22,7 +22,7 @@ minor releases; breaking changes are called out in the changelog. - **Performance.** Keep per-tick updates O(1) and maintain the benchmark suite; investigate further allocation and cache improvements. - **Bindings parity.** Keep the Python, Node.js and WebAssembly bindings — plus - the C ABI and the C# / .NET binding generated from it — in lockstep with the + the C ABI and the C# / .NET and Go 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 , plus quickstarts and cookbook material. diff --git a/SUPPORT.md b/SUPPORT.md index 3ad9269e..38daa7da 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -7,7 +7,7 @@ Thanks for using Wickra! Here is where to get help, depending on what you need. Most questions are answered in the documentation: - **Docs site:** — quickstarts for Rust, Python, - Node.js, WebAssembly, C and C#, a per-indicator reference, warmup periods, the + Node.js, WebAssembly, C, C# and Go, a per-indicator reference, warmup periods, the data layer, and an FAQ. - **README:** — installation and a quick overview. diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md index 58142539..1ecbc14f 100644 --- a/THREAT_MODEL.md +++ b/THREAT_MODEL.md @@ -4,7 +4,7 @@ This document describes Wickra's attack surface and the threats considered, together with their mitigations. It complements the security assurance case in [`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 -and the .NET binding built on it), +and the .NET and Go bindings built on it), not a network service or trading system; the attack surface is correspondingly small. diff --git a/bindings/c/README.md b/bindings/c/README.md index 83b75b4e..372e0323 100644 --- a/bindings/c/README.md +++ b/bindings/c/README.md @@ -9,7 +9,7 @@ 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# and any +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 **C ABI hub**: it compiles the diff --git a/bindings/csharp/README.md b/bindings/csharp/README.md index b9b4d37e..bf30f574 100644 --- a/bindings/csharp/README.md +++ b/bindings/csharp/README.md @@ -9,7 +9,7 @@ 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# and any +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 .NET binding; it consumes the diff --git a/bindings/go/README.md b/bindings/go/README.md new file mode 100644 index 00000000..d5f4e343 --- /dev/null +++ b/bindings/go/README.md @@ -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:** +- **Docs** (quickstarts, cookbook, TA-Lib migration): +- **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. diff --git a/bindings/go/go.mod b/bindings/go/go.mod new file mode 100644 index 00000000..e1a0d6ef --- /dev/null +++ b/bindings/go/go.mod @@ -0,0 +1,3 @@ +module github.com/wickra-lib/wickra/bindings/go + +go 1.23 diff --git a/bindings/go/indicators_gen.go b/bindings/go/indicators_gen.go new file mode 100644 index 00000000..b2296ce4 --- /dev/null +++ b/bindings/go/indicators_gen.go @@ -0,0 +1,31503 @@ +// Code generated from bindings/c/include/wickra.h. DO NOT EDIT. + +package wickra + +/* +#include "wickra.h" +*/ +import "C" + +import ( + "runtime" + "unsafe" +) + +// Keep the unsafe import live even if no archetype in a given build uses +// a slice pointer (every real header does). +var _ = unsafe.Pointer(nil) + +// AccelerationBandsOutput is the output of the AccelerationBands indicator. +type AccelerationBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// AdxOutput is the output of the Adx indicator. +type AdxOutput struct { + PlusDi float64 + MinusDi float64 + Adx float64 +} + +// AlligatorOutput is the output of the Alligator indicator. +type AlligatorOutput struct { + Jaw float64 + Teeth float64 + Lips float64 +} + +// AndrewsPitchforkOutput is the output of the AndrewsPitchfork indicator. +type AndrewsPitchforkOutput struct { + Median float64 + Upper float64 + Lower float64 +} + +// AroonOutput is the output of the Aroon indicator. +type AroonOutput struct { + Up float64 + Down float64 +} + +// AtrBandsOutput is the output of the AtrBands indicator. +type AtrBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// AtrRatchetOutput is the output of the AtrRatchet indicator. +type AtrRatchetOutput struct { + Value float64 + Direction float64 +} + +// AutoFibOutput is the output of the AutoFib indicator. +type AutoFibOutput struct { + Level0 float64 + Level236 float64 + Level382 float64 + Level500 float64 + Level618 float64 + Level786 float64 + Level1000 float64 +} + +// BollingerOutput is the output of the Bollinger indicator. +type BollingerOutput struct { + Upper float64 + Middle float64 + Lower float64 + Stddev float64 +} + +// BomarBandsOutput is the output of the BomarBands indicator. +type BomarBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// CamarillaPivotsOutput is the output of the CamarillaPivots indicator. +type CamarillaPivotsOutput struct { + Pp float64 + R1 float64 + R2 float64 + R3 float64 + R4 float64 + S1 float64 + S2 float64 + S3 float64 + S4 float64 +} + +// CandleVolumeOutput is the output of the CandleVolume indicator. +type CandleVolumeOutput struct { + Body float64 + Width float64 +} + +// CentralPivotRangeOutput is the output of the CentralPivotRange indicator. +type CentralPivotRangeOutput struct { + Pivot float64 + Tc float64 + Bc float64 +} + +// ChandeKrollStopOutput is the output of the ChandeKrollStop indicator. +type ChandeKrollStopOutput struct { + StopLong float64 + StopShort float64 +} + +// ChandelierExitOutput is the output of the ChandelierExit indicator. +type ChandelierExitOutput struct { + LongStop float64 + ShortStop float64 +} + +// ClassicPivotsOutput is the output of the ClassicPivots indicator. +type ClassicPivotsOutput struct { + Pp float64 + R1 float64 + R2 float64 + R3 float64 + S1 float64 + S2 float64 + S3 float64 +} + +// CointegrationOutput is the output of the Cointegration indicator. +type CointegrationOutput struct { + HedgeRatio float64 + Spread float64 + AdfStat float64 +} + +// CompositeProfileOutput is the output of the CompositeProfile indicator. +type CompositeProfileOutput struct { + Poc float64 + Vah float64 + Val float64 +} + +// DemarkPivotsOutput is the output of the DemarkPivots indicator. +type DemarkPivotsOutput struct { + Pp float64 + R1 float64 + S1 float64 +} + +// DollarBar is the output of the DollarBar indicator. +type DollarBar struct { + Open float64 + High float64 + Low float64 + Close float64 + Volume float64 + Dollar float64 +} + +// DonchianOutput is the output of the Donchian indicator. +type DonchianOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// DonchianStopOutput is the output of the DonchianStop indicator. +type DonchianStopOutput struct { + StopLong float64 + StopShort float64 +} + +// DoubleBollingerOutput is the output of the DoubleBollinger indicator. +type DoubleBollingerOutput struct { + UpperOuter float64 + UpperInner float64 + Middle float64 + LowerInner float64 + LowerOuter float64 +} + +// ElderRayOutput is the output of the ElderRay indicator. +type ElderRayOutput struct { + BullPower float64 + BearPower float64 +} + +// ElderSafeZoneOutput is the output of the ElderSafeZone indicator. +type ElderSafeZoneOutput struct { + Value float64 + Direction float64 +} + +// EquivolumeOutput is the output of the Equivolume indicator. +type EquivolumeOutput struct { + Height float64 + Width float64 +} + +// FibArcsOutput is the output of the FibArcs indicator. +type FibArcsOutput struct { + Arc382 float64 + Arc500 float64 + Arc618 float64 +} + +// FibChannelOutput is the output of the FibChannel indicator. +type FibChannelOutput struct { + Base float64 + Level618 float64 + Level1000 float64 + Level1618 float64 +} + +// FibConfluenceOutput is the output of the FibConfluence indicator. +type FibConfluenceOutput struct { + Price float64 + Strength float64 +} + +// FibExtensionOutput is the output of the FibExtension indicator. +type FibExtensionOutput struct { + Level1272 float64 + Level1414 float64 + Level1618 float64 + Level2000 float64 + Level2618 float64 +} + +// FibFanOutput is the output of the FibFan indicator. +type FibFanOutput struct { + Fan382 float64 + Fan500 float64 + Fan618 float64 +} + +// FibProjectionOutput is the output of the FibProjection indicator. +type FibProjectionOutput struct { + Level618 float64 + Level1000 float64 + Level1618 float64 + Level2618 float64 +} + +// FibRetracementOutput is the output of the FibRetracement indicator. +type FibRetracementOutput struct { + Level0 float64 + Level236 float64 + Level382 float64 + Level500 float64 + Level618 float64 + Level786 float64 + Level1000 float64 +} + +// FibTimeZonesOutput is the output of the FibTimeZones indicator. +type FibTimeZonesOutput struct { + OnZone float64 + BarsToNext float64 +} + +// FibonacciPivotsOutput is the output of the FibonacciPivots indicator. +type FibonacciPivotsOutput struct { + Pp float64 + R1 float64 + R2 float64 + R3 float64 + S1 float64 + S2 float64 + S3 float64 +} + +// FootprintLevel is the output of the FootprintLevel indicator. +type FootprintLevel struct { + Price float64 + BidVol float64 + AskVol float64 +} + +// FractalChaosBandsOutput is the output of the FractalChaosBands indicator. +type FractalChaosBandsOutput struct { + Upper float64 + Lower float64 +} + +// GatorOscillatorOutput is the output of the GatorOscillator indicator. +type GatorOscillatorOutput struct { + Upper float64 + Lower float64 +} + +// GoldenPocketOutput is the output of the GoldenPocket indicator. +type GoldenPocketOutput struct { + Low float64 + Mid float64 + High float64 +} + +// HeikinAshiOutput is the output of the HeikinAshi indicator. +type HeikinAshiOutput struct { + Open float64 + High float64 + Low float64 + Close float64 +} + +// HighLowVolumeNodesOutput is the output of the HighLowVolumeNodes indicator. +type HighLowVolumeNodesOutput struct { + Hvn float64 + Lvn float64 +} + +// HtPhasorOutput is the output of the HtPhasor indicator. +type HtPhasorOutput struct { + Inphase float64 + Quadrature float64 +} + +// HurstChannelOutput is the output of the HurstChannel indicator. +type HurstChannelOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// IchimokuOutput is the output of the Ichimoku indicator. +type IchimokuOutput struct { + Tenkan float64 + Kijun float64 + SenkouA float64 + SenkouB float64 + Chikou float64 +} + +// ImbalanceBar is the output of the ImbalanceBar indicator. +type ImbalanceBar struct { + Open float64 + High float64 + Low float64 + Close float64 + Imbalance float64 + Direction int8 +} + +// InitialBalanceOutput is the output of the InitialBalance indicator. +type InitialBalanceOutput struct { + High float64 + Low float64 +} + +// KagiBar is the output of the KagiBar indicator. +type KagiBar struct { + Start float64 + End float64 + Direction int8 +} + +// KalmanHedgeRatioOutput is the output of the KalmanHedgeRatio indicator. +type KalmanHedgeRatioOutput struct { + HedgeRatio float64 + Intercept float64 + Spread float64 +} + +// KaseDevStopOutput is the output of the KaseDevStop indicator. +type KaseDevStopOutput struct { + Value float64 + Direction float64 +} + +// KasePermissionStochasticOutput is the output of the KasePermissionStochastic indicator. +type KasePermissionStochasticOutput struct { + Fast float64 + Slow float64 +} + +// KeltnerOutput is the output of the Keltner indicator. +type KeltnerOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// KstOutput is the output of the Kst indicator. +type KstOutput struct { + Kst float64 + Signal float64 +} + +// LeadLagCrossCorrelationOutput is the output of the LeadLagCrossCorrelation indicator. +type LeadLagCrossCorrelationOutput struct { + Lag int64 + Correlation float64 +} + +// LinRegChannelOutput is the output of the LinRegChannel indicator. +type LinRegChannelOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// LineBreakBar is the output of the LineBreakBar indicator. +type LineBreakBar struct { + Open float64 + Close float64 + Direction int8 +} + +// LiquidationFeaturesOutput is the output of the LiquidationFeatures indicator. +type LiquidationFeaturesOutput struct { + Long float64 + Short float64 + Net float64 + Total float64 + Imbalance float64 +} + +// MaEnvelopeOutput is the output of the MaEnvelope indicator. +type MaEnvelopeOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// MacdOutput is the output of the Macd indicator. +type MacdOutput struct { + Macd float64 + Signal float64 + Histogram float64 +} + +// MamaOutput is the output of the Mama indicator. +type MamaOutput struct { + Mama float64 + Fama float64 +} + +// MedianChannelOutput is the output of the MedianChannel indicator. +type MedianChannelOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// ModifiedMaStopOutput is the output of the ModifiedMaStop indicator. +type ModifiedMaStopOutput struct { + Value float64 + Direction float64 +} + +// MurreyMathLinesOutput is the output of the MurreyMathLines indicator. +type MurreyMathLinesOutput struct { + Mm88 float64 + Mm78 float64 + Mm68 float64 + Mm58 float64 + Mm48 float64 + Mm38 float64 + Mm28 float64 + Mm18 float64 + Mm08 float64 +} + +// NrtrOutput is the output of the Nrtr indicator. +type NrtrOutput struct { + Value float64 + Direction float64 +} + +// OpeningRangeOutput is the output of the OpeningRange indicator. +type OpeningRangeOutput struct { + High float64 + Low float64 + BreakoutDistance float64 +} + +// OvernightIntradayReturnOutput is the output of the OvernightIntradayReturn indicator. +type OvernightIntradayReturnOutput struct { + Overnight float64 + Intraday float64 +} + +// PnfColumn is the output of the PnfColumn indicator. +type PnfColumn struct { + Direction int8 + High float64 + Low float64 +} + +// ProjectionBandsOutput is the output of the ProjectionBands indicator. +type ProjectionBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// QqeOutput is the output of the Qqe indicator. +type QqeOutput struct { + RsiMa float64 + TrailingLine float64 +} + +// QuartileBandsOutput is the output of the QuartileBands indicator. +type QuartileBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// RangeBar is the output of the RangeBar indicator. +type RangeBar struct { + Open float64 + Close float64 + Direction int8 +} + +// RelativeStrengthOutput is the output of the RelativeStrength indicator. +type RelativeStrengthOutput struct { + Ratio float64 + RatioMa float64 + RatioRsi float64 +} + +// RenkoBrick is the output of the RenkoBrick indicator. +type RenkoBrick struct { + Open float64 + Close float64 + Direction int8 +} + +// RunBar is the output of the RunBar indicator. +type RunBar struct { + Open float64 + High float64 + Low float64 + Close float64 + Length int + Direction int8 +} + +// RwiOutput is the output of the Rwi indicator. +type RwiOutput struct { + High float64 + Low float64 +} + +// SessionHighLowOutput is the output of the SessionHighLow indicator. +type SessionHighLowOutput struct { + High float64 + Low float64 +} + +// SessionRangeOutput is the output of the SessionRange indicator. +type SessionRangeOutput struct { + Asia float64 + Eu float64 + Us float64 +} + +// SmoothedHeikinAshiOutput is the output of the SmoothedHeikinAshi indicator. +type SmoothedHeikinAshiOutput struct { + Open float64 + High float64 + Low float64 + Close float64 +} + +// SpreadBollingerBandsOutput is the output of the SpreadBollingerBands indicator. +type SpreadBollingerBandsOutput struct { + Middle float64 + Upper float64 + Lower float64 + PercentB float64 +} + +// StandardErrorBandsOutput is the output of the StandardErrorBands indicator. +type StandardErrorBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// StarcBandsOutput is the output of the StarcBands indicator. +type StarcBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 +} + +// StochasticOutput is the output of the Stochastic indicator. +type StochasticOutput struct { + K float64 + D float64 +} + +// SuperTrendOutput is the output of the SuperTrend indicator. +type SuperTrendOutput struct { + Value float64 + Direction float64 +} + +// TdLinesOutput is the output of the TdLines indicator. +type TdLinesOutput struct { + Resistance float64 + Support float64 +} + +// TdMovingAverageOutput is the output of the TdMovingAverage indicator. +type TdMovingAverageOutput struct { + St1 float64 + St2 float64 +} + +// TdRangeProjectionOutput is the output of the TdRangeProjection indicator. +type TdRangeProjectionOutput struct { + High float64 + Low float64 +} + +// TdRiskLevelOutput is the output of the TdRiskLevel indicator. +type TdRiskLevelOutput struct { + BuyRisk float64 + SellRisk float64 +} + +// TdSequentialOutput is the output of the TdSequential indicator. +type TdSequentialOutput struct { + Setup float64 + Countdown float64 + Direction float64 +} + +// TickBar is the output of the TickBar indicator. +type TickBar struct { + Open float64 + High float64 + Low float64 + Close float64 + Volume float64 +} + +// TpoProfileOutputScalars is the output of the TpoProfileOutputScalars indicator. +type TpoProfileOutputScalars struct { + PriceLow float64 + PriceHigh float64 + Values []float64 +} + +// TtmSqueezeOutput is the output of the TtmSqueeze indicator. +type TtmSqueezeOutput struct { + Squeeze float64 + Momentum float64 +} + +// ValueAreaOutput is the output of the ValueArea indicator. +type ValueAreaOutput struct { + Poc float64 + Vah float64 + Val float64 +} + +// VolatilityConeOutput is the output of the VolatilityCone indicator. +type VolatilityConeOutput struct { + Current float64 + Min float64 + Median float64 + Max float64 + Percentile float64 +} + +// VolumeBar is the output of the VolumeBar indicator. +type VolumeBar struct { + Open float64 + High float64 + Low float64 + Close float64 + Volume float64 +} + +// VolumeProfileOutputScalars is the output of the VolumeProfileOutputScalars indicator. +type VolumeProfileOutputScalars struct { + PriceLow float64 + PriceHigh float64 + Values []float64 +} + +// VolumeWeightedMacdOutput is the output of the VolumeWeightedMacd indicator. +type VolumeWeightedMacdOutput struct { + Macd float64 + Signal float64 + Histogram float64 +} + +// VolumeWeightedSrOutput is the output of the VolumeWeightedSr indicator. +type VolumeWeightedSrOutput struct { + Support float64 + Resistance float64 +} + +// VortexOutput is the output of the Vortex indicator. +type VortexOutput struct { + Plus float64 + Minus float64 +} + +// VwapStdDevBandsOutput is the output of the VwapStdDevBands indicator. +type VwapStdDevBandsOutput struct { + Upper float64 + Middle float64 + Lower float64 + Stddev float64 +} + +// WaveTrendOutput is the output of the WaveTrend indicator. +type WaveTrendOutput struct { + Wt1 float64 + Wt2 float64 +} + +// WilliamsFractalsOutput is the output of the WilliamsFractals indicator. +type WilliamsFractalsOutput struct { + Up float64 + Down float64 +} + +// WoodiePivotsOutput is the output of the WoodiePivots indicator. +type WoodiePivotsOutput struct { + Pp float64 + R1 float64 + R2 float64 + S1 float64 + S2 float64 +} + +// ZeroLagMacdOutput is the output of the ZeroLagMacd indicator. +type ZeroLagMacdOutput struct { + Macd float64 + Signal float64 + Histogram float64 +} + +// ZigZagOutput is the output of the ZigZag indicator. +type ZigZagOutput struct { + Swing float64 + Direction float64 +} + +// AbandonedBaby wraps the AbandonedBaby indicator over the Wickra C ABI. +type AbandonedBaby struct { + handle *C.struct_AbandonedBaby +} + +// NewAbandonedBaby constructs a AbandonedBaby. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAbandonedBaby() (*AbandonedBaby, error) { + ptr := C.wickra_abandoned_baby_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AbandonedBaby{handle: ptr} + runtime.SetFinalizer(obj, (*AbandonedBaby).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AbandonedBaby) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_abandoned_baby_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AbandonedBaby) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_abandoned_baby_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AbandonedBaby) Reset() { + C.wickra_abandoned_baby_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AbandonedBaby) Close() { + if ind.handle != nil { + C.wickra_abandoned_baby_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Abcd wraps the Abcd indicator over the Wickra C ABI. +type Abcd struct { + handle *C.struct_Abcd +} + +// NewAbcd constructs a Abcd. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAbcd() (*Abcd, error) { + ptr := C.wickra_abcd_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Abcd{handle: ptr} + runtime.SetFinalizer(obj, (*Abcd).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Abcd) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_abcd_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Abcd) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_abcd_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Abcd) Reset() { + C.wickra_abcd_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Abcd) Close() { + if ind.handle != nil { + C.wickra_abcd_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AbsoluteBreadthIndex wraps the AbsoluteBreadthIndex indicator over the Wickra C ABI. +type AbsoluteBreadthIndex struct { + handle *C.struct_AbsoluteBreadthIndex +} + +// NewAbsoluteBreadthIndex constructs a AbsoluteBreadthIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAbsoluteBreadthIndex() (*AbsoluteBreadthIndex, error) { + ptr := C.wickra_absolute_breadth_index_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AbsoluteBreadthIndex{handle: ptr} + runtime.SetFinalizer(obj, (*AbsoluteBreadthIndex).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *AbsoluteBreadthIndex) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_absolute_breadth_index_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AbsoluteBreadthIndex) Reset() { + C.wickra_absolute_breadth_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AbsoluteBreadthIndex) Close() { + if ind.handle != nil { + C.wickra_absolute_breadth_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AccelerationBands wraps the AccelerationBands indicator over the Wickra C ABI. +type AccelerationBands struct { + handle *C.struct_AccelerationBands +} + +// NewAccelerationBands constructs a AccelerationBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAccelerationBands(period int, factor float64) (*AccelerationBands, error) { + ptr := C.wickra_acceleration_bands_new(C.uintptr_t(period), C.double(factor)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AccelerationBands{handle: ptr} + runtime.SetFinalizer(obj, (*AccelerationBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *AccelerationBands) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AccelerationBandsOutput, bool) { + var out C.struct_WickraAccelerationBandsOutput + ok := bool(C.wickra_acceleration_bands_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AccelerationBandsOutput{}, false + } + return AccelerationBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AccelerationBands) Reset() { + C.wickra_acceleration_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AccelerationBands) Close() { + if ind.handle != nil { + C.wickra_acceleration_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AcceleratorOscillator wraps the AcceleratorOscillator indicator over the Wickra C ABI. +type AcceleratorOscillator struct { + handle *C.struct_AcceleratorOscillator +} + +// NewAcceleratorOscillator constructs a AcceleratorOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAcceleratorOscillator(aoFast int, aoSlow int, signalPeriod int) (*AcceleratorOscillator, error) { + ptr := C.wickra_accelerator_oscillator_new(C.uintptr_t(aoFast), C.uintptr_t(aoSlow), C.uintptr_t(signalPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AcceleratorOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*AcceleratorOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AcceleratorOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_accelerator_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AcceleratorOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_accelerator_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AcceleratorOscillator) Reset() { + C.wickra_accelerator_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AcceleratorOscillator) Close() { + if ind.handle != nil { + C.wickra_accelerator_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdOscillator wraps the AdOscillator indicator over the Wickra C ABI. +type AdOscillator struct { + handle *C.struct_AdOscillator +} + +// NewAdOscillator constructs a AdOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdOscillator() (*AdOscillator, error) { + ptr := C.wickra_ad_oscillator_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*AdOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AdOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_ad_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AdOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ad_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdOscillator) Reset() { + C.wickra_ad_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdOscillator) Close() { + if ind.handle != nil { + C.wickra_ad_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdVolumeLine wraps the AdVolumeLine indicator over the Wickra C ABI. +type AdVolumeLine struct { + handle *C.struct_AdVolumeLine +} + +// NewAdVolumeLine constructs a AdVolumeLine. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdVolumeLine() (*AdVolumeLine, error) { + ptr := C.wickra_ad_volume_line_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdVolumeLine{handle: ptr} + runtime.SetFinalizer(obj, (*AdVolumeLine).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *AdVolumeLine) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_ad_volume_line_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdVolumeLine) Reset() { + C.wickra_ad_volume_line_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdVolumeLine) Close() { + if ind.handle != nil { + C.wickra_ad_volume_line_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdaptiveCci wraps the AdaptiveCci indicator over the Wickra C ABI. +type AdaptiveCci struct { + handle *C.struct_AdaptiveCci +} + +// NewAdaptiveCci constructs a AdaptiveCci. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdaptiveCci(period int) (*AdaptiveCci, error) { + ptr := C.wickra_adaptive_cci_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdaptiveCci{handle: ptr} + runtime.SetFinalizer(obj, (*AdaptiveCci).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AdaptiveCci) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_adaptive_cci_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AdaptiveCci) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_adaptive_cci_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdaptiveCci) Reset() { + C.wickra_adaptive_cci_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdaptiveCci) Close() { + if ind.handle != nil { + C.wickra_adaptive_cci_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdaptiveCycle wraps the AdaptiveCycle indicator over the Wickra C ABI. +type AdaptiveCycle struct { + handle *C.struct_AdaptiveCycle +} + +// NewAdaptiveCycle constructs a AdaptiveCycle. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdaptiveCycle() (*AdaptiveCycle, error) { + ptr := C.wickra_adaptive_cycle_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdaptiveCycle{handle: ptr} + runtime.SetFinalizer(obj, (*AdaptiveCycle).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AdaptiveCycle) Update(value float64) float64 { + r := float64(C.wickra_adaptive_cycle_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AdaptiveCycle) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_adaptive_cycle_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdaptiveCycle) Reset() { + C.wickra_adaptive_cycle_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdaptiveCycle) Close() { + if ind.handle != nil { + C.wickra_adaptive_cycle_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdaptiveLaguerreFilter wraps the AdaptiveLaguerreFilter indicator over the Wickra C ABI. +type AdaptiveLaguerreFilter struct { + handle *C.struct_AdaptiveLaguerreFilter +} + +// NewAdaptiveLaguerreFilter constructs a AdaptiveLaguerreFilter. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdaptiveLaguerreFilter(period int) (*AdaptiveLaguerreFilter, error) { + ptr := C.wickra_adaptive_laguerre_filter_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdaptiveLaguerreFilter{handle: ptr} + runtime.SetFinalizer(obj, (*AdaptiveLaguerreFilter).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AdaptiveLaguerreFilter) Update(value float64) float64 { + r := float64(C.wickra_adaptive_laguerre_filter_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AdaptiveLaguerreFilter) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_adaptive_laguerre_filter_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdaptiveLaguerreFilter) Reset() { + C.wickra_adaptive_laguerre_filter_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdaptiveLaguerreFilter) Close() { + if ind.handle != nil { + C.wickra_adaptive_laguerre_filter_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdaptiveRsi wraps the AdaptiveRsi indicator over the Wickra C ABI. +type AdaptiveRsi struct { + handle *C.struct_AdaptiveRsi +} + +// NewAdaptiveRsi constructs a AdaptiveRsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdaptiveRsi(period int) (*AdaptiveRsi, error) { + ptr := C.wickra_adaptive_rsi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdaptiveRsi{handle: ptr} + runtime.SetFinalizer(obj, (*AdaptiveRsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AdaptiveRsi) Update(value float64) float64 { + r := float64(C.wickra_adaptive_rsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AdaptiveRsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_adaptive_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdaptiveRsi) Reset() { + C.wickra_adaptive_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdaptiveRsi) Close() { + if ind.handle != nil { + C.wickra_adaptive_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Adl wraps the Adl indicator over the Wickra C ABI. +type Adl struct { + handle *C.struct_Adl +} + +// NewAdl constructs a Adl. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdl() (*Adl, error) { + ptr := C.wickra_adl_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Adl{handle: ptr} + runtime.SetFinalizer(obj, (*Adl).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Adl) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_adl_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Adl) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_adl_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Adl) Reset() { + C.wickra_adl_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Adl) Close() { + if ind.handle != nil { + C.wickra_adl_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdvanceBlock wraps the AdvanceBlock indicator over the Wickra C ABI. +type AdvanceBlock struct { + handle *C.struct_AdvanceBlock +} + +// NewAdvanceBlock constructs a AdvanceBlock. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdvanceBlock() (*AdvanceBlock, error) { + ptr := C.wickra_advance_block_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdvanceBlock{handle: ptr} + runtime.SetFinalizer(obj, (*AdvanceBlock).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AdvanceBlock) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_advance_block_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AdvanceBlock) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_advance_block_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdvanceBlock) Reset() { + C.wickra_advance_block_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdvanceBlock) Close() { + if ind.handle != nil { + C.wickra_advance_block_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdvanceDecline wraps the AdvanceDecline indicator over the Wickra C ABI. +type AdvanceDecline struct { + handle *C.struct_AdvanceDecline +} + +// NewAdvanceDecline constructs a AdvanceDecline. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdvanceDecline() (*AdvanceDecline, error) { + ptr := C.wickra_advance_decline_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdvanceDecline{handle: ptr} + runtime.SetFinalizer(obj, (*AdvanceDecline).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *AdvanceDecline) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_advance_decline_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdvanceDecline) Reset() { + C.wickra_advance_decline_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdvanceDecline) Close() { + if ind.handle != nil { + C.wickra_advance_decline_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AdvanceDeclineRatio wraps the AdvanceDeclineRatio indicator over the Wickra C ABI. +type AdvanceDeclineRatio struct { + handle *C.struct_AdvanceDeclineRatio +} + +// NewAdvanceDeclineRatio constructs a AdvanceDeclineRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdvanceDeclineRatio() (*AdvanceDeclineRatio, error) { + ptr := C.wickra_advance_decline_ratio_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AdvanceDeclineRatio{handle: ptr} + runtime.SetFinalizer(obj, (*AdvanceDeclineRatio).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *AdvanceDeclineRatio) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_advance_decline_ratio_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AdvanceDeclineRatio) Reset() { + C.wickra_advance_decline_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AdvanceDeclineRatio) Close() { + if ind.handle != nil { + C.wickra_advance_decline_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Adx wraps the Adx indicator over the Wickra C ABI. +type Adx struct { + handle *C.struct_Adx +} + +// NewAdx constructs a Adx. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdx(period int) (*Adx, error) { + ptr := C.wickra_adx_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Adx{handle: ptr} + runtime.SetFinalizer(obj, (*Adx).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Adx) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AdxOutput, bool) { + var out C.struct_WickraAdxOutput + ok := bool(C.wickra_adx_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AdxOutput{}, false + } + return AdxOutput{float64(out.plus_di), float64(out.minus_di), float64(out.adx)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Adx) Reset() { + C.wickra_adx_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Adx) Close() { + if ind.handle != nil { + C.wickra_adx_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Adxr wraps the Adxr indicator over the Wickra C ABI. +type Adxr struct { + handle *C.struct_Adxr +} + +// NewAdxr constructs a Adxr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAdxr(period int) (*Adxr, error) { + ptr := C.wickra_adxr_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Adxr{handle: ptr} + runtime.SetFinalizer(obj, (*Adxr).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Adxr) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_adxr_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Adxr) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_adxr_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Adxr) Reset() { + C.wickra_adxr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Adxr) Close() { + if ind.handle != nil { + C.wickra_adxr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Alligator wraps the Alligator indicator over the Wickra C ABI. +type Alligator struct { + handle *C.struct_Alligator +} + +// NewAlligator constructs a Alligator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAlligator(jawPeriod int, teethPeriod int, lipsPeriod int) (*Alligator, error) { + ptr := C.wickra_alligator_new(C.uintptr_t(jawPeriod), C.uintptr_t(teethPeriod), C.uintptr_t(lipsPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Alligator{handle: ptr} + runtime.SetFinalizer(obj, (*Alligator).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Alligator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AlligatorOutput, bool) { + var out C.struct_WickraAlligatorOutput + ok := bool(C.wickra_alligator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AlligatorOutput{}, false + } + return AlligatorOutput{float64(out.jaw), float64(out.teeth), float64(out.lips)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Alligator) Reset() { + C.wickra_alligator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Alligator) Close() { + if ind.handle != nil { + C.wickra_alligator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Alma wraps the Alma indicator over the Wickra C ABI. +type Alma struct { + handle *C.struct_Alma +} + +// NewAlma constructs a Alma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAlma(period int, offset float64, sigma float64) (*Alma, error) { + ptr := C.wickra_alma_new(C.uintptr_t(period), C.double(offset), C.double(sigma)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Alma{handle: ptr} + runtime.SetFinalizer(obj, (*Alma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Alma) Update(value float64) float64 { + r := float64(C.wickra_alma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Alma) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_alma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Alma) Reset() { + C.wickra_alma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Alma) Close() { + if ind.handle != nil { + C.wickra_alma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Alpha wraps the Alpha indicator over the Wickra C ABI. +type Alpha struct { + handle *C.struct_Alpha +} + +// NewAlpha constructs a Alpha. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAlpha(period int, riskFree float64) (*Alpha, error) { + ptr := C.wickra_alpha_new(C.uintptr_t(period), C.double(riskFree)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Alpha{handle: ptr} + runtime.SetFinalizer(obj, (*Alpha).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Alpha) Update(x float64, y float64) float64 { + r := float64(C.wickra_alpha_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Alpha) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_alpha_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Alpha) Reset() { + C.wickra_alpha_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Alpha) Close() { + if ind.handle != nil { + C.wickra_alpha_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AmihudIlliquidity wraps the AmihudIlliquidity indicator over the Wickra C ABI. +type AmihudIlliquidity struct { + handle *C.struct_AmihudIlliquidity +} + +// NewAmihudIlliquidity constructs a AmihudIlliquidity. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAmihudIlliquidity(period int) (*AmihudIlliquidity, error) { + ptr := C.wickra_amihud_illiquidity_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AmihudIlliquidity{handle: ptr} + runtime.SetFinalizer(obj, (*AmihudIlliquidity).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AmihudIlliquidity) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_amihud_illiquidity_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AmihudIlliquidity) Reset() { + C.wickra_amihud_illiquidity_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AmihudIlliquidity) Close() { + if ind.handle != nil { + C.wickra_amihud_illiquidity_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AnchoredRsi wraps the AnchoredRsi indicator over the Wickra C ABI. +type AnchoredRsi struct { + handle *C.struct_AnchoredRsi +} + +// NewAnchoredRsi constructs a AnchoredRsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAnchoredRsi() (*AnchoredRsi, error) { + ptr := C.wickra_anchored_rsi_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AnchoredRsi{handle: ptr} + runtime.SetFinalizer(obj, (*AnchoredRsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AnchoredRsi) Update(value float64) float64 { + r := float64(C.wickra_anchored_rsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AnchoredRsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_anchored_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AnchoredRsi) Reset() { + C.wickra_anchored_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AnchoredRsi) Close() { + if ind.handle != nil { + C.wickra_anchored_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AnchoredVwap wraps the AnchoredVwap indicator over the Wickra C ABI. +type AnchoredVwap struct { + handle *C.struct_AnchoredVwap +} + +// NewAnchoredVwap constructs a AnchoredVwap. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAnchoredVwap() (*AnchoredVwap, error) { + ptr := C.wickra_anchored_vwap_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AnchoredVwap{handle: ptr} + runtime.SetFinalizer(obj, (*AnchoredVwap).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AnchoredVwap) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_anchored_vwap_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AnchoredVwap) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_anchored_vwap_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AnchoredVwap) Reset() { + C.wickra_anchored_vwap_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AnchoredVwap) Close() { + if ind.handle != nil { + C.wickra_anchored_vwap_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AndrewsPitchfork wraps the AndrewsPitchfork indicator over the Wickra C ABI. +type AndrewsPitchfork struct { + handle *C.struct_AndrewsPitchfork +} + +// NewAndrewsPitchfork constructs a AndrewsPitchfork. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAndrewsPitchfork(strength int) (*AndrewsPitchfork, error) { + ptr := C.wickra_andrews_pitchfork_new(C.uintptr_t(strength)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AndrewsPitchfork{handle: ptr} + runtime.SetFinalizer(obj, (*AndrewsPitchfork).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *AndrewsPitchfork) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AndrewsPitchforkOutput, bool) { + var out C.struct_WickraAndrewsPitchforkOutput + ok := bool(C.wickra_andrews_pitchfork_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AndrewsPitchforkOutput{}, false + } + return AndrewsPitchforkOutput{float64(out.median), float64(out.upper), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AndrewsPitchfork) Reset() { + C.wickra_andrews_pitchfork_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AndrewsPitchfork) Close() { + if ind.handle != nil { + C.wickra_andrews_pitchfork_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Apo wraps the Apo indicator over the Wickra C ABI. +type Apo struct { + handle *C.struct_Apo +} + +// NewApo constructs a Apo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewApo(fast int, slow int) (*Apo, error) { + ptr := C.wickra_apo_new(C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Apo{handle: ptr} + runtime.SetFinalizer(obj, (*Apo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Apo) Update(value float64) float64 { + r := float64(C.wickra_apo_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Apo) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_apo_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Apo) Reset() { + C.wickra_apo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Apo) Close() { + if ind.handle != nil { + C.wickra_apo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Aroon wraps the Aroon indicator over the Wickra C ABI. +type Aroon struct { + handle *C.struct_Aroon +} + +// NewAroon constructs a Aroon. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAroon(period int) (*Aroon, error) { + ptr := C.wickra_aroon_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Aroon{handle: ptr} + runtime.SetFinalizer(obj, (*Aroon).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Aroon) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AroonOutput, bool) { + var out C.struct_WickraAroonOutput + ok := bool(C.wickra_aroon_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AroonOutput{}, false + } + return AroonOutput{float64(out.up), float64(out.down)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Aroon) Reset() { + C.wickra_aroon_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Aroon) Close() { + if ind.handle != nil { + C.wickra_aroon_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AroonOscillator wraps the AroonOscillator indicator over the Wickra C ABI. +type AroonOscillator struct { + handle *C.struct_AroonOscillator +} + +// NewAroonOscillator constructs a AroonOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAroonOscillator(period int) (*AroonOscillator, error) { + ptr := C.wickra_aroon_oscillator_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AroonOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*AroonOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AroonOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_aroon_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AroonOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_aroon_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AroonOscillator) Reset() { + C.wickra_aroon_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AroonOscillator) Close() { + if ind.handle != nil { + C.wickra_aroon_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Atr wraps the Atr indicator over the Wickra C ABI. +type Atr struct { + handle *C.struct_Atr +} + +// NewAtr constructs a Atr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAtr(period int) (*Atr, error) { + ptr := C.wickra_atr_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Atr{handle: ptr} + runtime.SetFinalizer(obj, (*Atr).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Atr) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_atr_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Atr) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_atr_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Atr) Reset() { + C.wickra_atr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Atr) Close() { + if ind.handle != nil { + C.wickra_atr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AtrBands wraps the AtrBands indicator over the Wickra C ABI. +type AtrBands struct { + handle *C.struct_AtrBands +} + +// NewAtrBands constructs a AtrBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAtrBands(period int, multiplier float64) (*AtrBands, error) { + ptr := C.wickra_atr_bands_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AtrBands{handle: ptr} + runtime.SetFinalizer(obj, (*AtrBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *AtrBands) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AtrBandsOutput, bool) { + var out C.struct_WickraAtrBandsOutput + ok := bool(C.wickra_atr_bands_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AtrBandsOutput{}, false + } + return AtrBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AtrBands) Reset() { + C.wickra_atr_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AtrBands) Close() { + if ind.handle != nil { + C.wickra_atr_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AtrRatchet wraps the AtrRatchet indicator over the Wickra C ABI. +type AtrRatchet struct { + handle *C.struct_AtrRatchet +} + +// NewAtrRatchet constructs a AtrRatchet. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAtrRatchet(atrPeriod int, startMult float64, increment float64) (*AtrRatchet, error) { + ptr := C.wickra_atr_ratchet_new(C.uintptr_t(atrPeriod), C.double(startMult), C.double(increment)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AtrRatchet{handle: ptr} + runtime.SetFinalizer(obj, (*AtrRatchet).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *AtrRatchet) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AtrRatchetOutput, bool) { + var out C.struct_WickraAtrRatchetOutput + ok := bool(C.wickra_atr_ratchet_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AtrRatchetOutput{}, false + } + return AtrRatchetOutput{float64(out.value), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AtrRatchet) Reset() { + C.wickra_atr_ratchet_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AtrRatchet) Close() { + if ind.handle != nil { + C.wickra_atr_ratchet_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AtrTrailingStop wraps the AtrTrailingStop indicator over the Wickra C ABI. +type AtrTrailingStop struct { + handle *C.struct_AtrTrailingStop +} + +// NewAtrTrailingStop constructs a AtrTrailingStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAtrTrailingStop(atrPeriod int, multiplier float64) (*AtrTrailingStop, error) { + ptr := C.wickra_atr_trailing_stop_new(C.uintptr_t(atrPeriod), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AtrTrailingStop{handle: ptr} + runtime.SetFinalizer(obj, (*AtrTrailingStop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AtrTrailingStop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_atr_trailing_stop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AtrTrailingStop) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_atr_trailing_stop_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AtrTrailingStop) Reset() { + C.wickra_atr_trailing_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AtrTrailingStop) Close() { + if ind.handle != nil { + C.wickra_atr_trailing_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AutoFib wraps the AutoFib indicator over the Wickra C ABI. +type AutoFib struct { + handle *C.struct_AutoFib +} + +// NewAutoFib constructs a AutoFib. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAutoFib() (*AutoFib, error) { + ptr := C.wickra_auto_fib_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AutoFib{handle: ptr} + runtime.SetFinalizer(obj, (*AutoFib).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *AutoFib) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (AutoFibOutput, bool) { + var out C.struct_WickraAutoFibOutput + ok := bool(C.wickra_auto_fib_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return AutoFibOutput{}, false + } + return AutoFibOutput{float64(out.level_0), float64(out.level_236), float64(out.level_382), float64(out.level_500), float64(out.level_618), float64(out.level_786), float64(out.level_1000)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AutoFib) Reset() { + C.wickra_auto_fib_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AutoFib) Close() { + if ind.handle != nil { + C.wickra_auto_fib_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Autocorrelation wraps the Autocorrelation indicator over the Wickra C ABI. +type Autocorrelation struct { + handle *C.struct_Autocorrelation +} + +// NewAutocorrelation constructs a Autocorrelation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAutocorrelation(period int, lag int) (*Autocorrelation, error) { + ptr := C.wickra_autocorrelation_new(C.uintptr_t(period), C.uintptr_t(lag)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Autocorrelation{handle: ptr} + runtime.SetFinalizer(obj, (*Autocorrelation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Autocorrelation) Update(value float64) float64 { + r := float64(C.wickra_autocorrelation_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Autocorrelation) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_autocorrelation_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Autocorrelation) Reset() { + C.wickra_autocorrelation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Autocorrelation) Close() { + if ind.handle != nil { + C.wickra_autocorrelation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AutocorrelationPeriodogram wraps the AutocorrelationPeriodogram indicator over the Wickra C ABI. +type AutocorrelationPeriodogram struct { + handle *C.struct_AutocorrelationPeriodogram +} + +// NewAutocorrelationPeriodogram constructs a AutocorrelationPeriodogram. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAutocorrelationPeriodogram(minPeriod int, maxPeriod int) (*AutocorrelationPeriodogram, error) { + ptr := C.wickra_autocorrelation_periodogram_new(C.uintptr_t(minPeriod), C.uintptr_t(maxPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AutocorrelationPeriodogram{handle: ptr} + runtime.SetFinalizer(obj, (*AutocorrelationPeriodogram).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AutocorrelationPeriodogram) Update(value float64) float64 { + r := float64(C.wickra_autocorrelation_periodogram_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AutocorrelationPeriodogram) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_autocorrelation_periodogram_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AutocorrelationPeriodogram) Reset() { + C.wickra_autocorrelation_periodogram_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AutocorrelationPeriodogram) Close() { + if ind.handle != nil { + C.wickra_autocorrelation_periodogram_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AverageDailyRange wraps the AverageDailyRange indicator over the Wickra C ABI. +type AverageDailyRange struct { + handle *C.struct_AverageDailyRange +} + +// NewAverageDailyRange constructs a AverageDailyRange. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAverageDailyRange(period int, utcOffsetMinutes int32) (*AverageDailyRange, error) { + ptr := C.wickra_average_daily_range_new(C.uintptr_t(period), C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AverageDailyRange{handle: ptr} + runtime.SetFinalizer(obj, (*AverageDailyRange).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AverageDailyRange) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_average_daily_range_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AverageDailyRange) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_average_daily_range_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AverageDailyRange) Reset() { + C.wickra_average_daily_range_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AverageDailyRange) Close() { + if ind.handle != nil { + C.wickra_average_daily_range_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AverageDrawdown wraps the AverageDrawdown indicator over the Wickra C ABI. +type AverageDrawdown struct { + handle *C.struct_AverageDrawdown +} + +// NewAverageDrawdown constructs a AverageDrawdown. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAverageDrawdown(period int) (*AverageDrawdown, error) { + ptr := C.wickra_average_drawdown_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AverageDrawdown{handle: ptr} + runtime.SetFinalizer(obj, (*AverageDrawdown).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AverageDrawdown) Update(value float64) float64 { + r := float64(C.wickra_average_drawdown_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AverageDrawdown) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_average_drawdown_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AverageDrawdown) Reset() { + C.wickra_average_drawdown_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AverageDrawdown) Close() { + if ind.handle != nil { + C.wickra_average_drawdown_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AvgPrice wraps the AvgPrice indicator over the Wickra C ABI. +type AvgPrice struct { + handle *C.struct_AvgPrice +} + +// NewAvgPrice constructs a AvgPrice. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAvgPrice() (*AvgPrice, error) { + ptr := C.wickra_avg_price_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AvgPrice{handle: ptr} + runtime.SetFinalizer(obj, (*AvgPrice).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AvgPrice) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_avg_price_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AvgPrice) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_avg_price_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AvgPrice) Reset() { + C.wickra_avg_price_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AvgPrice) Close() { + if ind.handle != nil { + C.wickra_avg_price_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AwesomeOscillator wraps the AwesomeOscillator indicator over the Wickra C ABI. +type AwesomeOscillator struct { + handle *C.struct_AwesomeOscillator +} + +// NewAwesomeOscillator constructs a AwesomeOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAwesomeOscillator(fast int, slow int) (*AwesomeOscillator, error) { + ptr := C.wickra_awesome_oscillator_new(C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AwesomeOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*AwesomeOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AwesomeOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_awesome_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AwesomeOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_awesome_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AwesomeOscillator) Reset() { + C.wickra_awesome_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AwesomeOscillator) Close() { + if ind.handle != nil { + C.wickra_awesome_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// AwesomeOscillatorHistogram wraps the AwesomeOscillatorHistogram indicator over the Wickra C ABI. +type AwesomeOscillatorHistogram struct { + handle *C.struct_AwesomeOscillatorHistogram +} + +// NewAwesomeOscillatorHistogram constructs a AwesomeOscillatorHistogram. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewAwesomeOscillatorHistogram(fast int, slow int, smaPeriod int) (*AwesomeOscillatorHistogram, error) { + ptr := C.wickra_awesome_oscillator_histogram_new(C.uintptr_t(fast), C.uintptr_t(slow), C.uintptr_t(smaPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &AwesomeOscillatorHistogram{handle: ptr} + runtime.SetFinalizer(obj, (*AwesomeOscillatorHistogram).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *AwesomeOscillatorHistogram) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_awesome_oscillator_histogram_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *AwesomeOscillatorHistogram) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_awesome_oscillator_histogram_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *AwesomeOscillatorHistogram) Reset() { + C.wickra_awesome_oscillator_histogram_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *AwesomeOscillatorHistogram) Close() { + if ind.handle != nil { + C.wickra_awesome_oscillator_histogram_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BalanceOfPower wraps the BalanceOfPower indicator over the Wickra C ABI. +type BalanceOfPower struct { + handle *C.struct_BalanceOfPower +} + +// NewBalanceOfPower constructs a BalanceOfPower. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBalanceOfPower() (*BalanceOfPower, error) { + ptr := C.wickra_balance_of_power_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BalanceOfPower{handle: ptr} + runtime.SetFinalizer(obj, (*BalanceOfPower).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BalanceOfPower) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_balance_of_power_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BalanceOfPower) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_balance_of_power_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BalanceOfPower) Reset() { + C.wickra_balance_of_power_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BalanceOfPower) Close() { + if ind.handle != nil { + C.wickra_balance_of_power_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BandpassFilter wraps the BandpassFilter indicator over the Wickra C ABI. +type BandpassFilter struct { + handle *C.struct_BandpassFilter +} + +// NewBandpassFilter constructs a BandpassFilter. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBandpassFilter(period int, bandwidth float64) (*BandpassFilter, error) { + ptr := C.wickra_bandpass_filter_new(C.uintptr_t(period), C.double(bandwidth)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BandpassFilter{handle: ptr} + runtime.SetFinalizer(obj, (*BandpassFilter).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BandpassFilter) Update(value float64) float64 { + r := float64(C.wickra_bandpass_filter_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BandpassFilter) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_bandpass_filter_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BandpassFilter) Reset() { + C.wickra_bandpass_filter_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BandpassFilter) Close() { + if ind.handle != nil { + C.wickra_bandpass_filter_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Bat wraps the Bat indicator over the Wickra C ABI. +type Bat struct { + handle *C.struct_Bat +} + +// NewBat constructs a Bat. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBat() (*Bat, error) { + ptr := C.wickra_bat_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Bat{handle: ptr} + runtime.SetFinalizer(obj, (*Bat).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Bat) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_bat_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Bat) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_bat_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Bat) Reset() { + C.wickra_bat_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Bat) Close() { + if ind.handle != nil { + C.wickra_bat_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BeltHold wraps the BeltHold indicator over the Wickra C ABI. +type BeltHold struct { + handle *C.struct_BeltHold +} + +// NewBeltHold constructs a BeltHold. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBeltHold() (*BeltHold, error) { + ptr := C.wickra_belt_hold_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BeltHold{handle: ptr} + runtime.SetFinalizer(obj, (*BeltHold).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BeltHold) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_belt_hold_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BeltHold) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_belt_hold_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BeltHold) Reset() { + C.wickra_belt_hold_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BeltHold) Close() { + if ind.handle != nil { + C.wickra_belt_hold_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Beta wraps the Beta indicator over the Wickra C ABI. +type Beta struct { + handle *C.struct_Beta +} + +// NewBeta constructs a Beta. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBeta(period int) (*Beta, error) { + ptr := C.wickra_beta_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Beta{handle: ptr} + runtime.SetFinalizer(obj, (*Beta).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Beta) Update(x float64, y float64) float64 { + r := float64(C.wickra_beta_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Beta) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_beta_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Beta) Reset() { + C.wickra_beta_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Beta) Close() { + if ind.handle != nil { + C.wickra_beta_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BetaNeutralSpread wraps the BetaNeutralSpread indicator over the Wickra C ABI. +type BetaNeutralSpread struct { + handle *C.struct_BetaNeutralSpread +} + +// NewBetaNeutralSpread constructs a BetaNeutralSpread. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBetaNeutralSpread(period int) (*BetaNeutralSpread, error) { + ptr := C.wickra_beta_neutral_spread_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BetaNeutralSpread{handle: ptr} + runtime.SetFinalizer(obj, (*BetaNeutralSpread).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BetaNeutralSpread) Update(x float64, y float64) float64 { + r := float64(C.wickra_beta_neutral_spread_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BetaNeutralSpread) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_beta_neutral_spread_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BetaNeutralSpread) Reset() { + C.wickra_beta_neutral_spread_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BetaNeutralSpread) Close() { + if ind.handle != nil { + C.wickra_beta_neutral_spread_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BetterVolume wraps the BetterVolume indicator over the Wickra C ABI. +type BetterVolume struct { + handle *C.struct_BetterVolume +} + +// NewBetterVolume constructs a BetterVolume. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBetterVolume(period int) (*BetterVolume, error) { + ptr := C.wickra_better_volume_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BetterVolume{handle: ptr} + runtime.SetFinalizer(obj, (*BetterVolume).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BetterVolume) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_better_volume_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BetterVolume) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_better_volume_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BetterVolume) Reset() { + C.wickra_better_volume_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BetterVolume) Close() { + if ind.handle != nil { + C.wickra_better_volume_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BipowerVariation wraps the BipowerVariation indicator over the Wickra C ABI. +type BipowerVariation struct { + handle *C.struct_BipowerVariation +} + +// NewBipowerVariation constructs a BipowerVariation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBipowerVariation(period int) (*BipowerVariation, error) { + ptr := C.wickra_bipower_variation_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BipowerVariation{handle: ptr} + runtime.SetFinalizer(obj, (*BipowerVariation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BipowerVariation) Update(value float64) float64 { + r := float64(C.wickra_bipower_variation_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BipowerVariation) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_bipower_variation_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BipowerVariation) Reset() { + C.wickra_bipower_variation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BipowerVariation) Close() { + if ind.handle != nil { + C.wickra_bipower_variation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BodySizePct wraps the BodySizePct indicator over the Wickra C ABI. +type BodySizePct struct { + handle *C.struct_BodySizePct +} + +// NewBodySizePct constructs a BodySizePct. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBodySizePct() (*BodySizePct, error) { + ptr := C.wickra_body_size_pct_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BodySizePct{handle: ptr} + runtime.SetFinalizer(obj, (*BodySizePct).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BodySizePct) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_body_size_pct_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BodySizePct) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_body_size_pct_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BodySizePct) Reset() { + C.wickra_body_size_pct_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BodySizePct) Close() { + if ind.handle != nil { + C.wickra_body_size_pct_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BollingerBands wraps the BollingerBands indicator over the Wickra C ABI. +type BollingerBands struct { + handle *C.struct_BollingerBands +} + +// NewBollingerBands constructs a BollingerBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBollingerBands(period int, multiplier float64) (*BollingerBands, error) { + ptr := C.wickra_bollinger_bands_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BollingerBands{handle: ptr} + runtime.SetFinalizer(obj, (*BollingerBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *BollingerBands) Update(value float64) (BollingerOutput, bool) { + var out C.struct_WickraBollingerOutput + ok := bool(C.wickra_bollinger_bands_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return BollingerOutput{}, false + } + return BollingerOutput{float64(out.upper), float64(out.middle), float64(out.lower), float64(out.stddev)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BollingerBands) Reset() { + C.wickra_bollinger_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BollingerBands) Close() { + if ind.handle != nil { + C.wickra_bollinger_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BollingerBandwidth wraps the BollingerBandwidth indicator over the Wickra C ABI. +type BollingerBandwidth struct { + handle *C.struct_BollingerBandwidth +} + +// NewBollingerBandwidth constructs a BollingerBandwidth. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBollingerBandwidth(period int, multiplier float64) (*BollingerBandwidth, error) { + ptr := C.wickra_bollinger_bandwidth_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BollingerBandwidth{handle: ptr} + runtime.SetFinalizer(obj, (*BollingerBandwidth).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BollingerBandwidth) Update(value float64) float64 { + r := float64(C.wickra_bollinger_bandwidth_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BollingerBandwidth) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_bollinger_bandwidth_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BollingerBandwidth) Reset() { + C.wickra_bollinger_bandwidth_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BollingerBandwidth) Close() { + if ind.handle != nil { + C.wickra_bollinger_bandwidth_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BomarBands wraps the BomarBands indicator over the Wickra C ABI. +type BomarBands struct { + handle *C.struct_BomarBands +} + +// NewBomarBands constructs a BomarBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBomarBands(period int, coverage float64) (*BomarBands, error) { + ptr := C.wickra_bomar_bands_new(C.uintptr_t(period), C.double(coverage)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BomarBands{handle: ptr} + runtime.SetFinalizer(obj, (*BomarBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *BomarBands) Update(value float64) (BomarBandsOutput, bool) { + var out C.struct_WickraBomarBandsOutput + ok := bool(C.wickra_bomar_bands_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return BomarBandsOutput{}, false + } + return BomarBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BomarBands) Reset() { + C.wickra_bomar_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BomarBands) Close() { + if ind.handle != nil { + C.wickra_bomar_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BreadthThrust wraps the BreadthThrust indicator over the Wickra C ABI. +type BreadthThrust struct { + handle *C.struct_BreadthThrust +} + +// NewBreadthThrust constructs a BreadthThrust. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBreadthThrust(period int) (*BreadthThrust, error) { + ptr := C.wickra_breadth_thrust_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BreadthThrust{handle: ptr} + runtime.SetFinalizer(obj, (*BreadthThrust).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *BreadthThrust) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_breadth_thrust_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BreadthThrust) Reset() { + C.wickra_breadth_thrust_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BreadthThrust) Close() { + if ind.handle != nil { + C.wickra_breadth_thrust_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Breakaway wraps the Breakaway indicator over the Wickra C ABI. +type Breakaway struct { + handle *C.struct_Breakaway +} + +// NewBreakaway constructs a Breakaway. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBreakaway() (*Breakaway, error) { + ptr := C.wickra_breakaway_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Breakaway{handle: ptr} + runtime.SetFinalizer(obj, (*Breakaway).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Breakaway) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_breakaway_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Breakaway) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_breakaway_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Breakaway) Reset() { + C.wickra_breakaway_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Breakaway) Close() { + if ind.handle != nil { + C.wickra_breakaway_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BullishPercentIndex wraps the BullishPercentIndex indicator over the Wickra C ABI. +type BullishPercentIndex struct { + handle *C.struct_BullishPercentIndex +} + +// NewBullishPercentIndex constructs a BullishPercentIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBullishPercentIndex() (*BullishPercentIndex, error) { + ptr := C.wickra_bullish_percent_index_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BullishPercentIndex{handle: ptr} + runtime.SetFinalizer(obj, (*BullishPercentIndex).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *BullishPercentIndex) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_bullish_percent_index_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BullishPercentIndex) Reset() { + C.wickra_bullish_percent_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BullishPercentIndex) Close() { + if ind.handle != nil { + C.wickra_bullish_percent_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// BurkeRatio wraps the BurkeRatio indicator over the Wickra C ABI. +type BurkeRatio struct { + handle *C.struct_BurkeRatio +} + +// NewBurkeRatio constructs a BurkeRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewBurkeRatio(period int) (*BurkeRatio, error) { + ptr := C.wickra_burke_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &BurkeRatio{handle: ptr} + runtime.SetFinalizer(obj, (*BurkeRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *BurkeRatio) Update(value float64) float64 { + r := float64(C.wickra_burke_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *BurkeRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_burke_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *BurkeRatio) Reset() { + C.wickra_burke_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *BurkeRatio) Close() { + if ind.handle != nil { + C.wickra_burke_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Butterfly wraps the Butterfly indicator over the Wickra C ABI. +type Butterfly struct { + handle *C.struct_Butterfly +} + +// NewButterfly constructs a Butterfly. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewButterfly() (*Butterfly, error) { + ptr := C.wickra_butterfly_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Butterfly{handle: ptr} + runtime.SetFinalizer(obj, (*Butterfly).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Butterfly) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_butterfly_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Butterfly) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_butterfly_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Butterfly) Reset() { + C.wickra_butterfly_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Butterfly) Close() { + if ind.handle != nil { + C.wickra_butterfly_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CalendarSpread wraps the CalendarSpread indicator over the Wickra C ABI. +type CalendarSpread struct { + handle *C.struct_CalendarSpread +} + +// NewCalendarSpread constructs a CalendarSpread. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCalendarSpread() (*CalendarSpread, error) { + ptr := C.wickra_calendar_spread_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CalendarSpread{handle: ptr} + runtime.SetFinalizer(obj, (*CalendarSpread).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CalendarSpread) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_calendar_spread_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CalendarSpread) Reset() { + C.wickra_calendar_spread_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CalendarSpread) Close() { + if ind.handle != nil { + C.wickra_calendar_spread_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CalmarRatio wraps the CalmarRatio indicator over the Wickra C ABI. +type CalmarRatio struct { + handle *C.struct_CalmarRatio +} + +// NewCalmarRatio constructs a CalmarRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCalmarRatio(period int) (*CalmarRatio, error) { + ptr := C.wickra_calmar_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CalmarRatio{handle: ptr} + runtime.SetFinalizer(obj, (*CalmarRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CalmarRatio) Update(value float64) float64 { + r := float64(C.wickra_calmar_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CalmarRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_calmar_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CalmarRatio) Reset() { + C.wickra_calmar_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CalmarRatio) Close() { + if ind.handle != nil { + C.wickra_calmar_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Camarilla wraps the Camarilla indicator over the Wickra C ABI. +type Camarilla struct { + handle *C.struct_Camarilla +} + +// NewCamarilla constructs a Camarilla. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCamarilla() (*Camarilla, error) { + ptr := C.wickra_camarilla_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Camarilla{handle: ptr} + runtime.SetFinalizer(obj, (*Camarilla).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Camarilla) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (CamarillaPivotsOutput, bool) { + var out C.struct_WickraCamarillaPivotsOutput + ok := bool(C.wickra_camarilla_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return CamarillaPivotsOutput{}, false + } + return CamarillaPivotsOutput{float64(out.pp), float64(out.r1), float64(out.r2), float64(out.r3), float64(out.r4), float64(out.s1), float64(out.s2), float64(out.s3), float64(out.s4)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Camarilla) Reset() { + C.wickra_camarilla_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Camarilla) Close() { + if ind.handle != nil { + C.wickra_camarilla_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CandleVolume wraps the CandleVolume indicator over the Wickra C ABI. +type CandleVolume struct { + handle *C.struct_CandleVolume +} + +// NewCandleVolume constructs a CandleVolume. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCandleVolume(period int) (*CandleVolume, error) { + ptr := C.wickra_candle_volume_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CandleVolume{handle: ptr} + runtime.SetFinalizer(obj, (*CandleVolume).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *CandleVolume) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (CandleVolumeOutput, bool) { + var out C.struct_WickraCandleVolumeOutput + ok := bool(C.wickra_candle_volume_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return CandleVolumeOutput{}, false + } + return CandleVolumeOutput{float64(out.body), float64(out.width)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CandleVolume) Reset() { + C.wickra_candle_volume_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CandleVolume) Close() { + if ind.handle != nil { + C.wickra_candle_volume_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Cci wraps the Cci indicator over the Wickra C ABI. +type Cci struct { + handle *C.struct_Cci +} + +// NewCci constructs a Cci. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCci(period int) (*Cci, error) { + ptr := C.wickra_cci_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Cci{handle: ptr} + runtime.SetFinalizer(obj, (*Cci).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Cci) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_cci_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Cci) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_cci_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Cci) Reset() { + C.wickra_cci_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Cci) Close() { + if ind.handle != nil { + C.wickra_cci_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CenterOfGravity wraps the CenterOfGravity indicator over the Wickra C ABI. +type CenterOfGravity struct { + handle *C.struct_CenterOfGravity +} + +// NewCenterOfGravity constructs a CenterOfGravity. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCenterOfGravity(period int) (*CenterOfGravity, error) { + ptr := C.wickra_center_of_gravity_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CenterOfGravity{handle: ptr} + runtime.SetFinalizer(obj, (*CenterOfGravity).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CenterOfGravity) Update(value float64) float64 { + r := float64(C.wickra_center_of_gravity_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CenterOfGravity) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_center_of_gravity_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CenterOfGravity) Reset() { + C.wickra_center_of_gravity_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CenterOfGravity) Close() { + if ind.handle != nil { + C.wickra_center_of_gravity_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CentralPivotRange wraps the CentralPivotRange indicator over the Wickra C ABI. +type CentralPivotRange struct { + handle *C.struct_CentralPivotRange +} + +// NewCentralPivotRange constructs a CentralPivotRange. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCentralPivotRange() (*CentralPivotRange, error) { + ptr := C.wickra_central_pivot_range_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CentralPivotRange{handle: ptr} + runtime.SetFinalizer(obj, (*CentralPivotRange).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *CentralPivotRange) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (CentralPivotRangeOutput, bool) { + var out C.struct_WickraCentralPivotRangeOutput + ok := bool(C.wickra_central_pivot_range_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return CentralPivotRangeOutput{}, false + } + return CentralPivotRangeOutput{float64(out.pivot), float64(out.tc), float64(out.bc)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CentralPivotRange) Reset() { + C.wickra_central_pivot_range_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CentralPivotRange) Close() { + if ind.handle != nil { + C.wickra_central_pivot_range_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Cfo wraps the Cfo indicator over the Wickra C ABI. +type Cfo struct { + handle *C.struct_Cfo +} + +// NewCfo constructs a Cfo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCfo(period int) (*Cfo, error) { + ptr := C.wickra_cfo_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Cfo{handle: ptr} + runtime.SetFinalizer(obj, (*Cfo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Cfo) Update(value float64) float64 { + r := float64(C.wickra_cfo_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Cfo) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_cfo_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Cfo) Reset() { + C.wickra_cfo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Cfo) Close() { + if ind.handle != nil { + C.wickra_cfo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ChaikinMoneyFlow wraps the ChaikinMoneyFlow indicator over the Wickra C ABI. +type ChaikinMoneyFlow struct { + handle *C.struct_ChaikinMoneyFlow +} + +// NewChaikinMoneyFlow constructs a ChaikinMoneyFlow. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewChaikinMoneyFlow(period int) (*ChaikinMoneyFlow, error) { + ptr := C.wickra_chaikin_money_flow_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ChaikinMoneyFlow{handle: ptr} + runtime.SetFinalizer(obj, (*ChaikinMoneyFlow).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ChaikinMoneyFlow) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_chaikin_money_flow_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ChaikinMoneyFlow) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_chaikin_money_flow_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ChaikinMoneyFlow) Reset() { + C.wickra_chaikin_money_flow_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ChaikinMoneyFlow) Close() { + if ind.handle != nil { + C.wickra_chaikin_money_flow_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ChaikinOscillator wraps the ChaikinOscillator indicator over the Wickra C ABI. +type ChaikinOscillator struct { + handle *C.struct_ChaikinOscillator +} + +// NewChaikinOscillator constructs a ChaikinOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewChaikinOscillator(fast int, slow int) (*ChaikinOscillator, error) { + ptr := C.wickra_chaikin_oscillator_new(C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ChaikinOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*ChaikinOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ChaikinOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_chaikin_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ChaikinOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_chaikin_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ChaikinOscillator) Reset() { + C.wickra_chaikin_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ChaikinOscillator) Close() { + if ind.handle != nil { + C.wickra_chaikin_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ChaikinVolatility wraps the ChaikinVolatility indicator over the Wickra C ABI. +type ChaikinVolatility struct { + handle *C.struct_ChaikinVolatility +} + +// NewChaikinVolatility constructs a ChaikinVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewChaikinVolatility(emaPeriod int, rocPeriod int) (*ChaikinVolatility, error) { + ptr := C.wickra_chaikin_volatility_new(C.uintptr_t(emaPeriod), C.uintptr_t(rocPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ChaikinVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*ChaikinVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ChaikinVolatility) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_chaikin_volatility_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ChaikinVolatility) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_chaikin_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ChaikinVolatility) Reset() { + C.wickra_chaikin_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ChaikinVolatility) Close() { + if ind.handle != nil { + C.wickra_chaikin_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ChandeKrollStop wraps the ChandeKrollStop indicator over the Wickra C ABI. +type ChandeKrollStop struct { + handle *C.struct_ChandeKrollStop +} + +// NewChandeKrollStop constructs a ChandeKrollStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewChandeKrollStop(atrPeriod int, atrMultiplier float64, stopPeriod int) (*ChandeKrollStop, error) { + ptr := C.wickra_chande_kroll_stop_new(C.uintptr_t(atrPeriod), C.double(atrMultiplier), C.uintptr_t(stopPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ChandeKrollStop{handle: ptr} + runtime.SetFinalizer(obj, (*ChandeKrollStop).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ChandeKrollStop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ChandeKrollStopOutput, bool) { + var out C.struct_WickraChandeKrollStopOutput + ok := bool(C.wickra_chande_kroll_stop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ChandeKrollStopOutput{}, false + } + return ChandeKrollStopOutput{float64(out.stop_long), float64(out.stop_short)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ChandeKrollStop) Reset() { + C.wickra_chande_kroll_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ChandeKrollStop) Close() { + if ind.handle != nil { + C.wickra_chande_kroll_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ChandelierExit wraps the ChandelierExit indicator over the Wickra C ABI. +type ChandelierExit struct { + handle *C.struct_ChandelierExit +} + +// NewChandelierExit constructs a ChandelierExit. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewChandelierExit(period int, multiplier float64) (*ChandelierExit, error) { + ptr := C.wickra_chandelier_exit_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ChandelierExit{handle: ptr} + runtime.SetFinalizer(obj, (*ChandelierExit).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ChandelierExit) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ChandelierExitOutput, bool) { + var out C.struct_WickraChandelierExitOutput + ok := bool(C.wickra_chandelier_exit_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ChandelierExitOutput{}, false + } + return ChandelierExitOutput{float64(out.long_stop), float64(out.short_stop)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ChandelierExit) Reset() { + C.wickra_chandelier_exit_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ChandelierExit) Close() { + if ind.handle != nil { + C.wickra_chandelier_exit_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ChoppinessIndex wraps the ChoppinessIndex indicator over the Wickra C ABI. +type ChoppinessIndex struct { + handle *C.struct_ChoppinessIndex +} + +// NewChoppinessIndex constructs a ChoppinessIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewChoppinessIndex(period int) (*ChoppinessIndex, error) { + ptr := C.wickra_choppiness_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ChoppinessIndex{handle: ptr} + runtime.SetFinalizer(obj, (*ChoppinessIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ChoppinessIndex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_choppiness_index_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ChoppinessIndex) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_choppiness_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ChoppinessIndex) Reset() { + C.wickra_choppiness_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ChoppinessIndex) Close() { + if ind.handle != nil { + C.wickra_choppiness_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ClassicPivots wraps the ClassicPivots indicator over the Wickra C ABI. +type ClassicPivots struct { + handle *C.struct_ClassicPivots +} + +// NewClassicPivots constructs a ClassicPivots. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewClassicPivots() (*ClassicPivots, error) { + ptr := C.wickra_classic_pivots_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ClassicPivots{handle: ptr} + runtime.SetFinalizer(obj, (*ClassicPivots).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ClassicPivots) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ClassicPivotsOutput, bool) { + var out C.struct_WickraClassicPivotsOutput + ok := bool(C.wickra_classic_pivots_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ClassicPivotsOutput{}, false + } + return ClassicPivotsOutput{float64(out.pp), float64(out.r1), float64(out.r2), float64(out.r3), float64(out.s1), float64(out.s2), float64(out.s3)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ClassicPivots) Reset() { + C.wickra_classic_pivots_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ClassicPivots) Close() { + if ind.handle != nil { + C.wickra_classic_pivots_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CloseVsOpen wraps the CloseVsOpen indicator over the Wickra C ABI. +type CloseVsOpen struct { + handle *C.struct_CloseVsOpen +} + +// NewCloseVsOpen constructs a CloseVsOpen. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCloseVsOpen() (*CloseVsOpen, error) { + ptr := C.wickra_close_vs_open_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CloseVsOpen{handle: ptr} + runtime.SetFinalizer(obj, (*CloseVsOpen).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CloseVsOpen) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_close_vs_open_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CloseVsOpen) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_close_vs_open_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CloseVsOpen) Reset() { + C.wickra_close_vs_open_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CloseVsOpen) Close() { + if ind.handle != nil { + C.wickra_close_vs_open_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ClosingMarubozu wraps the ClosingMarubozu indicator over the Wickra C ABI. +type ClosingMarubozu struct { + handle *C.struct_ClosingMarubozu +} + +// NewClosingMarubozu constructs a ClosingMarubozu. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewClosingMarubozu() (*ClosingMarubozu, error) { + ptr := C.wickra_closing_marubozu_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ClosingMarubozu{handle: ptr} + runtime.SetFinalizer(obj, (*ClosingMarubozu).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ClosingMarubozu) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_closing_marubozu_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ClosingMarubozu) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_closing_marubozu_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ClosingMarubozu) Reset() { + C.wickra_closing_marubozu_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ClosingMarubozu) Close() { + if ind.handle != nil { + C.wickra_closing_marubozu_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Cmo wraps the Cmo indicator over the Wickra C ABI. +type Cmo struct { + handle *C.struct_Cmo +} + +// NewCmo constructs a Cmo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCmo(period int) (*Cmo, error) { + ptr := C.wickra_cmo_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Cmo{handle: ptr} + runtime.SetFinalizer(obj, (*Cmo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Cmo) Update(value float64) float64 { + r := float64(C.wickra_cmo_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Cmo) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_cmo_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Cmo) Reset() { + C.wickra_cmo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Cmo) Close() { + if ind.handle != nil { + C.wickra_cmo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CoefficientOfVariation wraps the CoefficientOfVariation indicator over the Wickra C ABI. +type CoefficientOfVariation struct { + handle *C.struct_CoefficientOfVariation +} + +// NewCoefficientOfVariation constructs a CoefficientOfVariation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCoefficientOfVariation(period int) (*CoefficientOfVariation, error) { + ptr := C.wickra_coefficient_of_variation_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CoefficientOfVariation{handle: ptr} + runtime.SetFinalizer(obj, (*CoefficientOfVariation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CoefficientOfVariation) Update(value float64) float64 { + r := float64(C.wickra_coefficient_of_variation_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CoefficientOfVariation) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_coefficient_of_variation_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CoefficientOfVariation) Reset() { + C.wickra_coefficient_of_variation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CoefficientOfVariation) Close() { + if ind.handle != nil { + C.wickra_coefficient_of_variation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Cointegration wraps the Cointegration indicator over the Wickra C ABI. +type Cointegration struct { + handle *C.struct_Cointegration +} + +// NewCointegration constructs a Cointegration. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCointegration(period int, adfLags int) (*Cointegration, error) { + ptr := C.wickra_cointegration_new(C.uintptr_t(period), C.uintptr_t(adfLags)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Cointegration{handle: ptr} + runtime.SetFinalizer(obj, (*Cointegration).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Cointegration) Update(x float64, y float64) (CointegrationOutput, bool) { + var out C.struct_WickraCointegrationOutput + ok := bool(C.wickra_cointegration_update(ind.handle, C.double(x), C.double(y), &out)) + runtime.KeepAlive(ind) + if !ok { + return CointegrationOutput{}, false + } + return CointegrationOutput{float64(out.hedge_ratio), float64(out.spread), float64(out.adf_stat)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Cointegration) Reset() { + C.wickra_cointegration_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Cointegration) Close() { + if ind.handle != nil { + C.wickra_cointegration_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CommonSenseRatio wraps the CommonSenseRatio indicator over the Wickra C ABI. +type CommonSenseRatio struct { + handle *C.struct_CommonSenseRatio +} + +// NewCommonSenseRatio constructs a CommonSenseRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCommonSenseRatio(period int) (*CommonSenseRatio, error) { + ptr := C.wickra_common_sense_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CommonSenseRatio{handle: ptr} + runtime.SetFinalizer(obj, (*CommonSenseRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CommonSenseRatio) Update(value float64) float64 { + r := float64(C.wickra_common_sense_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CommonSenseRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_common_sense_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CommonSenseRatio) Reset() { + C.wickra_common_sense_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CommonSenseRatio) Close() { + if ind.handle != nil { + C.wickra_common_sense_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CompositeProfile wraps the CompositeProfile indicator over the Wickra C ABI. +type CompositeProfile struct { + handle *C.struct_CompositeProfile +} + +// NewCompositeProfile constructs a CompositeProfile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCompositeProfile(period int, bins int, valueAreaPct float64) (*CompositeProfile, error) { + ptr := C.wickra_composite_profile_new(C.uintptr_t(period), C.uintptr_t(bins), C.double(valueAreaPct)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CompositeProfile{handle: ptr} + runtime.SetFinalizer(obj, (*CompositeProfile).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *CompositeProfile) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (CompositeProfileOutput, bool) { + var out C.struct_WickraCompositeProfileOutput + ok := bool(C.wickra_composite_profile_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return CompositeProfileOutput{}, false + } + return CompositeProfileOutput{float64(out.poc), float64(out.vah), float64(out.val)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CompositeProfile) Reset() { + C.wickra_composite_profile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CompositeProfile) Close() { + if ind.handle != nil { + C.wickra_composite_profile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ConcealingBabySwallow wraps the ConcealingBabySwallow indicator over the Wickra C ABI. +type ConcealingBabySwallow struct { + handle *C.struct_ConcealingBabySwallow +} + +// NewConcealingBabySwallow constructs a ConcealingBabySwallow. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewConcealingBabySwallow() (*ConcealingBabySwallow, error) { + ptr := C.wickra_concealing_baby_swallow_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ConcealingBabySwallow{handle: ptr} + runtime.SetFinalizer(obj, (*ConcealingBabySwallow).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ConcealingBabySwallow) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_concealing_baby_swallow_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ConcealingBabySwallow) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_concealing_baby_swallow_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ConcealingBabySwallow) Reset() { + C.wickra_concealing_baby_swallow_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ConcealingBabySwallow) Close() { + if ind.handle != nil { + C.wickra_concealing_baby_swallow_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ConditionalValueAtRisk wraps the ConditionalValueAtRisk indicator over the Wickra C ABI. +type ConditionalValueAtRisk struct { + handle *C.struct_ConditionalValueAtRisk +} + +// NewConditionalValueAtRisk constructs a ConditionalValueAtRisk. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewConditionalValueAtRisk(period int, confidence float64) (*ConditionalValueAtRisk, error) { + ptr := C.wickra_conditional_value_at_risk_new(C.uintptr_t(period), C.double(confidence)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ConditionalValueAtRisk{handle: ptr} + runtime.SetFinalizer(obj, (*ConditionalValueAtRisk).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ConditionalValueAtRisk) Update(value float64) float64 { + r := float64(C.wickra_conditional_value_at_risk_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ConditionalValueAtRisk) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_conditional_value_at_risk_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ConditionalValueAtRisk) Reset() { + C.wickra_conditional_value_at_risk_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ConditionalValueAtRisk) Close() { + if ind.handle != nil { + C.wickra_conditional_value_at_risk_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ConnorsRsi wraps the ConnorsRsi indicator over the Wickra C ABI. +type ConnorsRsi struct { + handle *C.struct_ConnorsRsi +} + +// NewConnorsRsi constructs a ConnorsRsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewConnorsRsi(periodRsi int, periodStreak int, periodRank int) (*ConnorsRsi, error) { + ptr := C.wickra_connors_rsi_new(C.uintptr_t(periodRsi), C.uintptr_t(periodStreak), C.uintptr_t(periodRank)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ConnorsRsi{handle: ptr} + runtime.SetFinalizer(obj, (*ConnorsRsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ConnorsRsi) Update(value float64) float64 { + r := float64(C.wickra_connors_rsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ConnorsRsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_connors_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ConnorsRsi) Reset() { + C.wickra_connors_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ConnorsRsi) Close() { + if ind.handle != nil { + C.wickra_connors_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Coppock wraps the Coppock indicator over the Wickra C ABI. +type Coppock struct { + handle *C.struct_Coppock +} + +// NewCoppock constructs a Coppock. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCoppock(rocLongPeriod int, rocShortPeriod int, wmaPeriod int) (*Coppock, error) { + ptr := C.wickra_coppock_new(C.uintptr_t(rocLongPeriod), C.uintptr_t(rocShortPeriod), C.uintptr_t(wmaPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Coppock{handle: ptr} + runtime.SetFinalizer(obj, (*Coppock).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Coppock) Update(value float64) float64 { + r := float64(C.wickra_coppock_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Coppock) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_coppock_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Coppock) Reset() { + C.wickra_coppock_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Coppock) Close() { + if ind.handle != nil { + C.wickra_coppock_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CorrelationTrendIndicator wraps the CorrelationTrendIndicator indicator over the Wickra C ABI. +type CorrelationTrendIndicator struct { + handle *C.struct_CorrelationTrendIndicator +} + +// NewCorrelationTrendIndicator constructs a CorrelationTrendIndicator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCorrelationTrendIndicator(period int) (*CorrelationTrendIndicator, error) { + ptr := C.wickra_correlation_trend_indicator_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CorrelationTrendIndicator{handle: ptr} + runtime.SetFinalizer(obj, (*CorrelationTrendIndicator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CorrelationTrendIndicator) Update(value float64) float64 { + r := float64(C.wickra_correlation_trend_indicator_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CorrelationTrendIndicator) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_correlation_trend_indicator_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CorrelationTrendIndicator) Reset() { + C.wickra_correlation_trend_indicator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CorrelationTrendIndicator) Close() { + if ind.handle != nil { + C.wickra_correlation_trend_indicator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Counterattack wraps the Counterattack indicator over the Wickra C ABI. +type Counterattack struct { + handle *C.struct_Counterattack +} + +// NewCounterattack constructs a Counterattack. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCounterattack() (*Counterattack, error) { + ptr := C.wickra_counterattack_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Counterattack{handle: ptr} + runtime.SetFinalizer(obj, (*Counterattack).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Counterattack) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_counterattack_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Counterattack) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_counterattack_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Counterattack) Reset() { + C.wickra_counterattack_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Counterattack) Close() { + if ind.handle != nil { + C.wickra_counterattack_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Crab wraps the Crab indicator over the Wickra C ABI. +type Crab struct { + handle *C.struct_Crab +} + +// NewCrab constructs a Crab. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCrab() (*Crab, error) { + ptr := C.wickra_crab_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Crab{handle: ptr} + runtime.SetFinalizer(obj, (*Crab).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Crab) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_crab_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Crab) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_crab_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Crab) Reset() { + C.wickra_crab_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Crab) Close() { + if ind.handle != nil { + C.wickra_crab_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CumulativeVolumeDelta wraps the CumulativeVolumeDelta indicator over the Wickra C ABI. +type CumulativeVolumeDelta struct { + handle *C.struct_CumulativeVolumeDelta +} + +// NewCumulativeVolumeDelta constructs a CumulativeVolumeDelta. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCumulativeVolumeDelta() (*CumulativeVolumeDelta, error) { + ptr := C.wickra_cumulative_volume_delta_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CumulativeVolumeDelta{handle: ptr} + runtime.SetFinalizer(obj, (*CumulativeVolumeDelta).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CumulativeVolumeDelta) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_cumulative_volume_delta_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CumulativeVolumeDelta) Reset() { + C.wickra_cumulative_volume_delta_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CumulativeVolumeDelta) Close() { + if ind.handle != nil { + C.wickra_cumulative_volume_delta_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CumulativeVolumeIndex wraps the CumulativeVolumeIndex indicator over the Wickra C ABI. +type CumulativeVolumeIndex struct { + handle *C.struct_CumulativeVolumeIndex +} + +// NewCumulativeVolumeIndex constructs a CumulativeVolumeIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCumulativeVolumeIndex() (*CumulativeVolumeIndex, error) { + ptr := C.wickra_cumulative_volume_index_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CumulativeVolumeIndex{handle: ptr} + runtime.SetFinalizer(obj, (*CumulativeVolumeIndex).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *CumulativeVolumeIndex) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_cumulative_volume_index_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CumulativeVolumeIndex) Reset() { + C.wickra_cumulative_volume_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CumulativeVolumeIndex) Close() { + if ind.handle != nil { + C.wickra_cumulative_volume_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CupAndHandle wraps the CupAndHandle indicator over the Wickra C ABI. +type CupAndHandle struct { + handle *C.struct_CupAndHandle +} + +// NewCupAndHandle constructs a CupAndHandle. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCupAndHandle() (*CupAndHandle, error) { + ptr := C.wickra_cup_and_handle_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CupAndHandle{handle: ptr} + runtime.SetFinalizer(obj, (*CupAndHandle).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CupAndHandle) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_cup_and_handle_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CupAndHandle) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_cup_and_handle_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CupAndHandle) Reset() { + C.wickra_cup_and_handle_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CupAndHandle) Close() { + if ind.handle != nil { + C.wickra_cup_and_handle_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// CyberneticCycle wraps the CyberneticCycle indicator over the Wickra C ABI. +type CyberneticCycle struct { + handle *C.struct_CyberneticCycle +} + +// NewCyberneticCycle constructs a CyberneticCycle. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCyberneticCycle(period int) (*CyberneticCycle, error) { + ptr := C.wickra_cybernetic_cycle_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &CyberneticCycle{handle: ptr} + runtime.SetFinalizer(obj, (*CyberneticCycle).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *CyberneticCycle) Update(value float64) float64 { + r := float64(C.wickra_cybernetic_cycle_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *CyberneticCycle) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_cybernetic_cycle_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *CyberneticCycle) Reset() { + C.wickra_cybernetic_cycle_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *CyberneticCycle) Close() { + if ind.handle != nil { + C.wickra_cybernetic_cycle_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Cypher wraps the Cypher indicator over the Wickra C ABI. +type Cypher struct { + handle *C.struct_Cypher +} + +// NewCypher constructs a Cypher. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewCypher() (*Cypher, error) { + ptr := C.wickra_cypher_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Cypher{handle: ptr} + runtime.SetFinalizer(obj, (*Cypher).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Cypher) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_cypher_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Cypher) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_cypher_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Cypher) Reset() { + C.wickra_cypher_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Cypher) Close() { + if ind.handle != nil { + C.wickra_cypher_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DayOfWeekProfile wraps the DayOfWeekProfile indicator over the Wickra C ABI. +type DayOfWeekProfile struct { + handle *C.struct_DayOfWeekProfile + valuesCap int +} + +// NewDayOfWeekProfile constructs a DayOfWeekProfile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDayOfWeekProfile(utcOffsetMinutes int32) (*DayOfWeekProfile, error) { + ptr := C.wickra_day_of_week_profile_new(C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DayOfWeekProfile{handle: ptr} + obj.valuesCap = 4096 + runtime.SetFinalizer(obj, (*DayOfWeekProfile).Close) + return obj, nil +} + +// Update feeds one observation and returns the profile values +// (ok is false during warmup). +func (ind *DayOfWeekProfile) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) ([]float64, bool) { + values := make([]float64, ind.valuesCap) + n := int(C.wickra_day_of_week_profile_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), (*C.double)(unsafe.Pointer(&values[0])), C.uintptr_t(len(values)))) + runtime.KeepAlive(ind) + if n < 0 { + return nil, false + } + return values[:n], true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DayOfWeekProfile) Reset() { + C.wickra_day_of_week_profile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DayOfWeekProfile) Close() { + if ind.handle != nil { + C.wickra_day_of_week_profile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Decycler wraps the Decycler indicator over the Wickra C ABI. +type Decycler struct { + handle *C.struct_Decycler +} + +// NewDecycler constructs a Decycler. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDecycler(period int) (*Decycler, error) { + ptr := C.wickra_decycler_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Decycler{handle: ptr} + runtime.SetFinalizer(obj, (*Decycler).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Decycler) Update(value float64) float64 { + r := float64(C.wickra_decycler_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Decycler) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_decycler_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Decycler) Reset() { + C.wickra_decycler_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Decycler) Close() { + if ind.handle != nil { + C.wickra_decycler_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DecyclerOscillator wraps the DecyclerOscillator indicator over the Wickra C ABI. +type DecyclerOscillator struct { + handle *C.struct_DecyclerOscillator +} + +// NewDecyclerOscillator constructs a DecyclerOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDecyclerOscillator(fast int, slow int) (*DecyclerOscillator, error) { + ptr := C.wickra_decycler_oscillator_new(C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DecyclerOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*DecyclerOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DecyclerOscillator) Update(value float64) float64 { + r := float64(C.wickra_decycler_oscillator_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DecyclerOscillator) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_decycler_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DecyclerOscillator) Reset() { + C.wickra_decycler_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DecyclerOscillator) Close() { + if ind.handle != nil { + C.wickra_decycler_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Dema wraps the Dema indicator over the Wickra C ABI. +type Dema struct { + handle *C.struct_Dema +} + +// NewDema constructs a Dema. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDema(period int) (*Dema, error) { + ptr := C.wickra_dema_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Dema{handle: ptr} + runtime.SetFinalizer(obj, (*Dema).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Dema) Update(value float64) float64 { + r := float64(C.wickra_dema_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Dema) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_dema_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Dema) Reset() { + C.wickra_dema_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Dema) Close() { + if ind.handle != nil { + C.wickra_dema_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DemandIndex wraps the DemandIndex indicator over the Wickra C ABI. +type DemandIndex struct { + handle *C.struct_DemandIndex +} + +// NewDemandIndex constructs a DemandIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDemandIndex(period int) (*DemandIndex, error) { + ptr := C.wickra_demand_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DemandIndex{handle: ptr} + runtime.SetFinalizer(obj, (*DemandIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DemandIndex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_demand_index_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DemandIndex) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_demand_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DemandIndex) Reset() { + C.wickra_demand_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DemandIndex) Close() { + if ind.handle != nil { + C.wickra_demand_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DemarkPivots wraps the DemarkPivots indicator over the Wickra C ABI. +type DemarkPivots struct { + handle *C.struct_DemarkPivots +} + +// NewDemarkPivots constructs a DemarkPivots. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDemarkPivots() (*DemarkPivots, error) { + ptr := C.wickra_demark_pivots_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DemarkPivots{handle: ptr} + runtime.SetFinalizer(obj, (*DemarkPivots).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *DemarkPivots) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (DemarkPivotsOutput, bool) { + var out C.struct_WickraDemarkPivotsOutput + ok := bool(C.wickra_demark_pivots_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return DemarkPivotsOutput{}, false + } + return DemarkPivotsOutput{float64(out.pp), float64(out.r1), float64(out.s1)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DemarkPivots) Reset() { + C.wickra_demark_pivots_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DemarkPivots) Close() { + if ind.handle != nil { + C.wickra_demark_pivots_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DepthSlope wraps the DepthSlope indicator over the Wickra C ABI. +type DepthSlope struct { + handle *C.struct_DepthSlope +} + +// NewDepthSlope constructs a DepthSlope. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDepthSlope() (*DepthSlope, error) { + ptr := C.wickra_depth_slope_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DepthSlope{handle: ptr} + runtime.SetFinalizer(obj, (*DepthSlope).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *DepthSlope) Update(bidPrice []float64, bidSize []float64, askPrice []float64, askSize []float64) float64 { + if len(bidSize) != len(bidPrice) { + panic("wickra: input slices in the same group must have equal length") + } + if len(askSize) != len(askPrice) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_depth_slope_update(ind.handle, (*C.double)(unsafe.Pointer(&bidPrice[0])), (*C.double)(unsafe.Pointer(&bidSize[0])), C.uintptr_t(len(bidPrice)), (*C.double)(unsafe.Pointer(&askPrice[0])), (*C.double)(unsafe.Pointer(&askSize[0])), C.uintptr_t(len(askPrice)))) + runtime.KeepAlive(ind) + runtime.KeepAlive(bidPrice) + runtime.KeepAlive(bidSize) + runtime.KeepAlive(askPrice) + runtime.KeepAlive(askSize) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DepthSlope) Reset() { + C.wickra_depth_slope_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DepthSlope) Close() { + if ind.handle != nil { + C.wickra_depth_slope_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DerivativeOscillator wraps the DerivativeOscillator indicator over the Wickra C ABI. +type DerivativeOscillator struct { + handle *C.struct_DerivativeOscillator +} + +// NewDerivativeOscillator constructs a DerivativeOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDerivativeOscillator(rsiPeriod int, smooth1 int, smooth2 int, signalPeriod int) (*DerivativeOscillator, error) { + ptr := C.wickra_derivative_oscillator_new(C.uintptr_t(rsiPeriod), C.uintptr_t(smooth1), C.uintptr_t(smooth2), C.uintptr_t(signalPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DerivativeOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*DerivativeOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DerivativeOscillator) Update(value float64) float64 { + r := float64(C.wickra_derivative_oscillator_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DerivativeOscillator) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_derivative_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DerivativeOscillator) Reset() { + C.wickra_derivative_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DerivativeOscillator) Close() { + if ind.handle != nil { + C.wickra_derivative_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DetrendedStdDev wraps the DetrendedStdDev indicator over the Wickra C ABI. +type DetrendedStdDev struct { + handle *C.struct_DetrendedStdDev +} + +// NewDetrendedStdDev constructs a DetrendedStdDev. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDetrendedStdDev(period int) (*DetrendedStdDev, error) { + ptr := C.wickra_detrended_std_dev_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DetrendedStdDev{handle: ptr} + runtime.SetFinalizer(obj, (*DetrendedStdDev).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DetrendedStdDev) Update(value float64) float64 { + r := float64(C.wickra_detrended_std_dev_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DetrendedStdDev) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_detrended_std_dev_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DetrendedStdDev) Reset() { + C.wickra_detrended_std_dev_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DetrendedStdDev) Close() { + if ind.handle != nil { + C.wickra_detrended_std_dev_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DisparityIndex wraps the DisparityIndex indicator over the Wickra C ABI. +type DisparityIndex struct { + handle *C.struct_DisparityIndex +} + +// NewDisparityIndex constructs a DisparityIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDisparityIndex(period int) (*DisparityIndex, error) { + ptr := C.wickra_disparity_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DisparityIndex{handle: ptr} + runtime.SetFinalizer(obj, (*DisparityIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DisparityIndex) Update(value float64) float64 { + r := float64(C.wickra_disparity_index_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DisparityIndex) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_disparity_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DisparityIndex) Reset() { + C.wickra_disparity_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DisparityIndex) Close() { + if ind.handle != nil { + C.wickra_disparity_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DistanceSsd wraps the DistanceSsd indicator over the Wickra C ABI. +type DistanceSsd struct { + handle *C.struct_DistanceSsd +} + +// NewDistanceSsd constructs a DistanceSsd. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDistanceSsd(period int) (*DistanceSsd, error) { + ptr := C.wickra_distance_ssd_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DistanceSsd{handle: ptr} + runtime.SetFinalizer(obj, (*DistanceSsd).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DistanceSsd) Update(x float64, y float64) float64 { + r := float64(C.wickra_distance_ssd_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DistanceSsd) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_distance_ssd_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DistanceSsd) Reset() { + C.wickra_distance_ssd_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DistanceSsd) Close() { + if ind.handle != nil { + C.wickra_distance_ssd_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Doji wraps the Doji indicator over the Wickra C ABI. +type Doji struct { + handle *C.struct_Doji +} + +// NewDoji constructs a Doji. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDoji() (*Doji, error) { + ptr := C.wickra_doji_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Doji{handle: ptr} + runtime.SetFinalizer(obj, (*Doji).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Doji) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_doji_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Doji) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_doji_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Doji) Reset() { + C.wickra_doji_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Doji) Close() { + if ind.handle != nil { + C.wickra_doji_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DojiStar wraps the DojiStar indicator over the Wickra C ABI. +type DojiStar struct { + handle *C.struct_DojiStar +} + +// NewDojiStar constructs a DojiStar. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDojiStar() (*DojiStar, error) { + ptr := C.wickra_doji_star_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DojiStar{handle: ptr} + runtime.SetFinalizer(obj, (*DojiStar).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DojiStar) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_doji_star_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DojiStar) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_doji_star_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DojiStar) Reset() { + C.wickra_doji_star_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DojiStar) Close() { + if ind.handle != nil { + C.wickra_doji_star_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DollarBars wraps the DollarBars indicator over the Wickra C ABI. +type DollarBars struct { + handle *C.struct_DollarBars +} + +// NewDollarBars constructs a DollarBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDollarBars(dollarPerBar float64) (*DollarBars, error) { + ptr := C.wickra_dollar_bars_new(C.double(dollarPerBar)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DollarBars{handle: ptr} + runtime.SetFinalizer(obj, (*DollarBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *DollarBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []DollarBar { + const capacity = 64 + var buf [capacity]C.struct_WickraDollarBar + n := int(C.wickra_dollar_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]DollarBar, n) + for i := 0; i < n; i++ { + out[i] = DollarBar{float64(buf[i].open), float64(buf[i].high), float64(buf[i].low), float64(buf[i].close), float64(buf[i].volume), float64(buf[i].dollar)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DollarBars) Reset() { + C.wickra_dollar_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DollarBars) Close() { + if ind.handle != nil { + C.wickra_dollar_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Donchian wraps the Donchian indicator over the Wickra C ABI. +type Donchian struct { + handle *C.struct_Donchian +} + +// NewDonchian constructs a Donchian. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDonchian(period int) (*Donchian, error) { + ptr := C.wickra_donchian_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Donchian{handle: ptr} + runtime.SetFinalizer(obj, (*Donchian).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Donchian) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (DonchianOutput, bool) { + var out C.struct_WickraDonchianOutput + ok := bool(C.wickra_donchian_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return DonchianOutput{}, false + } + return DonchianOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Donchian) Reset() { + C.wickra_donchian_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Donchian) Close() { + if ind.handle != nil { + C.wickra_donchian_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DonchianStop wraps the DonchianStop indicator over the Wickra C ABI. +type DonchianStop struct { + handle *C.struct_DonchianStop +} + +// NewDonchianStop constructs a DonchianStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDonchianStop(period int) (*DonchianStop, error) { + ptr := C.wickra_donchian_stop_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DonchianStop{handle: ptr} + runtime.SetFinalizer(obj, (*DonchianStop).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *DonchianStop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (DonchianStopOutput, bool) { + var out C.struct_WickraDonchianStopOutput + ok := bool(C.wickra_donchian_stop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return DonchianStopOutput{}, false + } + return DonchianStopOutput{float64(out.stop_long), float64(out.stop_short)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DonchianStop) Reset() { + C.wickra_donchian_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DonchianStop) Close() { + if ind.handle != nil { + C.wickra_donchian_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DoubleBollinger wraps the DoubleBollinger indicator over the Wickra C ABI. +type DoubleBollinger struct { + handle *C.struct_DoubleBollinger +} + +// NewDoubleBollinger constructs a DoubleBollinger. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDoubleBollinger(period int, kInner float64, kOuter float64) (*DoubleBollinger, error) { + ptr := C.wickra_double_bollinger_new(C.uintptr_t(period), C.double(kInner), C.double(kOuter)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DoubleBollinger{handle: ptr} + runtime.SetFinalizer(obj, (*DoubleBollinger).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *DoubleBollinger) Update(value float64) (DoubleBollingerOutput, bool) { + var out C.struct_WickraDoubleBollingerOutput + ok := bool(C.wickra_double_bollinger_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return DoubleBollingerOutput{}, false + } + return DoubleBollingerOutput{float64(out.upper_outer), float64(out.upper_inner), float64(out.middle), float64(out.lower_inner), float64(out.lower_outer)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DoubleBollinger) Reset() { + C.wickra_double_bollinger_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DoubleBollinger) Close() { + if ind.handle != nil { + C.wickra_double_bollinger_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DoubleTopBottom wraps the DoubleTopBottom indicator over the Wickra C ABI. +type DoubleTopBottom struct { + handle *C.struct_DoubleTopBottom +} + +// NewDoubleTopBottom constructs a DoubleTopBottom. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDoubleTopBottom() (*DoubleTopBottom, error) { + ptr := C.wickra_double_top_bottom_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DoubleTopBottom{handle: ptr} + runtime.SetFinalizer(obj, (*DoubleTopBottom).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DoubleTopBottom) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_double_top_bottom_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DoubleTopBottom) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_double_top_bottom_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DoubleTopBottom) Reset() { + C.wickra_double_top_bottom_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DoubleTopBottom) Close() { + if ind.handle != nil { + C.wickra_double_top_bottom_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DownsideGapThreeMethods wraps the DownsideGapThreeMethods indicator over the Wickra C ABI. +type DownsideGapThreeMethods struct { + handle *C.struct_DownsideGapThreeMethods +} + +// NewDownsideGapThreeMethods constructs a DownsideGapThreeMethods. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDownsideGapThreeMethods() (*DownsideGapThreeMethods, error) { + ptr := C.wickra_downside_gap_three_methods_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DownsideGapThreeMethods{handle: ptr} + runtime.SetFinalizer(obj, (*DownsideGapThreeMethods).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DownsideGapThreeMethods) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_downside_gap_three_methods_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DownsideGapThreeMethods) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_downside_gap_three_methods_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DownsideGapThreeMethods) Reset() { + C.wickra_downside_gap_three_methods_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DownsideGapThreeMethods) Close() { + if ind.handle != nil { + C.wickra_downside_gap_three_methods_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Dpo wraps the Dpo indicator over the Wickra C ABI. +type Dpo struct { + handle *C.struct_Dpo +} + +// NewDpo constructs a Dpo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDpo(period int) (*Dpo, error) { + ptr := C.wickra_dpo_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Dpo{handle: ptr} + runtime.SetFinalizer(obj, (*Dpo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Dpo) Update(value float64) float64 { + r := float64(C.wickra_dpo_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Dpo) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_dpo_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Dpo) Reset() { + C.wickra_dpo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Dpo) Close() { + if ind.handle != nil { + C.wickra_dpo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DragonflyDoji wraps the DragonflyDoji indicator over the Wickra C ABI. +type DragonflyDoji struct { + handle *C.struct_DragonflyDoji +} + +// NewDragonflyDoji constructs a DragonflyDoji. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDragonflyDoji() (*DragonflyDoji, error) { + ptr := C.wickra_dragonfly_doji_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DragonflyDoji{handle: ptr} + runtime.SetFinalizer(obj, (*DragonflyDoji).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DragonflyDoji) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_dragonfly_doji_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DragonflyDoji) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_dragonfly_doji_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DragonflyDoji) Reset() { + C.wickra_dragonfly_doji_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DragonflyDoji) Close() { + if ind.handle != nil { + C.wickra_dragonfly_doji_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DrawdownDuration wraps the DrawdownDuration indicator over the Wickra C ABI. +type DrawdownDuration struct { + handle *C.struct_DrawdownDuration +} + +// NewDrawdownDuration constructs a DrawdownDuration. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDrawdownDuration() (*DrawdownDuration, error) { + ptr := C.wickra_drawdown_duration_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DrawdownDuration{handle: ptr} + runtime.SetFinalizer(obj, (*DrawdownDuration).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DrawdownDuration) Update(value float64) float64 { + r := float64(C.wickra_drawdown_duration_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DrawdownDuration) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_drawdown_duration_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DrawdownDuration) Reset() { + C.wickra_drawdown_duration_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DrawdownDuration) Close() { + if ind.handle != nil { + C.wickra_drawdown_duration_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DumplingTop wraps the DumplingTop indicator over the Wickra C ABI. +type DumplingTop struct { + handle *C.struct_DumplingTop +} + +// NewDumplingTop constructs a DumplingTop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDumplingTop(period int) (*DumplingTop, error) { + ptr := C.wickra_dumpling_top_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DumplingTop{handle: ptr} + runtime.SetFinalizer(obj, (*DumplingTop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DumplingTop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_dumpling_top_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DumplingTop) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_dumpling_top_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DumplingTop) Reset() { + C.wickra_dumpling_top_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DumplingTop) Close() { + if ind.handle != nil { + C.wickra_dumpling_top_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Dx wraps the Dx indicator over the Wickra C ABI. +type Dx struct { + handle *C.struct_Dx +} + +// NewDx constructs a Dx. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDx(period int) (*Dx, error) { + ptr := C.wickra_dx_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Dx{handle: ptr} + runtime.SetFinalizer(obj, (*Dx).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Dx) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_dx_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Dx) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_dx_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Dx) Reset() { + C.wickra_dx_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Dx) Close() { + if ind.handle != nil { + C.wickra_dx_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// DynamicMomentumIndex wraps the DynamicMomentumIndex indicator over the Wickra C ABI. +type DynamicMomentumIndex struct { + handle *C.struct_DynamicMomentumIndex +} + +// NewDynamicMomentumIndex constructs a DynamicMomentumIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewDynamicMomentumIndex(period int) (*DynamicMomentumIndex, error) { + ptr := C.wickra_dynamic_momentum_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &DynamicMomentumIndex{handle: ptr} + runtime.SetFinalizer(obj, (*DynamicMomentumIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *DynamicMomentumIndex) Update(value float64) float64 { + r := float64(C.wickra_dynamic_momentum_index_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *DynamicMomentumIndex) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_dynamic_momentum_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *DynamicMomentumIndex) Reset() { + C.wickra_dynamic_momentum_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *DynamicMomentumIndex) Close() { + if ind.handle != nil { + C.wickra_dynamic_momentum_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EaseOfMovement wraps the EaseOfMovement indicator over the Wickra C ABI. +type EaseOfMovement struct { + handle *C.struct_EaseOfMovement +} + +// NewEaseOfMovement constructs a EaseOfMovement. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEaseOfMovement(period int) (*EaseOfMovement, error) { + ptr := C.wickra_ease_of_movement_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EaseOfMovement{handle: ptr} + runtime.SetFinalizer(obj, (*EaseOfMovement).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EaseOfMovement) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_ease_of_movement_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *EaseOfMovement) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ease_of_movement_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EaseOfMovement) Reset() { + C.wickra_ease_of_movement_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EaseOfMovement) Close() { + if ind.handle != nil { + C.wickra_ease_of_movement_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EffectiveSpread wraps the EffectiveSpread indicator over the Wickra C ABI. +type EffectiveSpread struct { + handle *C.struct_EffectiveSpread +} + +// NewEffectiveSpread constructs a EffectiveSpread. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEffectiveSpread() (*EffectiveSpread, error) { + ptr := C.wickra_effective_spread_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EffectiveSpread{handle: ptr} + runtime.SetFinalizer(obj, (*EffectiveSpread).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EffectiveSpread) Update(price float64, size float64, isBuy bool, timestamp int64, mid float64) float64 { + r := float64(C.wickra_effective_spread_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp), C.double(mid))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EffectiveSpread) Reset() { + C.wickra_effective_spread_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EffectiveSpread) Close() { + if ind.handle != nil { + C.wickra_effective_spread_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EhlersStochastic wraps the EhlersStochastic indicator over the Wickra C ABI. +type EhlersStochastic struct { + handle *C.struct_EhlersStochastic +} + +// NewEhlersStochastic constructs a EhlersStochastic. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEhlersStochastic(period int) (*EhlersStochastic, error) { + ptr := C.wickra_ehlers_stochastic_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EhlersStochastic{handle: ptr} + runtime.SetFinalizer(obj, (*EhlersStochastic).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EhlersStochastic) Update(value float64) float64 { + r := float64(C.wickra_ehlers_stochastic_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *EhlersStochastic) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ehlers_stochastic_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EhlersStochastic) Reset() { + C.wickra_ehlers_stochastic_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EhlersStochastic) Close() { + if ind.handle != nil { + C.wickra_ehlers_stochastic_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Ehma wraps the Ehma indicator over the Wickra C ABI. +type Ehma struct { + handle *C.struct_Ehma +} + +// NewEhma constructs a Ehma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEhma(period int) (*Ehma, error) { + ptr := C.wickra_ehma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Ehma{handle: ptr} + runtime.SetFinalizer(obj, (*Ehma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Ehma) Update(value float64) float64 { + r := float64(C.wickra_ehma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Ehma) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ehma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Ehma) Reset() { + C.wickra_ehma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Ehma) Close() { + if ind.handle != nil { + C.wickra_ehma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ElderImpulse wraps the ElderImpulse indicator over the Wickra C ABI. +type ElderImpulse struct { + handle *C.struct_ElderImpulse +} + +// NewElderImpulse constructs a ElderImpulse. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewElderImpulse(emaPeriod int, macdFast int, macdSlow int, macdSignal int) (*ElderImpulse, error) { + ptr := C.wickra_elder_impulse_new(C.uintptr_t(emaPeriod), C.uintptr_t(macdFast), C.uintptr_t(macdSlow), C.uintptr_t(macdSignal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ElderImpulse{handle: ptr} + runtime.SetFinalizer(obj, (*ElderImpulse).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ElderImpulse) Update(value float64) float64 { + r := float64(C.wickra_elder_impulse_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ElderImpulse) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_elder_impulse_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ElderImpulse) Reset() { + C.wickra_elder_impulse_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ElderImpulse) Close() { + if ind.handle != nil { + C.wickra_elder_impulse_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ElderRay wraps the ElderRay indicator over the Wickra C ABI. +type ElderRay struct { + handle *C.struct_ElderRay +} + +// NewElderRay constructs a ElderRay. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewElderRay(period int) (*ElderRay, error) { + ptr := C.wickra_elder_ray_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ElderRay{handle: ptr} + runtime.SetFinalizer(obj, (*ElderRay).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ElderRay) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ElderRayOutput, bool) { + var out C.struct_WickraElderRayOutput + ok := bool(C.wickra_elder_ray_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ElderRayOutput{}, false + } + return ElderRayOutput{float64(out.bull_power), float64(out.bear_power)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ElderRay) Reset() { + C.wickra_elder_ray_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ElderRay) Close() { + if ind.handle != nil { + C.wickra_elder_ray_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ElderSafeZone wraps the ElderSafeZone indicator over the Wickra C ABI. +type ElderSafeZone struct { + handle *C.struct_ElderSafeZone +} + +// NewElderSafeZone constructs a ElderSafeZone. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewElderSafeZone(period int, coeff float64) (*ElderSafeZone, error) { + ptr := C.wickra_elder_safe_zone_new(C.uintptr_t(period), C.double(coeff)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ElderSafeZone{handle: ptr} + runtime.SetFinalizer(obj, (*ElderSafeZone).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ElderSafeZone) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ElderSafeZoneOutput, bool) { + var out C.struct_WickraElderSafeZoneOutput + ok := bool(C.wickra_elder_safe_zone_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ElderSafeZoneOutput{}, false + } + return ElderSafeZoneOutput{float64(out.value), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ElderSafeZone) Reset() { + C.wickra_elder_safe_zone_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ElderSafeZone) Close() { + if ind.handle != nil { + C.wickra_elder_safe_zone_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Ema wraps the Ema indicator over the Wickra C ABI. +type Ema struct { + handle *C.struct_Ema +} + +// NewEma constructs a Ema. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEma(period int) (*Ema, error) { + ptr := C.wickra_ema_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Ema{handle: ptr} + runtime.SetFinalizer(obj, (*Ema).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Ema) Update(value float64) float64 { + r := float64(C.wickra_ema_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Ema) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ema_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Ema) Reset() { + C.wickra_ema_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Ema) Close() { + if ind.handle != nil { + C.wickra_ema_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EmpiricalModeDecomposition wraps the EmpiricalModeDecomposition indicator over the Wickra C ABI. +type EmpiricalModeDecomposition struct { + handle *C.struct_EmpiricalModeDecomposition +} + +// NewEmpiricalModeDecomposition constructs a EmpiricalModeDecomposition. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEmpiricalModeDecomposition(period int, fraction float64) (*EmpiricalModeDecomposition, error) { + ptr := C.wickra_empirical_mode_decomposition_new(C.uintptr_t(period), C.double(fraction)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EmpiricalModeDecomposition{handle: ptr} + runtime.SetFinalizer(obj, (*EmpiricalModeDecomposition).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EmpiricalModeDecomposition) Update(value float64) float64 { + r := float64(C.wickra_empirical_mode_decomposition_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *EmpiricalModeDecomposition) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_empirical_mode_decomposition_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EmpiricalModeDecomposition) Reset() { + C.wickra_empirical_mode_decomposition_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EmpiricalModeDecomposition) Close() { + if ind.handle != nil { + C.wickra_empirical_mode_decomposition_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Engulfing wraps the Engulfing indicator over the Wickra C ABI. +type Engulfing struct { + handle *C.struct_Engulfing +} + +// NewEngulfing constructs a Engulfing. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEngulfing() (*Engulfing, error) { + ptr := C.wickra_engulfing_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Engulfing{handle: ptr} + runtime.SetFinalizer(obj, (*Engulfing).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Engulfing) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_engulfing_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Engulfing) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_engulfing_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Engulfing) Reset() { + C.wickra_engulfing_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Engulfing) Close() { + if ind.handle != nil { + C.wickra_engulfing_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Equivolume wraps the Equivolume indicator over the Wickra C ABI. +type Equivolume struct { + handle *C.struct_Equivolume +} + +// NewEquivolume constructs a Equivolume. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEquivolume(period int) (*Equivolume, error) { + ptr := C.wickra_equivolume_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Equivolume{handle: ptr} + runtime.SetFinalizer(obj, (*Equivolume).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Equivolume) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (EquivolumeOutput, bool) { + var out C.struct_WickraEquivolumeOutput + ok := bool(C.wickra_equivolume_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return EquivolumeOutput{}, false + } + return EquivolumeOutput{float64(out.height), float64(out.width)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Equivolume) Reset() { + C.wickra_equivolume_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Equivolume) Close() { + if ind.handle != nil { + C.wickra_equivolume_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EstimatedLeverageRatio wraps the EstimatedLeverageRatio indicator over the Wickra C ABI. +type EstimatedLeverageRatio struct { + handle *C.struct_EstimatedLeverageRatio +} + +// NewEstimatedLeverageRatio constructs a EstimatedLeverageRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEstimatedLeverageRatio() (*EstimatedLeverageRatio, error) { + ptr := C.wickra_estimated_leverage_ratio_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EstimatedLeverageRatio{handle: ptr} + runtime.SetFinalizer(obj, (*EstimatedLeverageRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EstimatedLeverageRatio) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_estimated_leverage_ratio_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EstimatedLeverageRatio) Reset() { + C.wickra_estimated_leverage_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EstimatedLeverageRatio) Close() { + if ind.handle != nil { + C.wickra_estimated_leverage_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EvenBetterSinewave wraps the EvenBetterSinewave indicator over the Wickra C ABI. +type EvenBetterSinewave struct { + handle *C.struct_EvenBetterSinewave +} + +// NewEvenBetterSinewave constructs a EvenBetterSinewave. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEvenBetterSinewave(hpPeriod int, ssfLength int) (*EvenBetterSinewave, error) { + ptr := C.wickra_even_better_sinewave_new(C.uintptr_t(hpPeriod), C.uintptr_t(ssfLength)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EvenBetterSinewave{handle: ptr} + runtime.SetFinalizer(obj, (*EvenBetterSinewave).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EvenBetterSinewave) Update(value float64) float64 { + r := float64(C.wickra_even_better_sinewave_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *EvenBetterSinewave) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_even_better_sinewave_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EvenBetterSinewave) Reset() { + C.wickra_even_better_sinewave_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EvenBetterSinewave) Close() { + if ind.handle != nil { + C.wickra_even_better_sinewave_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EveningDojiStar wraps the EveningDojiStar indicator over the Wickra C ABI. +type EveningDojiStar struct { + handle *C.struct_EveningDojiStar +} + +// NewEveningDojiStar constructs a EveningDojiStar. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEveningDojiStar() (*EveningDojiStar, error) { + ptr := C.wickra_evening_doji_star_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EveningDojiStar{handle: ptr} + runtime.SetFinalizer(obj, (*EveningDojiStar).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EveningDojiStar) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_evening_doji_star_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *EveningDojiStar) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_evening_doji_star_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EveningDojiStar) Reset() { + C.wickra_evening_doji_star_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EveningDojiStar) Close() { + if ind.handle != nil { + C.wickra_evening_doji_star_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Evwma wraps the Evwma indicator over the Wickra C ABI. +type Evwma struct { + handle *C.struct_Evwma +} + +// NewEvwma constructs a Evwma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEvwma(period int) (*Evwma, error) { + ptr := C.wickra_evwma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Evwma{handle: ptr} + runtime.SetFinalizer(obj, (*Evwma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Evwma) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_evwma_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Evwma) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_evwma_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Evwma) Reset() { + C.wickra_evwma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Evwma) Close() { + if ind.handle != nil { + C.wickra_evwma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// EwmaVolatility wraps the EwmaVolatility indicator over the Wickra C ABI. +type EwmaVolatility struct { + handle *C.struct_EwmaVolatility +} + +// NewEwmaVolatility constructs a EwmaVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewEwmaVolatility(lambda float64) (*EwmaVolatility, error) { + ptr := C.wickra_ewma_volatility_new(C.double(lambda)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &EwmaVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*EwmaVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *EwmaVolatility) Update(value float64) float64 { + r := float64(C.wickra_ewma_volatility_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *EwmaVolatility) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ewma_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *EwmaVolatility) Reset() { + C.wickra_ewma_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *EwmaVolatility) Close() { + if ind.handle != nil { + C.wickra_ewma_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Expectancy wraps the Expectancy indicator over the Wickra C ABI. +type Expectancy struct { + handle *C.struct_Expectancy +} + +// NewExpectancy constructs a Expectancy. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewExpectancy(period int) (*Expectancy, error) { + ptr := C.wickra_expectancy_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Expectancy{handle: ptr} + runtime.SetFinalizer(obj, (*Expectancy).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Expectancy) Update(value float64) float64 { + r := float64(C.wickra_expectancy_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Expectancy) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_expectancy_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Expectancy) Reset() { + C.wickra_expectancy_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Expectancy) Close() { + if ind.handle != nil { + C.wickra_expectancy_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FallingThreeMethods wraps the FallingThreeMethods indicator over the Wickra C ABI. +type FallingThreeMethods struct { + handle *C.struct_FallingThreeMethods +} + +// NewFallingThreeMethods constructs a FallingThreeMethods. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFallingThreeMethods() (*FallingThreeMethods, error) { + ptr := C.wickra_falling_three_methods_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FallingThreeMethods{handle: ptr} + runtime.SetFinalizer(obj, (*FallingThreeMethods).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FallingThreeMethods) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_falling_three_methods_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *FallingThreeMethods) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_falling_three_methods_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FallingThreeMethods) Reset() { + C.wickra_falling_three_methods_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FallingThreeMethods) Close() { + if ind.handle != nil { + C.wickra_falling_three_methods_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Fama wraps the Fama indicator over the Wickra C ABI. +type Fama struct { + handle *C.struct_Fama +} + +// NewFama constructs a Fama. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFama(fastLimit float64, slowLimit float64) (*Fama, error) { + ptr := C.wickra_fama_new(C.double(fastLimit), C.double(slowLimit)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Fama{handle: ptr} + runtime.SetFinalizer(obj, (*Fama).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Fama) Update(value float64) float64 { + r := float64(C.wickra_fama_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Fama) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_fama_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Fama) Reset() { + C.wickra_fama_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Fama) Close() { + if ind.handle != nil { + C.wickra_fama_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibArcs wraps the FibArcs indicator over the Wickra C ABI. +type FibArcs struct { + handle *C.struct_FibArcs +} + +// NewFibArcs constructs a FibArcs. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibArcs() (*FibArcs, error) { + ptr := C.wickra_fib_arcs_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibArcs{handle: ptr} + runtime.SetFinalizer(obj, (*FibArcs).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibArcs) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibArcsOutput, bool) { + var out C.struct_WickraFibArcsOutput + ok := bool(C.wickra_fib_arcs_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibArcsOutput{}, false + } + return FibArcsOutput{float64(out.arc_382), float64(out.arc_500), float64(out.arc_618)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibArcs) Reset() { + C.wickra_fib_arcs_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibArcs) Close() { + if ind.handle != nil { + C.wickra_fib_arcs_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibChannel wraps the FibChannel indicator over the Wickra C ABI. +type FibChannel struct { + handle *C.struct_FibChannel +} + +// NewFibChannel constructs a FibChannel. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibChannel() (*FibChannel, error) { + ptr := C.wickra_fib_channel_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibChannel{handle: ptr} + runtime.SetFinalizer(obj, (*FibChannel).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibChannel) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibChannelOutput, bool) { + var out C.struct_WickraFibChannelOutput + ok := bool(C.wickra_fib_channel_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibChannelOutput{}, false + } + return FibChannelOutput{float64(out.base), float64(out.level_618), float64(out.level_1000), float64(out.level_1618)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibChannel) Reset() { + C.wickra_fib_channel_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibChannel) Close() { + if ind.handle != nil { + C.wickra_fib_channel_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibConfluence wraps the FibConfluence indicator over the Wickra C ABI. +type FibConfluence struct { + handle *C.struct_FibConfluence +} + +// NewFibConfluence constructs a FibConfluence. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibConfluence() (*FibConfluence, error) { + ptr := C.wickra_fib_confluence_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibConfluence{handle: ptr} + runtime.SetFinalizer(obj, (*FibConfluence).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibConfluence) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibConfluenceOutput, bool) { + var out C.struct_WickraFibConfluenceOutput + ok := bool(C.wickra_fib_confluence_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibConfluenceOutput{}, false + } + return FibConfluenceOutput{float64(out.price), float64(out.strength)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibConfluence) Reset() { + C.wickra_fib_confluence_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibConfluence) Close() { + if ind.handle != nil { + C.wickra_fib_confluence_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibExtension wraps the FibExtension indicator over the Wickra C ABI. +type FibExtension struct { + handle *C.struct_FibExtension +} + +// NewFibExtension constructs a FibExtension. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibExtension() (*FibExtension, error) { + ptr := C.wickra_fib_extension_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibExtension{handle: ptr} + runtime.SetFinalizer(obj, (*FibExtension).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibExtension) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibExtensionOutput, bool) { + var out C.struct_WickraFibExtensionOutput + ok := bool(C.wickra_fib_extension_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibExtensionOutput{}, false + } + return FibExtensionOutput{float64(out.level_1272), float64(out.level_1414), float64(out.level_1618), float64(out.level_2000), float64(out.level_2618)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibExtension) Reset() { + C.wickra_fib_extension_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibExtension) Close() { + if ind.handle != nil { + C.wickra_fib_extension_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibFan wraps the FibFan indicator over the Wickra C ABI. +type FibFan struct { + handle *C.struct_FibFan +} + +// NewFibFan constructs a FibFan. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibFan() (*FibFan, error) { + ptr := C.wickra_fib_fan_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibFan{handle: ptr} + runtime.SetFinalizer(obj, (*FibFan).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibFan) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibFanOutput, bool) { + var out C.struct_WickraFibFanOutput + ok := bool(C.wickra_fib_fan_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibFanOutput{}, false + } + return FibFanOutput{float64(out.fan_382), float64(out.fan_500), float64(out.fan_618)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibFan) Reset() { + C.wickra_fib_fan_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibFan) Close() { + if ind.handle != nil { + C.wickra_fib_fan_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibProjection wraps the FibProjection indicator over the Wickra C ABI. +type FibProjection struct { + handle *C.struct_FibProjection +} + +// NewFibProjection constructs a FibProjection. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibProjection() (*FibProjection, error) { + ptr := C.wickra_fib_projection_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibProjection{handle: ptr} + runtime.SetFinalizer(obj, (*FibProjection).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibProjection) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibProjectionOutput, bool) { + var out C.struct_WickraFibProjectionOutput + ok := bool(C.wickra_fib_projection_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibProjectionOutput{}, false + } + return FibProjectionOutput{float64(out.level_618), float64(out.level_1000), float64(out.level_1618), float64(out.level_2618)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibProjection) Reset() { + C.wickra_fib_projection_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibProjection) Close() { + if ind.handle != nil { + C.wickra_fib_projection_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibRetracement wraps the FibRetracement indicator over the Wickra C ABI. +type FibRetracement struct { + handle *C.struct_FibRetracement +} + +// NewFibRetracement constructs a FibRetracement. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibRetracement() (*FibRetracement, error) { + ptr := C.wickra_fib_retracement_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibRetracement{handle: ptr} + runtime.SetFinalizer(obj, (*FibRetracement).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibRetracement) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibRetracementOutput, bool) { + var out C.struct_WickraFibRetracementOutput + ok := bool(C.wickra_fib_retracement_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibRetracementOutput{}, false + } + return FibRetracementOutput{float64(out.level_0), float64(out.level_236), float64(out.level_382), float64(out.level_500), float64(out.level_618), float64(out.level_786), float64(out.level_1000)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibRetracement) Reset() { + C.wickra_fib_retracement_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibRetracement) Close() { + if ind.handle != nil { + C.wickra_fib_retracement_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibTimeZones wraps the FibTimeZones indicator over the Wickra C ABI. +type FibTimeZones struct { + handle *C.struct_FibTimeZones +} + +// NewFibTimeZones constructs a FibTimeZones. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibTimeZones() (*FibTimeZones, error) { + ptr := C.wickra_fib_time_zones_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibTimeZones{handle: ptr} + runtime.SetFinalizer(obj, (*FibTimeZones).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibTimeZones) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibTimeZonesOutput, bool) { + var out C.struct_WickraFibTimeZonesOutput + ok := bool(C.wickra_fib_time_zones_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibTimeZonesOutput{}, false + } + return FibTimeZonesOutput{float64(out.on_zone), float64(out.bars_to_next)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibTimeZones) Reset() { + C.wickra_fib_time_zones_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibTimeZones) Close() { + if ind.handle != nil { + C.wickra_fib_time_zones_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FibonacciPivots wraps the FibonacciPivots indicator over the Wickra C ABI. +type FibonacciPivots struct { + handle *C.struct_FibonacciPivots +} + +// NewFibonacciPivots constructs a FibonacciPivots. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFibonacciPivots() (*FibonacciPivots, error) { + ptr := C.wickra_fibonacci_pivots_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FibonacciPivots{handle: ptr} + runtime.SetFinalizer(obj, (*FibonacciPivots).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FibonacciPivots) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FibonacciPivotsOutput, bool) { + var out C.struct_WickraFibonacciPivotsOutput + ok := bool(C.wickra_fibonacci_pivots_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FibonacciPivotsOutput{}, false + } + return FibonacciPivotsOutput{float64(out.pp), float64(out.r1), float64(out.r2), float64(out.r3), float64(out.s1), float64(out.s2), float64(out.s3)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FibonacciPivots) Reset() { + C.wickra_fibonacci_pivots_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FibonacciPivots) Close() { + if ind.handle != nil { + C.wickra_fibonacci_pivots_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FisherRsi wraps the FisherRsi indicator over the Wickra C ABI. +type FisherRsi struct { + handle *C.struct_FisherRsi +} + +// NewFisherRsi constructs a FisherRsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFisherRsi(period int) (*FisherRsi, error) { + ptr := C.wickra_fisher_rsi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FisherRsi{handle: ptr} + runtime.SetFinalizer(obj, (*FisherRsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FisherRsi) Update(value float64) float64 { + r := float64(C.wickra_fisher_rsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *FisherRsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_fisher_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FisherRsi) Reset() { + C.wickra_fisher_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FisherRsi) Close() { + if ind.handle != nil { + C.wickra_fisher_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FisherTransform wraps the FisherTransform indicator over the Wickra C ABI. +type FisherTransform struct { + handle *C.struct_FisherTransform +} + +// NewFisherTransform constructs a FisherTransform. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFisherTransform(period int) (*FisherTransform, error) { + ptr := C.wickra_fisher_transform_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FisherTransform{handle: ptr} + runtime.SetFinalizer(obj, (*FisherTransform).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FisherTransform) Update(value float64) float64 { + r := float64(C.wickra_fisher_transform_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *FisherTransform) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_fisher_transform_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FisherTransform) Reset() { + C.wickra_fisher_transform_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FisherTransform) Close() { + if ind.handle != nil { + C.wickra_fisher_transform_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FlagPennant wraps the FlagPennant indicator over the Wickra C ABI. +type FlagPennant struct { + handle *C.struct_FlagPennant +} + +// NewFlagPennant constructs a FlagPennant. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFlagPennant() (*FlagPennant, error) { + ptr := C.wickra_flag_pennant_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FlagPennant{handle: ptr} + runtime.SetFinalizer(obj, (*FlagPennant).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FlagPennant) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_flag_pennant_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *FlagPennant) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_flag_pennant_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FlagPennant) Reset() { + C.wickra_flag_pennant_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FlagPennant) Close() { + if ind.handle != nil { + C.wickra_flag_pennant_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Footprint wraps the Footprint indicator over the Wickra C ABI. +type Footprint struct { + handle *C.struct_Footprint +} + +// NewFootprint constructs a Footprint. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFootprint(tickSize float64) (*Footprint, error) { + ptr := C.wickra_footprint_new(C.double(tickSize)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Footprint{handle: ptr} + runtime.SetFinalizer(obj, (*Footprint).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *Footprint) Update(price float64, size float64, isBuy bool, timestamp int64) []FootprintLevel { + const capacity = 64 + var buf [capacity]C.struct_WickraFootprintLevel + n := int(C.wickra_footprint_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]FootprintLevel, n) + for i := 0; i < n; i++ { + out[i] = FootprintLevel{float64(buf[i].price), float64(buf[i].bid_vol), float64(buf[i].ask_vol)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Footprint) Reset() { + C.wickra_footprint_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Footprint) Close() { + if ind.handle != nil { + C.wickra_footprint_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ForceIndex wraps the ForceIndex indicator over the Wickra C ABI. +type ForceIndex struct { + handle *C.struct_ForceIndex +} + +// NewForceIndex constructs a ForceIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewForceIndex(period int) (*ForceIndex, error) { + ptr := C.wickra_force_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ForceIndex{handle: ptr} + runtime.SetFinalizer(obj, (*ForceIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ForceIndex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_force_index_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ForceIndex) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_force_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ForceIndex) Reset() { + C.wickra_force_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ForceIndex) Close() { + if ind.handle != nil { + C.wickra_force_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FractalChaosBands wraps the FractalChaosBands indicator over the Wickra C ABI. +type FractalChaosBands struct { + handle *C.struct_FractalChaosBands +} + +// NewFractalChaosBands constructs a FractalChaosBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFractalChaosBands(k int) (*FractalChaosBands, error) { + ptr := C.wickra_fractal_chaos_bands_new(C.uintptr_t(k)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FractalChaosBands{handle: ptr} + runtime.SetFinalizer(obj, (*FractalChaosBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *FractalChaosBands) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (FractalChaosBandsOutput, bool) { + var out C.struct_WickraFractalChaosBandsOutput + ok := bool(C.wickra_fractal_chaos_bands_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return FractalChaosBandsOutput{}, false + } + return FractalChaosBandsOutput{float64(out.upper), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FractalChaosBands) Reset() { + C.wickra_fractal_chaos_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FractalChaosBands) Close() { + if ind.handle != nil { + C.wickra_fractal_chaos_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Frama wraps the Frama indicator over the Wickra C ABI. +type Frama struct { + handle *C.struct_Frama +} + +// NewFrama constructs a Frama. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFrama(period int) (*Frama, error) { + ptr := C.wickra_frama_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Frama{handle: ptr} + runtime.SetFinalizer(obj, (*Frama).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Frama) Update(value float64) float64 { + r := float64(C.wickra_frama_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Frama) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_frama_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Frama) Reset() { + C.wickra_frama_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Frama) Close() { + if ind.handle != nil { + C.wickra_frama_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FryPanBottom wraps the FryPanBottom indicator over the Wickra C ABI. +type FryPanBottom struct { + handle *C.struct_FryPanBottom +} + +// NewFryPanBottom constructs a FryPanBottom. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFryPanBottom(period int) (*FryPanBottom, error) { + ptr := C.wickra_fry_pan_bottom_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FryPanBottom{handle: ptr} + runtime.SetFinalizer(obj, (*FryPanBottom).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FryPanBottom) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_fry_pan_bottom_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *FryPanBottom) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_fry_pan_bottom_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FryPanBottom) Reset() { + C.wickra_fry_pan_bottom_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FryPanBottom) Close() { + if ind.handle != nil { + C.wickra_fry_pan_bottom_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FundingBasis wraps the FundingBasis indicator over the Wickra C ABI. +type FundingBasis struct { + handle *C.struct_FundingBasis +} + +// NewFundingBasis constructs a FundingBasis. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFundingBasis() (*FundingBasis, error) { + ptr := C.wickra_funding_basis_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FundingBasis{handle: ptr} + runtime.SetFinalizer(obj, (*FundingBasis).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FundingBasis) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_funding_basis_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FundingBasis) Reset() { + C.wickra_funding_basis_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FundingBasis) Close() { + if ind.handle != nil { + C.wickra_funding_basis_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FundingImpliedApr wraps the FundingImpliedApr indicator over the Wickra C ABI. +type FundingImpliedApr struct { + handle *C.struct_FundingImpliedApr +} + +// NewFundingImpliedApr constructs a FundingImpliedApr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFundingImpliedApr(intervalsPerYear float64) (*FundingImpliedApr, error) { + ptr := C.wickra_funding_implied_apr_new(C.double(intervalsPerYear)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FundingImpliedApr{handle: ptr} + runtime.SetFinalizer(obj, (*FundingImpliedApr).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FundingImpliedApr) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_funding_implied_apr_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FundingImpliedApr) Reset() { + C.wickra_funding_implied_apr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FundingImpliedApr) Close() { + if ind.handle != nil { + C.wickra_funding_implied_apr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FundingRate wraps the FundingRate indicator over the Wickra C ABI. +type FundingRate struct { + handle *C.struct_FundingRate +} + +// NewFundingRate constructs a FundingRate. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFundingRate() (*FundingRate, error) { + ptr := C.wickra_funding_rate_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FundingRate{handle: ptr} + runtime.SetFinalizer(obj, (*FundingRate).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FundingRate) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_funding_rate_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FundingRate) Reset() { + C.wickra_funding_rate_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FundingRate) Close() { + if ind.handle != nil { + C.wickra_funding_rate_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FundingRateMean wraps the FundingRateMean indicator over the Wickra C ABI. +type FundingRateMean struct { + handle *C.struct_FundingRateMean +} + +// NewFundingRateMean constructs a FundingRateMean. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFundingRateMean(window int) (*FundingRateMean, error) { + ptr := C.wickra_funding_rate_mean_new(C.uintptr_t(window)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FundingRateMean{handle: ptr} + runtime.SetFinalizer(obj, (*FundingRateMean).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FundingRateMean) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_funding_rate_mean_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FundingRateMean) Reset() { + C.wickra_funding_rate_mean_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FundingRateMean) Close() { + if ind.handle != nil { + C.wickra_funding_rate_mean_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// FundingRateZScore wraps the FundingRateZScore indicator over the Wickra C ABI. +type FundingRateZScore struct { + handle *C.struct_FundingRateZScore +} + +// NewFundingRateZScore constructs a FundingRateZScore. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewFundingRateZScore(window int) (*FundingRateZScore, error) { + ptr := C.wickra_funding_rate_z_score_new(C.uintptr_t(window)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &FundingRateZScore{handle: ptr} + runtime.SetFinalizer(obj, (*FundingRateZScore).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *FundingRateZScore) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_funding_rate_z_score_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *FundingRateZScore) Reset() { + C.wickra_funding_rate_z_score_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *FundingRateZScore) Close() { + if ind.handle != nil { + C.wickra_funding_rate_z_score_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GainLossRatio wraps the GainLossRatio indicator over the Wickra C ABI. +type GainLossRatio struct { + handle *C.struct_GainLossRatio +} + +// NewGainLossRatio constructs a GainLossRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGainLossRatio(period int) (*GainLossRatio, error) { + ptr := C.wickra_gain_loss_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GainLossRatio{handle: ptr} + runtime.SetFinalizer(obj, (*GainLossRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GainLossRatio) Update(value float64) float64 { + r := float64(C.wickra_gain_loss_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GainLossRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_gain_loss_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GainLossRatio) Reset() { + C.wickra_gain_loss_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GainLossRatio) Close() { + if ind.handle != nil { + C.wickra_gain_loss_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GainToPainRatio wraps the GainToPainRatio indicator over the Wickra C ABI. +type GainToPainRatio struct { + handle *C.struct_GainToPainRatio +} + +// NewGainToPainRatio constructs a GainToPainRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGainToPainRatio(period int) (*GainToPainRatio, error) { + ptr := C.wickra_gain_to_pain_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GainToPainRatio{handle: ptr} + runtime.SetFinalizer(obj, (*GainToPainRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GainToPainRatio) Update(value float64) float64 { + r := float64(C.wickra_gain_to_pain_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GainToPainRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_gain_to_pain_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GainToPainRatio) Reset() { + C.wickra_gain_to_pain_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GainToPainRatio) Close() { + if ind.handle != nil { + C.wickra_gain_to_pain_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GapSideBySideWhite wraps the GapSideBySideWhite indicator over the Wickra C ABI. +type GapSideBySideWhite struct { + handle *C.struct_GapSideBySideWhite +} + +// NewGapSideBySideWhite constructs a GapSideBySideWhite. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGapSideBySideWhite() (*GapSideBySideWhite, error) { + ptr := C.wickra_gap_side_by_side_white_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GapSideBySideWhite{handle: ptr} + runtime.SetFinalizer(obj, (*GapSideBySideWhite).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GapSideBySideWhite) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_gap_side_by_side_white_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GapSideBySideWhite) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_gap_side_by_side_white_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GapSideBySideWhite) Reset() { + C.wickra_gap_side_by_side_white_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GapSideBySideWhite) Close() { + if ind.handle != nil { + C.wickra_gap_side_by_side_white_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Garch11 wraps the Garch11 indicator over the Wickra C ABI. +type Garch11 struct { + handle *C.struct_Garch11 +} + +// NewGarch11 constructs a Garch11. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGarch11(omega float64, alpha float64, beta float64) (*Garch11, error) { + ptr := C.wickra_garch11_new(C.double(omega), C.double(alpha), C.double(beta)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Garch11{handle: ptr} + runtime.SetFinalizer(obj, (*Garch11).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Garch11) Update(value float64) float64 { + r := float64(C.wickra_garch11_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Garch11) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_garch11_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Garch11) Reset() { + C.wickra_garch11_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Garch11) Close() { + if ind.handle != nil { + C.wickra_garch11_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GarmanKlassVolatility wraps the GarmanKlassVolatility indicator over the Wickra C ABI. +type GarmanKlassVolatility struct { + handle *C.struct_GarmanKlassVolatility +} + +// NewGarmanKlassVolatility constructs a GarmanKlassVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGarmanKlassVolatility(period int, tradingPeriods int) (*GarmanKlassVolatility, error) { + ptr := C.wickra_garman_klass_volatility_new(C.uintptr_t(period), C.uintptr_t(tradingPeriods)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GarmanKlassVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*GarmanKlassVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GarmanKlassVolatility) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_garman_klass_volatility_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GarmanKlassVolatility) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_garman_klass_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GarmanKlassVolatility) Reset() { + C.wickra_garman_klass_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GarmanKlassVolatility) Close() { + if ind.handle != nil { + C.wickra_garman_klass_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Gartley wraps the Gartley indicator over the Wickra C ABI. +type Gartley struct { + handle *C.struct_Gartley +} + +// NewGartley constructs a Gartley. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGartley() (*Gartley, error) { + ptr := C.wickra_gartley_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Gartley{handle: ptr} + runtime.SetFinalizer(obj, (*Gartley).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Gartley) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_gartley_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Gartley) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_gartley_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Gartley) Reset() { + C.wickra_gartley_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Gartley) Close() { + if ind.handle != nil { + C.wickra_gartley_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GatorOscillator wraps the GatorOscillator indicator over the Wickra C ABI. +type GatorOscillator struct { + handle *C.struct_GatorOscillator +} + +// NewGatorOscillator constructs a GatorOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGatorOscillator(jawPeriod int, teethPeriod int, lipsPeriod int) (*GatorOscillator, error) { + ptr := C.wickra_gator_oscillator_new(C.uintptr_t(jawPeriod), C.uintptr_t(teethPeriod), C.uintptr_t(lipsPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GatorOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*GatorOscillator).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *GatorOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (GatorOscillatorOutput, bool) { + var out C.struct_WickraGatorOscillatorOutput + ok := bool(C.wickra_gator_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return GatorOscillatorOutput{}, false + } + return GatorOscillatorOutput{float64(out.upper), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GatorOscillator) Reset() { + C.wickra_gator_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GatorOscillator) Close() { + if ind.handle != nil { + C.wickra_gator_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GeneralizedDema wraps the GeneralizedDema indicator over the Wickra C ABI. +type GeneralizedDema struct { + handle *C.struct_GeneralizedDema +} + +// NewGeneralizedDema constructs a GeneralizedDema. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGeneralizedDema(period int, v float64) (*GeneralizedDema, error) { + ptr := C.wickra_generalized_dema_new(C.uintptr_t(period), C.double(v)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GeneralizedDema{handle: ptr} + runtime.SetFinalizer(obj, (*GeneralizedDema).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GeneralizedDema) Update(value float64) float64 { + r := float64(C.wickra_generalized_dema_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GeneralizedDema) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_generalized_dema_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GeneralizedDema) Reset() { + C.wickra_generalized_dema_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GeneralizedDema) Close() { + if ind.handle != nil { + C.wickra_generalized_dema_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GeometricMa wraps the GeometricMa indicator over the Wickra C ABI. +type GeometricMa struct { + handle *C.struct_GeometricMa +} + +// NewGeometricMa constructs a GeometricMa. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGeometricMa(period int) (*GeometricMa, error) { + ptr := C.wickra_geometric_ma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GeometricMa{handle: ptr} + runtime.SetFinalizer(obj, (*GeometricMa).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GeometricMa) Update(value float64) float64 { + r := float64(C.wickra_geometric_ma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GeometricMa) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_geometric_ma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GeometricMa) Reset() { + C.wickra_geometric_ma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GeometricMa) Close() { + if ind.handle != nil { + C.wickra_geometric_ma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GoldenPocket wraps the GoldenPocket indicator over the Wickra C ABI. +type GoldenPocket struct { + handle *C.struct_GoldenPocket +} + +// NewGoldenPocket constructs a GoldenPocket. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGoldenPocket() (*GoldenPocket, error) { + ptr := C.wickra_golden_pocket_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GoldenPocket{handle: ptr} + runtime.SetFinalizer(obj, (*GoldenPocket).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *GoldenPocket) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (GoldenPocketOutput, bool) { + var out C.struct_WickraGoldenPocketOutput + ok := bool(C.wickra_golden_pocket_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return GoldenPocketOutput{}, false + } + return GoldenPocketOutput{float64(out.low), float64(out.mid), float64(out.high)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GoldenPocket) Reset() { + C.wickra_golden_pocket_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GoldenPocket) Close() { + if ind.handle != nil { + C.wickra_golden_pocket_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GrangerCausality wraps the GrangerCausality indicator over the Wickra C ABI. +type GrangerCausality struct { + handle *C.struct_GrangerCausality +} + +// NewGrangerCausality constructs a GrangerCausality. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGrangerCausality(period int, lag int) (*GrangerCausality, error) { + ptr := C.wickra_granger_causality_new(C.uintptr_t(period), C.uintptr_t(lag)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GrangerCausality{handle: ptr} + runtime.SetFinalizer(obj, (*GrangerCausality).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GrangerCausality) Update(x float64, y float64) float64 { + r := float64(C.wickra_granger_causality_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GrangerCausality) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_granger_causality_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GrangerCausality) Reset() { + C.wickra_granger_causality_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GrangerCausality) Close() { + if ind.handle != nil { + C.wickra_granger_causality_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// GravestoneDoji wraps the GravestoneDoji indicator over the Wickra C ABI. +type GravestoneDoji struct { + handle *C.struct_GravestoneDoji +} + +// NewGravestoneDoji constructs a GravestoneDoji. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewGravestoneDoji() (*GravestoneDoji, error) { + ptr := C.wickra_gravestone_doji_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &GravestoneDoji{handle: ptr} + runtime.SetFinalizer(obj, (*GravestoneDoji).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *GravestoneDoji) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_gravestone_doji_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *GravestoneDoji) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_gravestone_doji_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *GravestoneDoji) Reset() { + C.wickra_gravestone_doji_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *GravestoneDoji) Close() { + if ind.handle != nil { + C.wickra_gravestone_doji_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Hammer wraps the Hammer indicator over the Wickra C ABI. +type Hammer struct { + handle *C.struct_Hammer +} + +// NewHammer constructs a Hammer. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHammer() (*Hammer, error) { + ptr := C.wickra_hammer_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Hammer{handle: ptr} + runtime.SetFinalizer(obj, (*Hammer).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Hammer) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_hammer_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Hammer) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hammer_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Hammer) Reset() { + C.wickra_hammer_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Hammer) Close() { + if ind.handle != nil { + C.wickra_hammer_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HangingMan wraps the HangingMan indicator over the Wickra C ABI. +type HangingMan struct { + handle *C.struct_HangingMan +} + +// NewHangingMan constructs a HangingMan. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHangingMan() (*HangingMan, error) { + ptr := C.wickra_hanging_man_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HangingMan{handle: ptr} + runtime.SetFinalizer(obj, (*HangingMan).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HangingMan) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_hanging_man_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HangingMan) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hanging_man_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HangingMan) Reset() { + C.wickra_hanging_man_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HangingMan) Close() { + if ind.handle != nil { + C.wickra_hanging_man_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Harami wraps the Harami indicator over the Wickra C ABI. +type Harami struct { + handle *C.struct_Harami +} + +// NewHarami constructs a Harami. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHarami() (*Harami, error) { + ptr := C.wickra_harami_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Harami{handle: ptr} + runtime.SetFinalizer(obj, (*Harami).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Harami) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_harami_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Harami) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_harami_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Harami) Reset() { + C.wickra_harami_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Harami) Close() { + if ind.handle != nil { + C.wickra_harami_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HaramiCross wraps the HaramiCross indicator over the Wickra C ABI. +type HaramiCross struct { + handle *C.struct_HaramiCross +} + +// NewHaramiCross constructs a HaramiCross. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHaramiCross() (*HaramiCross, error) { + ptr := C.wickra_harami_cross_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HaramiCross{handle: ptr} + runtime.SetFinalizer(obj, (*HaramiCross).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HaramiCross) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_harami_cross_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HaramiCross) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_harami_cross_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HaramiCross) Reset() { + C.wickra_harami_cross_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HaramiCross) Close() { + if ind.handle != nil { + C.wickra_harami_cross_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HasbrouckInformationShare wraps the HasbrouckInformationShare indicator over the Wickra C ABI. +type HasbrouckInformationShare struct { + handle *C.struct_HasbrouckInformationShare +} + +// NewHasbrouckInformationShare constructs a HasbrouckInformationShare. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHasbrouckInformationShare(period int) (*HasbrouckInformationShare, error) { + ptr := C.wickra_hasbrouck_information_share_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HasbrouckInformationShare{handle: ptr} + runtime.SetFinalizer(obj, (*HasbrouckInformationShare).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HasbrouckInformationShare) Update(x float64, y float64) float64 { + r := float64(C.wickra_hasbrouck_information_share_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HasbrouckInformationShare) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hasbrouck_information_share_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HasbrouckInformationShare) Reset() { + C.wickra_hasbrouck_information_share_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HasbrouckInformationShare) Close() { + if ind.handle != nil { + C.wickra_hasbrouck_information_share_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HeadAndShoulders wraps the HeadAndShoulders indicator over the Wickra C ABI. +type HeadAndShoulders struct { + handle *C.struct_HeadAndShoulders +} + +// NewHeadAndShoulders constructs a HeadAndShoulders. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHeadAndShoulders() (*HeadAndShoulders, error) { + ptr := C.wickra_head_and_shoulders_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HeadAndShoulders{handle: ptr} + runtime.SetFinalizer(obj, (*HeadAndShoulders).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HeadAndShoulders) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_head_and_shoulders_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HeadAndShoulders) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_head_and_shoulders_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HeadAndShoulders) Reset() { + C.wickra_head_and_shoulders_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HeadAndShoulders) Close() { + if ind.handle != nil { + C.wickra_head_and_shoulders_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HeikinAshi wraps the HeikinAshi indicator over the Wickra C ABI. +type HeikinAshi struct { + handle *C.struct_HeikinAshi +} + +// NewHeikinAshi constructs a HeikinAshi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHeikinAshi() (*HeikinAshi, error) { + ptr := C.wickra_heikin_ashi_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HeikinAshi{handle: ptr} + runtime.SetFinalizer(obj, (*HeikinAshi).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *HeikinAshi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (HeikinAshiOutput, bool) { + var out C.struct_WickraHeikinAshiOutput + ok := bool(C.wickra_heikin_ashi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return HeikinAshiOutput{}, false + } + return HeikinAshiOutput{float64(out.open), float64(out.high), float64(out.low), float64(out.close)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HeikinAshi) Reset() { + C.wickra_heikin_ashi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HeikinAshi) Close() { + if ind.handle != nil { + C.wickra_heikin_ashi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HeikinAshiOscillator wraps the HeikinAshiOscillator indicator over the Wickra C ABI. +type HeikinAshiOscillator struct { + handle *C.struct_HeikinAshiOscillator +} + +// NewHeikinAshiOscillator constructs a HeikinAshiOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHeikinAshiOscillator(period int) (*HeikinAshiOscillator, error) { + ptr := C.wickra_heikin_ashi_oscillator_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HeikinAshiOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*HeikinAshiOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HeikinAshiOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_heikin_ashi_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HeikinAshiOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_heikin_ashi_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HeikinAshiOscillator) Reset() { + C.wickra_heikin_ashi_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HeikinAshiOscillator) Close() { + if ind.handle != nil { + C.wickra_heikin_ashi_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HiLoActivator wraps the HiLoActivator indicator over the Wickra C ABI. +type HiLoActivator struct { + handle *C.struct_HiLoActivator +} + +// NewHiLoActivator constructs a HiLoActivator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHiLoActivator(period int) (*HiLoActivator, error) { + ptr := C.wickra_hi_lo_activator_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HiLoActivator{handle: ptr} + runtime.SetFinalizer(obj, (*HiLoActivator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HiLoActivator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_hi_lo_activator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HiLoActivator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hi_lo_activator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HiLoActivator) Reset() { + C.wickra_hi_lo_activator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HiLoActivator) Close() { + if ind.handle != nil { + C.wickra_hi_lo_activator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HighLowIndex wraps the HighLowIndex indicator over the Wickra C ABI. +type HighLowIndex struct { + handle *C.struct_HighLowIndex +} + +// NewHighLowIndex constructs a HighLowIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHighLowIndex(period int) (*HighLowIndex, error) { + ptr := C.wickra_high_low_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HighLowIndex{handle: ptr} + runtime.SetFinalizer(obj, (*HighLowIndex).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *HighLowIndex) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_high_low_index_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HighLowIndex) Reset() { + C.wickra_high_low_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HighLowIndex) Close() { + if ind.handle != nil { + C.wickra_high_low_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HighLowRange wraps the HighLowRange indicator over the Wickra C ABI. +type HighLowRange struct { + handle *C.struct_HighLowRange +} + +// NewHighLowRange constructs a HighLowRange. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHighLowRange() (*HighLowRange, error) { + ptr := C.wickra_high_low_range_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HighLowRange{handle: ptr} + runtime.SetFinalizer(obj, (*HighLowRange).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HighLowRange) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_high_low_range_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HighLowRange) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_high_low_range_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HighLowRange) Reset() { + C.wickra_high_low_range_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HighLowRange) Close() { + if ind.handle != nil { + C.wickra_high_low_range_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HighLowVolumeNodes wraps the HighLowVolumeNodes indicator over the Wickra C ABI. +type HighLowVolumeNodes struct { + handle *C.struct_HighLowVolumeNodes +} + +// NewHighLowVolumeNodes constructs a HighLowVolumeNodes. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHighLowVolumeNodes(period int, bins int) (*HighLowVolumeNodes, error) { + ptr := C.wickra_high_low_volume_nodes_new(C.uintptr_t(period), C.uintptr_t(bins)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HighLowVolumeNodes{handle: ptr} + runtime.SetFinalizer(obj, (*HighLowVolumeNodes).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *HighLowVolumeNodes) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (HighLowVolumeNodesOutput, bool) { + var out C.struct_WickraHighLowVolumeNodesOutput + ok := bool(C.wickra_high_low_volume_nodes_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return HighLowVolumeNodesOutput{}, false + } + return HighLowVolumeNodesOutput{float64(out.hvn), float64(out.lvn)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HighLowVolumeNodes) Reset() { + C.wickra_high_low_volume_nodes_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HighLowVolumeNodes) Close() { + if ind.handle != nil { + C.wickra_high_low_volume_nodes_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HighWave wraps the HighWave indicator over the Wickra C ABI. +type HighWave struct { + handle *C.struct_HighWave +} + +// NewHighWave constructs a HighWave. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHighWave() (*HighWave, error) { + ptr := C.wickra_high_wave_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HighWave{handle: ptr} + runtime.SetFinalizer(obj, (*HighWave).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HighWave) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_high_wave_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HighWave) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_high_wave_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HighWave) Reset() { + C.wickra_high_wave_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HighWave) Close() { + if ind.handle != nil { + C.wickra_high_wave_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HighpassFilter wraps the HighpassFilter indicator over the Wickra C ABI. +type HighpassFilter struct { + handle *C.struct_HighpassFilter +} + +// NewHighpassFilter constructs a HighpassFilter. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHighpassFilter(period int) (*HighpassFilter, error) { + ptr := C.wickra_highpass_filter_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HighpassFilter{handle: ptr} + runtime.SetFinalizer(obj, (*HighpassFilter).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HighpassFilter) Update(value float64) float64 { + r := float64(C.wickra_highpass_filter_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HighpassFilter) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_highpass_filter_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HighpassFilter) Reset() { + C.wickra_highpass_filter_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HighpassFilter) Close() { + if ind.handle != nil { + C.wickra_highpass_filter_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Hikkake wraps the Hikkake indicator over the Wickra C ABI. +type Hikkake struct { + handle *C.struct_Hikkake +} + +// NewHikkake constructs a Hikkake. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHikkake() (*Hikkake, error) { + ptr := C.wickra_hikkake_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Hikkake{handle: ptr} + runtime.SetFinalizer(obj, (*Hikkake).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Hikkake) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_hikkake_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Hikkake) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hikkake_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Hikkake) Reset() { + C.wickra_hikkake_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Hikkake) Close() { + if ind.handle != nil { + C.wickra_hikkake_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HikkakeModified wraps the HikkakeModified indicator over the Wickra C ABI. +type HikkakeModified struct { + handle *C.struct_HikkakeModified +} + +// NewHikkakeModified constructs a HikkakeModified. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHikkakeModified() (*HikkakeModified, error) { + ptr := C.wickra_hikkake_modified_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HikkakeModified{handle: ptr} + runtime.SetFinalizer(obj, (*HikkakeModified).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HikkakeModified) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_hikkake_modified_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HikkakeModified) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hikkake_modified_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HikkakeModified) Reset() { + C.wickra_hikkake_modified_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HikkakeModified) Close() { + if ind.handle != nil { + C.wickra_hikkake_modified_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HilbertDominantCycle wraps the HilbertDominantCycle indicator over the Wickra C ABI. +type HilbertDominantCycle struct { + handle *C.struct_HilbertDominantCycle +} + +// NewHilbertDominantCycle constructs a HilbertDominantCycle. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHilbertDominantCycle() (*HilbertDominantCycle, error) { + ptr := C.wickra_hilbert_dominant_cycle_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HilbertDominantCycle{handle: ptr} + runtime.SetFinalizer(obj, (*HilbertDominantCycle).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HilbertDominantCycle) Update(value float64) float64 { + r := float64(C.wickra_hilbert_dominant_cycle_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HilbertDominantCycle) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hilbert_dominant_cycle_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HilbertDominantCycle) Reset() { + C.wickra_hilbert_dominant_cycle_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HilbertDominantCycle) Close() { + if ind.handle != nil { + C.wickra_hilbert_dominant_cycle_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HistoricalVolatility wraps the HistoricalVolatility indicator over the Wickra C ABI. +type HistoricalVolatility struct { + handle *C.struct_HistoricalVolatility +} + +// NewHistoricalVolatility constructs a HistoricalVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHistoricalVolatility(period int, tradingPeriods int) (*HistoricalVolatility, error) { + ptr := C.wickra_historical_volatility_new(C.uintptr_t(period), C.uintptr_t(tradingPeriods)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HistoricalVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*HistoricalVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HistoricalVolatility) Update(value float64) float64 { + r := float64(C.wickra_historical_volatility_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HistoricalVolatility) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_historical_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HistoricalVolatility) Reset() { + C.wickra_historical_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HistoricalVolatility) Close() { + if ind.handle != nil { + C.wickra_historical_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Hma wraps the Hma indicator over the Wickra C ABI. +type Hma struct { + handle *C.struct_Hma +} + +// NewHma constructs a Hma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHma(period int) (*Hma, error) { + ptr := C.wickra_hma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Hma{handle: ptr} + runtime.SetFinalizer(obj, (*Hma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Hma) Update(value float64) float64 { + r := float64(C.wickra_hma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Hma) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Hma) Reset() { + C.wickra_hma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Hma) Close() { + if ind.handle != nil { + C.wickra_hma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HoltWinters wraps the HoltWinters indicator over the Wickra C ABI. +type HoltWinters struct { + handle *C.struct_HoltWinters +} + +// NewHoltWinters constructs a HoltWinters. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHoltWinters(alpha float64, beta float64) (*HoltWinters, error) { + ptr := C.wickra_holt_winters_new(C.double(alpha), C.double(beta)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HoltWinters{handle: ptr} + runtime.SetFinalizer(obj, (*HoltWinters).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HoltWinters) Update(value float64) float64 { + r := float64(C.wickra_holt_winters_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HoltWinters) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_holt_winters_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HoltWinters) Reset() { + C.wickra_holt_winters_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HoltWinters) Close() { + if ind.handle != nil { + C.wickra_holt_winters_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HomingPigeon wraps the HomingPigeon indicator over the Wickra C ABI. +type HomingPigeon struct { + handle *C.struct_HomingPigeon +} + +// NewHomingPigeon constructs a HomingPigeon. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHomingPigeon() (*HomingPigeon, error) { + ptr := C.wickra_homing_pigeon_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HomingPigeon{handle: ptr} + runtime.SetFinalizer(obj, (*HomingPigeon).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HomingPigeon) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_homing_pigeon_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HomingPigeon) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_homing_pigeon_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HomingPigeon) Reset() { + C.wickra_homing_pigeon_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HomingPigeon) Close() { + if ind.handle != nil { + C.wickra_homing_pigeon_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HtDcPhase wraps the HtDcPhase indicator over the Wickra C ABI. +type HtDcPhase struct { + handle *C.struct_HtDcPhase +} + +// NewHtDcPhase constructs a HtDcPhase. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHtDcPhase() (*HtDcPhase, error) { + ptr := C.wickra_ht_dc_phase_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HtDcPhase{handle: ptr} + runtime.SetFinalizer(obj, (*HtDcPhase).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HtDcPhase) Update(value float64) float64 { + r := float64(C.wickra_ht_dc_phase_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HtDcPhase) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ht_dc_phase_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HtDcPhase) Reset() { + C.wickra_ht_dc_phase_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HtDcPhase) Close() { + if ind.handle != nil { + C.wickra_ht_dc_phase_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HtPhasor wraps the HtPhasor indicator over the Wickra C ABI. +type HtPhasor struct { + handle *C.struct_HtPhasor +} + +// NewHtPhasor constructs a HtPhasor. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHtPhasor() (*HtPhasor, error) { + ptr := C.wickra_ht_phasor_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HtPhasor{handle: ptr} + runtime.SetFinalizer(obj, (*HtPhasor).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *HtPhasor) Update(value float64) (HtPhasorOutput, bool) { + var out C.struct_WickraHtPhasorOutput + ok := bool(C.wickra_ht_phasor_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return HtPhasorOutput{}, false + } + return HtPhasorOutput{float64(out.inphase), float64(out.quadrature)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HtPhasor) Reset() { + C.wickra_ht_phasor_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HtPhasor) Close() { + if ind.handle != nil { + C.wickra_ht_phasor_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HtTrendMode wraps the HtTrendMode indicator over the Wickra C ABI. +type HtTrendMode struct { + handle *C.struct_HtTrendMode +} + +// NewHtTrendMode constructs a HtTrendMode. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHtTrendMode() (*HtTrendMode, error) { + ptr := C.wickra_ht_trend_mode_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HtTrendMode{handle: ptr} + runtime.SetFinalizer(obj, (*HtTrendMode).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HtTrendMode) Update(value float64) float64 { + r := float64(C.wickra_ht_trend_mode_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HtTrendMode) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ht_trend_mode_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HtTrendMode) Reset() { + C.wickra_ht_trend_mode_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HtTrendMode) Close() { + if ind.handle != nil { + C.wickra_ht_trend_mode_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HurstChannel wraps the HurstChannel indicator over the Wickra C ABI. +type HurstChannel struct { + handle *C.struct_HurstChannel +} + +// NewHurstChannel constructs a HurstChannel. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHurstChannel(period int, multiplier float64) (*HurstChannel, error) { + ptr := C.wickra_hurst_channel_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HurstChannel{handle: ptr} + runtime.SetFinalizer(obj, (*HurstChannel).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *HurstChannel) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (HurstChannelOutput, bool) { + var out C.struct_WickraHurstChannelOutput + ok := bool(C.wickra_hurst_channel_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return HurstChannelOutput{}, false + } + return HurstChannelOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HurstChannel) Reset() { + C.wickra_hurst_channel_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HurstChannel) Close() { + if ind.handle != nil { + C.wickra_hurst_channel_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// HurstExponent wraps the HurstExponent indicator over the Wickra C ABI. +type HurstExponent struct { + handle *C.struct_HurstExponent +} + +// NewHurstExponent constructs a HurstExponent. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewHurstExponent(period int, chunks int) (*HurstExponent, error) { + ptr := C.wickra_hurst_exponent_new(C.uintptr_t(period), C.uintptr_t(chunks)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &HurstExponent{handle: ptr} + runtime.SetFinalizer(obj, (*HurstExponent).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *HurstExponent) Update(value float64) float64 { + r := float64(C.wickra_hurst_exponent_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *HurstExponent) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_hurst_exponent_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *HurstExponent) Reset() { + C.wickra_hurst_exponent_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *HurstExponent) Close() { + if ind.handle != nil { + C.wickra_hurst_exponent_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Ichimoku wraps the Ichimoku indicator over the Wickra C ABI. +type Ichimoku struct { + handle *C.struct_Ichimoku +} + +// NewIchimoku constructs a Ichimoku. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewIchimoku(tenkanPeriod int, kijunPeriod int, senkouBPeriod int, displacement int) (*Ichimoku, error) { + ptr := C.wickra_ichimoku_new(C.uintptr_t(tenkanPeriod), C.uintptr_t(kijunPeriod), C.uintptr_t(senkouBPeriod), C.uintptr_t(displacement)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Ichimoku{handle: ptr} + runtime.SetFinalizer(obj, (*Ichimoku).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Ichimoku) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (IchimokuOutput, bool) { + var out C.struct_WickraIchimokuOutput + ok := bool(C.wickra_ichimoku_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return IchimokuOutput{}, false + } + return IchimokuOutput{float64(out.tenkan), float64(out.kijun), float64(out.senkou_a), float64(out.senkou_b), float64(out.chikou)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Ichimoku) Reset() { + C.wickra_ichimoku_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Ichimoku) Close() { + if ind.handle != nil { + C.wickra_ichimoku_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// IdenticalThreeCrows wraps the IdenticalThreeCrows indicator over the Wickra C ABI. +type IdenticalThreeCrows struct { + handle *C.struct_IdenticalThreeCrows +} + +// NewIdenticalThreeCrows constructs a IdenticalThreeCrows. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewIdenticalThreeCrows() (*IdenticalThreeCrows, error) { + ptr := C.wickra_identical_three_crows_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &IdenticalThreeCrows{handle: ptr} + runtime.SetFinalizer(obj, (*IdenticalThreeCrows).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *IdenticalThreeCrows) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_identical_three_crows_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *IdenticalThreeCrows) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_identical_three_crows_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *IdenticalThreeCrows) Reset() { + C.wickra_identical_three_crows_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *IdenticalThreeCrows) Close() { + if ind.handle != nil { + C.wickra_identical_three_crows_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ImbalanceBars wraps the ImbalanceBars indicator over the Wickra C ABI. +type ImbalanceBars struct { + handle *C.struct_ImbalanceBars +} + +// NewImbalanceBars constructs a ImbalanceBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewImbalanceBars(threshold float64) (*ImbalanceBars, error) { + ptr := C.wickra_imbalance_bars_new(C.double(threshold)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ImbalanceBars{handle: ptr} + runtime.SetFinalizer(obj, (*ImbalanceBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *ImbalanceBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []ImbalanceBar { + const capacity = 64 + var buf [capacity]C.struct_WickraImbalanceBar + n := int(C.wickra_imbalance_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]ImbalanceBar, n) + for i := 0; i < n; i++ { + out[i] = ImbalanceBar{float64(buf[i].open), float64(buf[i].high), float64(buf[i].low), float64(buf[i].close), float64(buf[i].imbalance), int8(buf[i].direction)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ImbalanceBars) Reset() { + C.wickra_imbalance_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ImbalanceBars) Close() { + if ind.handle != nil { + C.wickra_imbalance_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// InNeck wraps the InNeck indicator over the Wickra C ABI. +type InNeck struct { + handle *C.struct_InNeck +} + +// NewInNeck constructs a InNeck. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewInNeck() (*InNeck, error) { + ptr := C.wickra_in_neck_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &InNeck{handle: ptr} + runtime.SetFinalizer(obj, (*InNeck).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *InNeck) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_in_neck_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *InNeck) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_in_neck_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *InNeck) Reset() { + C.wickra_in_neck_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *InNeck) Close() { + if ind.handle != nil { + C.wickra_in_neck_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Inertia wraps the Inertia indicator over the Wickra C ABI. +type Inertia struct { + handle *C.struct_Inertia +} + +// NewInertia constructs a Inertia. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewInertia(rviPeriod int, linregPeriod int) (*Inertia, error) { + ptr := C.wickra_inertia_new(C.uintptr_t(rviPeriod), C.uintptr_t(linregPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Inertia{handle: ptr} + runtime.SetFinalizer(obj, (*Inertia).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Inertia) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_inertia_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Inertia) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_inertia_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Inertia) Reset() { + C.wickra_inertia_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Inertia) Close() { + if ind.handle != nil { + C.wickra_inertia_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// InformationRatio wraps the InformationRatio indicator over the Wickra C ABI. +type InformationRatio struct { + handle *C.struct_InformationRatio +} + +// NewInformationRatio constructs a InformationRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewInformationRatio(period int) (*InformationRatio, error) { + ptr := C.wickra_information_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &InformationRatio{handle: ptr} + runtime.SetFinalizer(obj, (*InformationRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *InformationRatio) Update(x float64, y float64) float64 { + r := float64(C.wickra_information_ratio_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *InformationRatio) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_information_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *InformationRatio) Reset() { + C.wickra_information_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *InformationRatio) Close() { + if ind.handle != nil { + C.wickra_information_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// InitialBalance wraps the InitialBalance indicator over the Wickra C ABI. +type InitialBalance struct { + handle *C.struct_InitialBalance +} + +// NewInitialBalance constructs a InitialBalance. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewInitialBalance(period int) (*InitialBalance, error) { + ptr := C.wickra_initial_balance_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &InitialBalance{handle: ptr} + runtime.SetFinalizer(obj, (*InitialBalance).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *InitialBalance) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (InitialBalanceOutput, bool) { + var out C.struct_WickraInitialBalanceOutput + ok := bool(C.wickra_initial_balance_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return InitialBalanceOutput{}, false + } + return InitialBalanceOutput{float64(out.high), float64(out.low)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *InitialBalance) Reset() { + C.wickra_initial_balance_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *InitialBalance) Close() { + if ind.handle != nil { + C.wickra_initial_balance_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// InstantaneousTrendline wraps the InstantaneousTrendline indicator over the Wickra C ABI. +type InstantaneousTrendline struct { + handle *C.struct_InstantaneousTrendline +} + +// NewInstantaneousTrendline constructs a InstantaneousTrendline. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewInstantaneousTrendline(period int) (*InstantaneousTrendline, error) { + ptr := C.wickra_instantaneous_trendline_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &InstantaneousTrendline{handle: ptr} + runtime.SetFinalizer(obj, (*InstantaneousTrendline).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *InstantaneousTrendline) Update(value float64) float64 { + r := float64(C.wickra_instantaneous_trendline_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *InstantaneousTrendline) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_instantaneous_trendline_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *InstantaneousTrendline) Reset() { + C.wickra_instantaneous_trendline_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *InstantaneousTrendline) Close() { + if ind.handle != nil { + C.wickra_instantaneous_trendline_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// IntradayIntensity wraps the IntradayIntensity indicator over the Wickra C ABI. +type IntradayIntensity struct { + handle *C.struct_IntradayIntensity +} + +// NewIntradayIntensity constructs a IntradayIntensity. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewIntradayIntensity() (*IntradayIntensity, error) { + ptr := C.wickra_intraday_intensity_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &IntradayIntensity{handle: ptr} + runtime.SetFinalizer(obj, (*IntradayIntensity).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *IntradayIntensity) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_intraday_intensity_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *IntradayIntensity) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_intraday_intensity_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *IntradayIntensity) Reset() { + C.wickra_intraday_intensity_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *IntradayIntensity) Close() { + if ind.handle != nil { + C.wickra_intraday_intensity_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// IntradayMomentumIndex wraps the IntradayMomentumIndex indicator over the Wickra C ABI. +type IntradayMomentumIndex struct { + handle *C.struct_IntradayMomentumIndex +} + +// NewIntradayMomentumIndex constructs a IntradayMomentumIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewIntradayMomentumIndex(period int) (*IntradayMomentumIndex, error) { + ptr := C.wickra_intraday_momentum_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &IntradayMomentumIndex{handle: ptr} + runtime.SetFinalizer(obj, (*IntradayMomentumIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *IntradayMomentumIndex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_intraday_momentum_index_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *IntradayMomentumIndex) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_intraday_momentum_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *IntradayMomentumIndex) Reset() { + C.wickra_intraday_momentum_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *IntradayMomentumIndex) Close() { + if ind.handle != nil { + C.wickra_intraday_momentum_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// IntradayVolatilityProfile wraps the IntradayVolatilityProfile indicator over the Wickra C ABI. +type IntradayVolatilityProfile struct { + handle *C.struct_IntradayVolatilityProfile + valuesCap int +} + +// NewIntradayVolatilityProfile constructs a IntradayVolatilityProfile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewIntradayVolatilityProfile(buckets int, utcOffsetMinutes int32) (*IntradayVolatilityProfile, error) { + ptr := C.wickra_intraday_volatility_profile_new(C.uintptr_t(buckets), C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &IntradayVolatilityProfile{handle: ptr} + obj.valuesCap = buckets + runtime.SetFinalizer(obj, (*IntradayVolatilityProfile).Close) + return obj, nil +} + +// Update feeds one observation and returns the profile values +// (ok is false during warmup). +func (ind *IntradayVolatilityProfile) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) ([]float64, bool) { + values := make([]float64, ind.valuesCap) + n := int(C.wickra_intraday_volatility_profile_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), (*C.double)(unsafe.Pointer(&values[0])), C.uintptr_t(len(values)))) + runtime.KeepAlive(ind) + if n < 0 { + return nil, false + } + return values[:n], true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *IntradayVolatilityProfile) Reset() { + C.wickra_intraday_volatility_profile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *IntradayVolatilityProfile) Close() { + if ind.handle != nil { + C.wickra_intraday_volatility_profile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// InverseFisherTransform wraps the InverseFisherTransform indicator over the Wickra C ABI. +type InverseFisherTransform struct { + handle *C.struct_InverseFisherTransform +} + +// NewInverseFisherTransform constructs a InverseFisherTransform. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewInverseFisherTransform(scale float64) (*InverseFisherTransform, error) { + ptr := C.wickra_inverse_fisher_transform_new(C.double(scale)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &InverseFisherTransform{handle: ptr} + runtime.SetFinalizer(obj, (*InverseFisherTransform).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *InverseFisherTransform) Update(value float64) float64 { + r := float64(C.wickra_inverse_fisher_transform_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *InverseFisherTransform) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_inverse_fisher_transform_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *InverseFisherTransform) Reset() { + C.wickra_inverse_fisher_transform_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *InverseFisherTransform) Close() { + if ind.handle != nil { + C.wickra_inverse_fisher_transform_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// InvertedHammer wraps the InvertedHammer indicator over the Wickra C ABI. +type InvertedHammer struct { + handle *C.struct_InvertedHammer +} + +// NewInvertedHammer constructs a InvertedHammer. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewInvertedHammer() (*InvertedHammer, error) { + ptr := C.wickra_inverted_hammer_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &InvertedHammer{handle: ptr} + runtime.SetFinalizer(obj, (*InvertedHammer).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *InvertedHammer) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_inverted_hammer_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *InvertedHammer) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_inverted_hammer_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *InvertedHammer) Reset() { + C.wickra_inverted_hammer_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *InvertedHammer) Close() { + if ind.handle != nil { + C.wickra_inverted_hammer_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// JarqueBera wraps the JarqueBera indicator over the Wickra C ABI. +type JarqueBera struct { + handle *C.struct_JarqueBera +} + +// NewJarqueBera constructs a JarqueBera. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewJarqueBera(period int) (*JarqueBera, error) { + ptr := C.wickra_jarque_bera_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &JarqueBera{handle: ptr} + runtime.SetFinalizer(obj, (*JarqueBera).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *JarqueBera) Update(value float64) float64 { + r := float64(C.wickra_jarque_bera_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *JarqueBera) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_jarque_bera_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *JarqueBera) Reset() { + C.wickra_jarque_bera_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *JarqueBera) Close() { + if ind.handle != nil { + C.wickra_jarque_bera_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Jma wraps the Jma indicator over the Wickra C ABI. +type Jma struct { + handle *C.struct_Jma +} + +// NewJma constructs a Jma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewJma(period int, phase float64, power uint32) (*Jma, error) { + ptr := C.wickra_jma_new(C.uintptr_t(period), C.double(phase), C.uint32_t(power)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Jma{handle: ptr} + runtime.SetFinalizer(obj, (*Jma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Jma) Update(value float64) float64 { + r := float64(C.wickra_jma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Jma) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_jma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Jma) Reset() { + C.wickra_jma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Jma) Close() { + if ind.handle != nil { + C.wickra_jma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// JumpIndicator wraps the JumpIndicator indicator over the Wickra C ABI. +type JumpIndicator struct { + handle *C.struct_JumpIndicator +} + +// NewJumpIndicator constructs a JumpIndicator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewJumpIndicator(period int, threshold float64) (*JumpIndicator, error) { + ptr := C.wickra_jump_indicator_new(C.uintptr_t(period), C.double(threshold)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &JumpIndicator{handle: ptr} + runtime.SetFinalizer(obj, (*JumpIndicator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *JumpIndicator) Update(value float64) float64 { + r := float64(C.wickra_jump_indicator_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *JumpIndicator) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_jump_indicator_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *JumpIndicator) Reset() { + C.wickra_jump_indicator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *JumpIndicator) Close() { + if ind.handle != nil { + C.wickra_jump_indicator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KRatio wraps the KRatio indicator over the Wickra C ABI. +type KRatio struct { + handle *C.struct_KRatio +} + +// NewKRatio constructs a KRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKRatio(period int) (*KRatio, error) { + ptr := C.wickra_k_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KRatio{handle: ptr} + runtime.SetFinalizer(obj, (*KRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *KRatio) Update(value float64) float64 { + r := float64(C.wickra_k_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *KRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_k_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KRatio) Reset() { + C.wickra_k_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KRatio) Close() { + if ind.handle != nil { + C.wickra_k_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KagiBars wraps the KagiBars indicator over the Wickra C ABI. +type KagiBars struct { + handle *C.struct_KagiBars +} + +// NewKagiBars constructs a KagiBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKagiBars(reversal float64) (*KagiBars, error) { + ptr := C.wickra_kagi_bars_new(C.double(reversal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KagiBars{handle: ptr} + runtime.SetFinalizer(obj, (*KagiBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *KagiBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []KagiBar { + const capacity = 64 + var buf [capacity]C.struct_WickraKagiBar + n := int(C.wickra_kagi_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]KagiBar, n) + for i := 0; i < n; i++ { + out[i] = KagiBar{float64(buf[i].start), float64(buf[i].end), int8(buf[i].direction)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KagiBars) Reset() { + C.wickra_kagi_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KagiBars) Close() { + if ind.handle != nil { + C.wickra_kagi_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KalmanHedgeRatio wraps the KalmanHedgeRatio indicator over the Wickra C ABI. +type KalmanHedgeRatio struct { + handle *C.struct_KalmanHedgeRatio +} + +// NewKalmanHedgeRatio constructs a KalmanHedgeRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKalmanHedgeRatio(delta float64, observationVar float64) (*KalmanHedgeRatio, error) { + ptr := C.wickra_kalman_hedge_ratio_new(C.double(delta), C.double(observationVar)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KalmanHedgeRatio{handle: ptr} + runtime.SetFinalizer(obj, (*KalmanHedgeRatio).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *KalmanHedgeRatio) Update(x float64, y float64) (KalmanHedgeRatioOutput, bool) { + var out C.struct_WickraKalmanHedgeRatioOutput + ok := bool(C.wickra_kalman_hedge_ratio_update(ind.handle, C.double(x), C.double(y), &out)) + runtime.KeepAlive(ind) + if !ok { + return KalmanHedgeRatioOutput{}, false + } + return KalmanHedgeRatioOutput{float64(out.hedge_ratio), float64(out.intercept), float64(out.spread)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KalmanHedgeRatio) Reset() { + C.wickra_kalman_hedge_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KalmanHedgeRatio) Close() { + if ind.handle != nil { + C.wickra_kalman_hedge_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Kama wraps the Kama indicator over the Wickra C ABI. +type Kama struct { + handle *C.struct_Kama +} + +// NewKama constructs a Kama. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKama(erPeriod int, fast int, slow int) (*Kama, error) { + ptr := C.wickra_kama_new(C.uintptr_t(erPeriod), C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Kama{handle: ptr} + runtime.SetFinalizer(obj, (*Kama).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Kama) Update(value float64) float64 { + r := float64(C.wickra_kama_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Kama) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_kama_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Kama) Reset() { + C.wickra_kama_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Kama) Close() { + if ind.handle != nil { + C.wickra_kama_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KaseDevStop wraps the KaseDevStop indicator over the Wickra C ABI. +type KaseDevStop struct { + handle *C.struct_KaseDevStop +} + +// NewKaseDevStop constructs a KaseDevStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKaseDevStop(period int, dev float64) (*KaseDevStop, error) { + ptr := C.wickra_kase_dev_stop_new(C.uintptr_t(period), C.double(dev)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KaseDevStop{handle: ptr} + runtime.SetFinalizer(obj, (*KaseDevStop).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *KaseDevStop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (KaseDevStopOutput, bool) { + var out C.struct_WickraKaseDevStopOutput + ok := bool(C.wickra_kase_dev_stop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return KaseDevStopOutput{}, false + } + return KaseDevStopOutput{float64(out.value), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KaseDevStop) Reset() { + C.wickra_kase_dev_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KaseDevStop) Close() { + if ind.handle != nil { + C.wickra_kase_dev_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KasePermissionStochastic wraps the KasePermissionStochastic indicator over the Wickra C ABI. +type KasePermissionStochastic struct { + handle *C.struct_KasePermissionStochastic +} + +// NewKasePermissionStochastic constructs a KasePermissionStochastic. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKasePermissionStochastic(length int, smooth int) (*KasePermissionStochastic, error) { + ptr := C.wickra_kase_permission_stochastic_new(C.uintptr_t(length), C.uintptr_t(smooth)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KasePermissionStochastic{handle: ptr} + runtime.SetFinalizer(obj, (*KasePermissionStochastic).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *KasePermissionStochastic) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (KasePermissionStochasticOutput, bool) { + var out C.struct_WickraKasePermissionStochasticOutput + ok := bool(C.wickra_kase_permission_stochastic_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return KasePermissionStochasticOutput{}, false + } + return KasePermissionStochasticOutput{float64(out.fast), float64(out.slow)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KasePermissionStochastic) Reset() { + C.wickra_kase_permission_stochastic_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KasePermissionStochastic) Close() { + if ind.handle != nil { + C.wickra_kase_permission_stochastic_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KellyCriterion wraps the KellyCriterion indicator over the Wickra C ABI. +type KellyCriterion struct { + handle *C.struct_KellyCriterion +} + +// NewKellyCriterion constructs a KellyCriterion. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKellyCriterion(period int) (*KellyCriterion, error) { + ptr := C.wickra_kelly_criterion_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KellyCriterion{handle: ptr} + runtime.SetFinalizer(obj, (*KellyCriterion).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *KellyCriterion) Update(value float64) float64 { + r := float64(C.wickra_kelly_criterion_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *KellyCriterion) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_kelly_criterion_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KellyCriterion) Reset() { + C.wickra_kelly_criterion_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KellyCriterion) Close() { + if ind.handle != nil { + C.wickra_kelly_criterion_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Keltner wraps the Keltner indicator over the Wickra C ABI. +type Keltner struct { + handle *C.struct_Keltner +} + +// NewKeltner constructs a Keltner. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKeltner(emaPeriod int, atrPeriod int, multiplier float64) (*Keltner, error) { + ptr := C.wickra_keltner_new(C.uintptr_t(emaPeriod), C.uintptr_t(atrPeriod), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Keltner{handle: ptr} + runtime.SetFinalizer(obj, (*Keltner).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Keltner) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (KeltnerOutput, bool) { + var out C.struct_WickraKeltnerOutput + ok := bool(C.wickra_keltner_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return KeltnerOutput{}, false + } + return KeltnerOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Keltner) Reset() { + C.wickra_keltner_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Keltner) Close() { + if ind.handle != nil { + C.wickra_keltner_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KendallTau wraps the KendallTau indicator over the Wickra C ABI. +type KendallTau struct { + handle *C.struct_KendallTau +} + +// NewKendallTau constructs a KendallTau. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKendallTau(period int) (*KendallTau, error) { + ptr := C.wickra_kendall_tau_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KendallTau{handle: ptr} + runtime.SetFinalizer(obj, (*KendallTau).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *KendallTau) Update(x float64, y float64) float64 { + r := float64(C.wickra_kendall_tau_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *KendallTau) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_kendall_tau_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KendallTau) Reset() { + C.wickra_kendall_tau_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KendallTau) Close() { + if ind.handle != nil { + C.wickra_kendall_tau_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Kicking wraps the Kicking indicator over the Wickra C ABI. +type Kicking struct { + handle *C.struct_Kicking +} + +// NewKicking constructs a Kicking. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKicking() (*Kicking, error) { + ptr := C.wickra_kicking_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Kicking{handle: ptr} + runtime.SetFinalizer(obj, (*Kicking).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Kicking) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_kicking_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Kicking) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_kicking_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Kicking) Reset() { + C.wickra_kicking_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Kicking) Close() { + if ind.handle != nil { + C.wickra_kicking_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KickingByLength wraps the KickingByLength indicator over the Wickra C ABI. +type KickingByLength struct { + handle *C.struct_KickingByLength +} + +// NewKickingByLength constructs a KickingByLength. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKickingByLength() (*KickingByLength, error) { + ptr := C.wickra_kicking_by_length_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KickingByLength{handle: ptr} + runtime.SetFinalizer(obj, (*KickingByLength).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *KickingByLength) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_kicking_by_length_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *KickingByLength) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_kicking_by_length_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KickingByLength) Reset() { + C.wickra_kicking_by_length_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KickingByLength) Close() { + if ind.handle != nil { + C.wickra_kicking_by_length_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Kst wraps the Kst indicator over the Wickra C ABI. +type Kst struct { + handle *C.struct_Kst +} + +// NewKst constructs a Kst. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKst(roc1 int, roc2 int, roc3 int, roc4 int, sma1 int, sma2 int, sma3 int, sma4 int, signal int) (*Kst, error) { + ptr := C.wickra_kst_new(C.uintptr_t(roc1), C.uintptr_t(roc2), C.uintptr_t(roc3), C.uintptr_t(roc4), C.uintptr_t(sma1), C.uintptr_t(sma2), C.uintptr_t(sma3), C.uintptr_t(sma4), C.uintptr_t(signal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Kst{handle: ptr} + runtime.SetFinalizer(obj, (*Kst).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Kst) Update(value float64) (KstOutput, bool) { + var out C.struct_WickraKstOutput + ok := bool(C.wickra_kst_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return KstOutput{}, false + } + return KstOutput{float64(out.kst), float64(out.signal)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Kst) Reset() { + C.wickra_kst_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Kst) Close() { + if ind.handle != nil { + C.wickra_kst_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Kurtosis wraps the Kurtosis indicator over the Wickra C ABI. +type Kurtosis struct { + handle *C.struct_Kurtosis +} + +// NewKurtosis constructs a Kurtosis. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKurtosis(period int) (*Kurtosis, error) { + ptr := C.wickra_kurtosis_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Kurtosis{handle: ptr} + runtime.SetFinalizer(obj, (*Kurtosis).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Kurtosis) Update(value float64) float64 { + r := float64(C.wickra_kurtosis_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Kurtosis) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_kurtosis_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Kurtosis) Reset() { + C.wickra_kurtosis_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Kurtosis) Close() { + if ind.handle != nil { + C.wickra_kurtosis_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Kvo wraps the Kvo indicator over the Wickra C ABI. +type Kvo struct { + handle *C.struct_Kvo +} + +// NewKvo constructs a Kvo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKvo(fast int, slow int) (*Kvo, error) { + ptr := C.wickra_kvo_new(C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Kvo{handle: ptr} + runtime.SetFinalizer(obj, (*Kvo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Kvo) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_kvo_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Kvo) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_kvo_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Kvo) Reset() { + C.wickra_kvo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Kvo) Close() { + if ind.handle != nil { + C.wickra_kvo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// KylesLambda wraps the KylesLambda indicator over the Wickra C ABI. +type KylesLambda struct { + handle *C.struct_KylesLambda +} + +// NewKylesLambda constructs a KylesLambda. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewKylesLambda(window int) (*KylesLambda, error) { + ptr := C.wickra_kyles_lambda_new(C.uintptr_t(window)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &KylesLambda{handle: ptr} + runtime.SetFinalizer(obj, (*KylesLambda).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *KylesLambda) Update(price float64, size float64, isBuy bool, timestamp int64, mid float64) float64 { + r := float64(C.wickra_kyles_lambda_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp), C.double(mid))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *KylesLambda) Reset() { + C.wickra_kyles_lambda_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *KylesLambda) Close() { + if ind.handle != nil { + C.wickra_kyles_lambda_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LadderBottom wraps the LadderBottom indicator over the Wickra C ABI. +type LadderBottom struct { + handle *C.struct_LadderBottom +} + +// NewLadderBottom constructs a LadderBottom. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLadderBottom() (*LadderBottom, error) { + ptr := C.wickra_ladder_bottom_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LadderBottom{handle: ptr} + runtime.SetFinalizer(obj, (*LadderBottom).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LadderBottom) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_ladder_bottom_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LadderBottom) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ladder_bottom_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LadderBottom) Reset() { + C.wickra_ladder_bottom_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LadderBottom) Close() { + if ind.handle != nil { + C.wickra_ladder_bottom_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LaguerreRsi wraps the LaguerreRsi indicator over the Wickra C ABI. +type LaguerreRsi struct { + handle *C.struct_LaguerreRsi +} + +// NewLaguerreRsi constructs a LaguerreRsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLaguerreRsi(gamma float64) (*LaguerreRsi, error) { + ptr := C.wickra_laguerre_rsi_new(C.double(gamma)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LaguerreRsi{handle: ptr} + runtime.SetFinalizer(obj, (*LaguerreRsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LaguerreRsi) Update(value float64) float64 { + r := float64(C.wickra_laguerre_rsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LaguerreRsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_laguerre_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LaguerreRsi) Reset() { + C.wickra_laguerre_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LaguerreRsi) Close() { + if ind.handle != nil { + C.wickra_laguerre_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LeadLagCrossCorrelation wraps the LeadLagCrossCorrelation indicator over the Wickra C ABI. +type LeadLagCrossCorrelation struct { + handle *C.struct_LeadLagCrossCorrelation +} + +// NewLeadLagCrossCorrelation constructs a LeadLagCrossCorrelation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLeadLagCrossCorrelation(window int, maxLag int) (*LeadLagCrossCorrelation, error) { + ptr := C.wickra_lead_lag_cross_correlation_new(C.uintptr_t(window), C.uintptr_t(maxLag)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LeadLagCrossCorrelation{handle: ptr} + runtime.SetFinalizer(obj, (*LeadLagCrossCorrelation).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *LeadLagCrossCorrelation) Update(x float64, y float64) (LeadLagCrossCorrelationOutput, bool) { + var out C.struct_WickraLeadLagCrossCorrelationOutput + ok := bool(C.wickra_lead_lag_cross_correlation_update(ind.handle, C.double(x), C.double(y), &out)) + runtime.KeepAlive(ind) + if !ok { + return LeadLagCrossCorrelationOutput{}, false + } + return LeadLagCrossCorrelationOutput{int64(out.lag), float64(out.correlation)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LeadLagCrossCorrelation) Reset() { + C.wickra_lead_lag_cross_correlation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LeadLagCrossCorrelation) Close() { + if ind.handle != nil { + C.wickra_lead_lag_cross_correlation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LinRegAngle wraps the LinRegAngle indicator over the Wickra C ABI. +type LinRegAngle struct { + handle *C.struct_LinRegAngle +} + +// NewLinRegAngle constructs a LinRegAngle. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLinRegAngle(period int) (*LinRegAngle, error) { + ptr := C.wickra_lin_reg_angle_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LinRegAngle{handle: ptr} + runtime.SetFinalizer(obj, (*LinRegAngle).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LinRegAngle) Update(value float64) float64 { + r := float64(C.wickra_lin_reg_angle_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LinRegAngle) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_lin_reg_angle_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LinRegAngle) Reset() { + C.wickra_lin_reg_angle_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LinRegAngle) Close() { + if ind.handle != nil { + C.wickra_lin_reg_angle_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LinRegChannel wraps the LinRegChannel indicator over the Wickra C ABI. +type LinRegChannel struct { + handle *C.struct_LinRegChannel +} + +// NewLinRegChannel constructs a LinRegChannel. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLinRegChannel(period int, multiplier float64) (*LinRegChannel, error) { + ptr := C.wickra_lin_reg_channel_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LinRegChannel{handle: ptr} + runtime.SetFinalizer(obj, (*LinRegChannel).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *LinRegChannel) Update(value float64) (LinRegChannelOutput, bool) { + var out C.struct_WickraLinRegChannelOutput + ok := bool(C.wickra_lin_reg_channel_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return LinRegChannelOutput{}, false + } + return LinRegChannelOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LinRegChannel) Reset() { + C.wickra_lin_reg_channel_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LinRegChannel) Close() { + if ind.handle != nil { + C.wickra_lin_reg_channel_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LinRegIntercept wraps the LinRegIntercept indicator over the Wickra C ABI. +type LinRegIntercept struct { + handle *C.struct_LinRegIntercept +} + +// NewLinRegIntercept constructs a LinRegIntercept. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLinRegIntercept(period int) (*LinRegIntercept, error) { + ptr := C.wickra_lin_reg_intercept_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LinRegIntercept{handle: ptr} + runtime.SetFinalizer(obj, (*LinRegIntercept).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LinRegIntercept) Update(value float64) float64 { + r := float64(C.wickra_lin_reg_intercept_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LinRegIntercept) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_lin_reg_intercept_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LinRegIntercept) Reset() { + C.wickra_lin_reg_intercept_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LinRegIntercept) Close() { + if ind.handle != nil { + C.wickra_lin_reg_intercept_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LinRegSlope wraps the LinRegSlope indicator over the Wickra C ABI. +type LinRegSlope struct { + handle *C.struct_LinRegSlope +} + +// NewLinRegSlope constructs a LinRegSlope. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLinRegSlope(period int) (*LinRegSlope, error) { + ptr := C.wickra_lin_reg_slope_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LinRegSlope{handle: ptr} + runtime.SetFinalizer(obj, (*LinRegSlope).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LinRegSlope) Update(value float64) float64 { + r := float64(C.wickra_lin_reg_slope_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LinRegSlope) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_lin_reg_slope_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LinRegSlope) Reset() { + C.wickra_lin_reg_slope_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LinRegSlope) Close() { + if ind.handle != nil { + C.wickra_lin_reg_slope_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LinearRegression wraps the LinearRegression indicator over the Wickra C ABI. +type LinearRegression struct { + handle *C.struct_LinearRegression +} + +// NewLinearRegression constructs a LinearRegression. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLinearRegression(period int) (*LinearRegression, error) { + ptr := C.wickra_linear_regression_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LinearRegression{handle: ptr} + runtime.SetFinalizer(obj, (*LinearRegression).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LinearRegression) Update(value float64) float64 { + r := float64(C.wickra_linear_regression_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LinearRegression) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_linear_regression_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LinearRegression) Reset() { + C.wickra_linear_regression_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LinearRegression) Close() { + if ind.handle != nil { + C.wickra_linear_regression_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LiquidationFeatures wraps the LiquidationFeatures indicator over the Wickra C ABI. +type LiquidationFeatures struct { + handle *C.struct_LiquidationFeatures +} + +// NewLiquidationFeatures constructs a LiquidationFeatures. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLiquidationFeatures() (*LiquidationFeatures, error) { + ptr := C.wickra_liquidation_features_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LiquidationFeatures{handle: ptr} + runtime.SetFinalizer(obj, (*LiquidationFeatures).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *LiquidationFeatures) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) (LiquidationFeaturesOutput, bool) { + var out C.struct_WickraLiquidationFeaturesOutput + ok := bool(C.wickra_liquidation_features_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return LiquidationFeaturesOutput{}, false + } + return LiquidationFeaturesOutput{float64(out.long_), float64(out.short_), float64(out.net), float64(out.total), float64(out.imbalance)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LiquidationFeatures) Reset() { + C.wickra_liquidation_features_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LiquidationFeatures) Close() { + if ind.handle != nil { + C.wickra_liquidation_features_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LogReturn wraps the LogReturn indicator over the Wickra C ABI. +type LogReturn struct { + handle *C.struct_LogReturn +} + +// NewLogReturn constructs a LogReturn. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLogReturn(period int) (*LogReturn, error) { + ptr := C.wickra_log_return_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LogReturn{handle: ptr} + runtime.SetFinalizer(obj, (*LogReturn).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LogReturn) Update(value float64) float64 { + r := float64(C.wickra_log_return_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LogReturn) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_log_return_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LogReturn) Reset() { + C.wickra_log_return_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LogReturn) Close() { + if ind.handle != nil { + C.wickra_log_return_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LongLeggedDoji wraps the LongLeggedDoji indicator over the Wickra C ABI. +type LongLeggedDoji struct { + handle *C.struct_LongLeggedDoji +} + +// NewLongLeggedDoji constructs a LongLeggedDoji. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLongLeggedDoji() (*LongLeggedDoji, error) { + ptr := C.wickra_long_legged_doji_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LongLeggedDoji{handle: ptr} + runtime.SetFinalizer(obj, (*LongLeggedDoji).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LongLeggedDoji) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_long_legged_doji_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LongLeggedDoji) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_long_legged_doji_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LongLeggedDoji) Reset() { + C.wickra_long_legged_doji_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LongLeggedDoji) Close() { + if ind.handle != nil { + C.wickra_long_legged_doji_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LongLine wraps the LongLine indicator over the Wickra C ABI. +type LongLine struct { + handle *C.struct_LongLine +} + +// NewLongLine constructs a LongLine. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLongLine() (*LongLine, error) { + ptr := C.wickra_long_line_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LongLine{handle: ptr} + runtime.SetFinalizer(obj, (*LongLine).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LongLine) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_long_line_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *LongLine) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_long_line_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LongLine) Reset() { + C.wickra_long_line_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LongLine) Close() { + if ind.handle != nil { + C.wickra_long_line_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// LongShortRatio wraps the LongShortRatio indicator over the Wickra C ABI. +type LongShortRatio struct { + handle *C.struct_LongShortRatio +} + +// NewLongShortRatio constructs a LongShortRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewLongShortRatio() (*LongShortRatio, error) { + ptr := C.wickra_long_short_ratio_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &LongShortRatio{handle: ptr} + runtime.SetFinalizer(obj, (*LongShortRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *LongShortRatio) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_long_short_ratio_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *LongShortRatio) Reset() { + C.wickra_long_short_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *LongShortRatio) Close() { + if ind.handle != nil { + C.wickra_long_short_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// M2Measure wraps the M2Measure indicator over the Wickra C ABI. +type M2Measure struct { + handle *C.struct_M2Measure +} + +// NewM2Measure constructs a M2Measure. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewM2Measure(period int, riskFree float64, benchmarkStddev float64) (*M2Measure, error) { + ptr := C.wickra_m2_measure_new(C.uintptr_t(period), C.double(riskFree), C.double(benchmarkStddev)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &M2Measure{handle: ptr} + runtime.SetFinalizer(obj, (*M2Measure).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *M2Measure) Update(value float64) float64 { + r := float64(C.wickra_m2_measure_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *M2Measure) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_m2_measure_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *M2Measure) Reset() { + C.wickra_m2_measure_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *M2Measure) Close() { + if ind.handle != nil { + C.wickra_m2_measure_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MaEnvelope wraps the MaEnvelope indicator over the Wickra C ABI. +type MaEnvelope struct { + handle *C.struct_MaEnvelope +} + +// NewMaEnvelope constructs a MaEnvelope. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMaEnvelope(period int, percent float64) (*MaEnvelope, error) { + ptr := C.wickra_ma_envelope_new(C.uintptr_t(period), C.double(percent)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MaEnvelope{handle: ptr} + runtime.SetFinalizer(obj, (*MaEnvelope).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *MaEnvelope) Update(value float64) (MaEnvelopeOutput, bool) { + var out C.struct_WickraMaEnvelopeOutput + ok := bool(C.wickra_ma_envelope_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return MaEnvelopeOutput{}, false + } + return MaEnvelopeOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MaEnvelope) Reset() { + C.wickra_ma_envelope_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MaEnvelope) Close() { + if ind.handle != nil { + C.wickra_ma_envelope_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MacdExt wraps the MacdExt indicator over the Wickra C ABI. +type MacdExt struct { + handle *C.struct_MacdExt +} + +// NewMacdExt constructs a MacdExt. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMacdExt(fast int, fastType uint8, slow int, slowType uint8, signal int, signalType uint8) (*MacdExt, error) { + ptr := C.wickra_macd_ext_new(C.uintptr_t(fast), C.uint8_t(fastType), C.uintptr_t(slow), C.uint8_t(slowType), C.uintptr_t(signal), C.uint8_t(signalType)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MacdExt{handle: ptr} + runtime.SetFinalizer(obj, (*MacdExt).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *MacdExt) Update(value float64) (MacdOutput, bool) { + var out C.struct_WickraMacdOutput + ok := bool(C.wickra_macd_ext_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return MacdOutput{}, false + } + return MacdOutput{float64(out.macd), float64(out.signal), float64(out.histogram)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MacdExt) Reset() { + C.wickra_macd_ext_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MacdExt) Close() { + if ind.handle != nil { + C.wickra_macd_ext_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MacdFix wraps the MacdFix indicator over the Wickra C ABI. +type MacdFix struct { + handle *C.struct_MacdFix +} + +// NewMacdFix constructs a MacdFix. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMacdFix(signal int) (*MacdFix, error) { + ptr := C.wickra_macd_fix_new(C.uintptr_t(signal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MacdFix{handle: ptr} + runtime.SetFinalizer(obj, (*MacdFix).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *MacdFix) Update(value float64) (MacdOutput, bool) { + var out C.struct_WickraMacdOutput + ok := bool(C.wickra_macd_fix_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return MacdOutput{}, false + } + return MacdOutput{float64(out.macd), float64(out.signal), float64(out.histogram)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MacdFix) Reset() { + C.wickra_macd_fix_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MacdFix) Close() { + if ind.handle != nil { + C.wickra_macd_fix_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MacdHistogram wraps the MacdHistogram indicator over the Wickra C ABI. +type MacdHistogram struct { + handle *C.struct_MacdHistogram +} + +// NewMacdHistogram constructs a MacdHistogram. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMacdHistogram(fast int, slow int, signal int) (*MacdHistogram, error) { + ptr := C.wickra_macd_histogram_new(C.uintptr_t(fast), C.uintptr_t(slow), C.uintptr_t(signal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MacdHistogram{handle: ptr} + runtime.SetFinalizer(obj, (*MacdHistogram).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MacdHistogram) Update(value float64) float64 { + r := float64(C.wickra_macd_histogram_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MacdHistogram) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_macd_histogram_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MacdHistogram) Reset() { + C.wickra_macd_histogram_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MacdHistogram) Close() { + if ind.handle != nil { + C.wickra_macd_histogram_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MacdIndicator wraps the MacdIndicator indicator over the Wickra C ABI. +type MacdIndicator struct { + handle *C.struct_MacdIndicator +} + +// NewMacdIndicator constructs a MacdIndicator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMacdIndicator(fast int, slow int, signal int) (*MacdIndicator, error) { + ptr := C.wickra_macd_indicator_new(C.uintptr_t(fast), C.uintptr_t(slow), C.uintptr_t(signal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MacdIndicator{handle: ptr} + runtime.SetFinalizer(obj, (*MacdIndicator).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *MacdIndicator) Update(value float64) (MacdOutput, bool) { + var out C.struct_WickraMacdOutput + ok := bool(C.wickra_macd_indicator_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return MacdOutput{}, false + } + return MacdOutput{float64(out.macd), float64(out.signal), float64(out.histogram)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MacdIndicator) Reset() { + C.wickra_macd_indicator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MacdIndicator) Close() { + if ind.handle != nil { + C.wickra_macd_indicator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Mama wraps the Mama indicator over the Wickra C ABI. +type Mama struct { + handle *C.struct_Mama +} + +// NewMama constructs a Mama. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMama(fastLimit float64, slowLimit float64) (*Mama, error) { + ptr := C.wickra_mama_new(C.double(fastLimit), C.double(slowLimit)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Mama{handle: ptr} + runtime.SetFinalizer(obj, (*Mama).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Mama) Update(value float64) (MamaOutput, bool) { + var out C.struct_WickraMamaOutput + ok := bool(C.wickra_mama_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return MamaOutput{}, false + } + return MamaOutput{float64(out.mama), float64(out.fama)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Mama) Reset() { + C.wickra_mama_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Mama) Close() { + if ind.handle != nil { + C.wickra_mama_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MarketFacilitationIndex wraps the MarketFacilitationIndex indicator over the Wickra C ABI. +type MarketFacilitationIndex struct { + handle *C.struct_MarketFacilitationIndex +} + +// NewMarketFacilitationIndex constructs a MarketFacilitationIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMarketFacilitationIndex() (*MarketFacilitationIndex, error) { + ptr := C.wickra_market_facilitation_index_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MarketFacilitationIndex{handle: ptr} + runtime.SetFinalizer(obj, (*MarketFacilitationIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MarketFacilitationIndex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_market_facilitation_index_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MarketFacilitationIndex) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_market_facilitation_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MarketFacilitationIndex) Reset() { + C.wickra_market_facilitation_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MarketFacilitationIndex) Close() { + if ind.handle != nil { + C.wickra_market_facilitation_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MartinRatio wraps the MartinRatio indicator over the Wickra C ABI. +type MartinRatio struct { + handle *C.struct_MartinRatio +} + +// NewMartinRatio constructs a MartinRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMartinRatio(period int) (*MartinRatio, error) { + ptr := C.wickra_martin_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MartinRatio{handle: ptr} + runtime.SetFinalizer(obj, (*MartinRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MartinRatio) Update(value float64) float64 { + r := float64(C.wickra_martin_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MartinRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_martin_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MartinRatio) Reset() { + C.wickra_martin_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MartinRatio) Close() { + if ind.handle != nil { + C.wickra_martin_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Marubozu wraps the Marubozu indicator over the Wickra C ABI. +type Marubozu struct { + handle *C.struct_Marubozu +} + +// NewMarubozu constructs a Marubozu. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMarubozu() (*Marubozu, error) { + ptr := C.wickra_marubozu_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Marubozu{handle: ptr} + runtime.SetFinalizer(obj, (*Marubozu).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Marubozu) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_marubozu_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Marubozu) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_marubozu_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Marubozu) Reset() { + C.wickra_marubozu_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Marubozu) Close() { + if ind.handle != nil { + C.wickra_marubozu_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MassIndex wraps the MassIndex indicator over the Wickra C ABI. +type MassIndex struct { + handle *C.struct_MassIndex +} + +// NewMassIndex constructs a MassIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMassIndex(emaPeriod int, sumPeriod int) (*MassIndex, error) { + ptr := C.wickra_mass_index_new(C.uintptr_t(emaPeriod), C.uintptr_t(sumPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MassIndex{handle: ptr} + runtime.SetFinalizer(obj, (*MassIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MassIndex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_mass_index_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MassIndex) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_mass_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MassIndex) Reset() { + C.wickra_mass_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MassIndex) Close() { + if ind.handle != nil { + C.wickra_mass_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MatHold wraps the MatHold indicator over the Wickra C ABI. +type MatHold struct { + handle *C.struct_MatHold +} + +// NewMatHold constructs a MatHold. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMatHold() (*MatHold, error) { + ptr := C.wickra_mat_hold_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MatHold{handle: ptr} + runtime.SetFinalizer(obj, (*MatHold).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MatHold) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_mat_hold_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MatHold) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_mat_hold_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MatHold) Reset() { + C.wickra_mat_hold_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MatHold) Close() { + if ind.handle != nil { + C.wickra_mat_hold_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MatchingLow wraps the MatchingLow indicator over the Wickra C ABI. +type MatchingLow struct { + handle *C.struct_MatchingLow +} + +// NewMatchingLow constructs a MatchingLow. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMatchingLow() (*MatchingLow, error) { + ptr := C.wickra_matching_low_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MatchingLow{handle: ptr} + runtime.SetFinalizer(obj, (*MatchingLow).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MatchingLow) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_matching_low_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MatchingLow) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_matching_low_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MatchingLow) Reset() { + C.wickra_matching_low_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MatchingLow) Close() { + if ind.handle != nil { + C.wickra_matching_low_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MaxDrawdown wraps the MaxDrawdown indicator over the Wickra C ABI. +type MaxDrawdown struct { + handle *C.struct_MaxDrawdown +} + +// NewMaxDrawdown constructs a MaxDrawdown. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMaxDrawdown(period int) (*MaxDrawdown, error) { + ptr := C.wickra_max_drawdown_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MaxDrawdown{handle: ptr} + runtime.SetFinalizer(obj, (*MaxDrawdown).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MaxDrawdown) Update(value float64) float64 { + r := float64(C.wickra_max_drawdown_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MaxDrawdown) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_max_drawdown_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MaxDrawdown) Reset() { + C.wickra_max_drawdown_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MaxDrawdown) Close() { + if ind.handle != nil { + C.wickra_max_drawdown_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// McClellanOscillator wraps the McClellanOscillator indicator over the Wickra C ABI. +type McClellanOscillator struct { + handle *C.struct_McClellanOscillator +} + +// NewMcClellanOscillator constructs a McClellanOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMcClellanOscillator() (*McClellanOscillator, error) { + ptr := C.wickra_mc_clellan_oscillator_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &McClellanOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*McClellanOscillator).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *McClellanOscillator) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_mc_clellan_oscillator_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *McClellanOscillator) Reset() { + C.wickra_mc_clellan_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *McClellanOscillator) Close() { + if ind.handle != nil { + C.wickra_mc_clellan_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// McClellanSummationIndex wraps the McClellanSummationIndex indicator over the Wickra C ABI. +type McClellanSummationIndex struct { + handle *C.struct_McClellanSummationIndex +} + +// NewMcClellanSummationIndex constructs a McClellanSummationIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMcClellanSummationIndex() (*McClellanSummationIndex, error) { + ptr := C.wickra_mc_clellan_summation_index_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &McClellanSummationIndex{handle: ptr} + runtime.SetFinalizer(obj, (*McClellanSummationIndex).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *McClellanSummationIndex) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_mc_clellan_summation_index_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *McClellanSummationIndex) Reset() { + C.wickra_mc_clellan_summation_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *McClellanSummationIndex) Close() { + if ind.handle != nil { + C.wickra_mc_clellan_summation_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// McGinleyDynamic wraps the McGinleyDynamic indicator over the Wickra C ABI. +type McGinleyDynamic struct { + handle *C.struct_McGinleyDynamic +} + +// NewMcGinleyDynamic constructs a McGinleyDynamic. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMcGinleyDynamic(period int) (*McGinleyDynamic, error) { + ptr := C.wickra_mc_ginley_dynamic_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &McGinleyDynamic{handle: ptr} + runtime.SetFinalizer(obj, (*McGinleyDynamic).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *McGinleyDynamic) Update(value float64) float64 { + r := float64(C.wickra_mc_ginley_dynamic_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *McGinleyDynamic) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_mc_ginley_dynamic_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *McGinleyDynamic) Reset() { + C.wickra_mc_ginley_dynamic_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *McGinleyDynamic) Close() { + if ind.handle != nil { + C.wickra_mc_ginley_dynamic_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MedianAbsoluteDeviation wraps the MedianAbsoluteDeviation indicator over the Wickra C ABI. +type MedianAbsoluteDeviation struct { + handle *C.struct_MedianAbsoluteDeviation +} + +// NewMedianAbsoluteDeviation constructs a MedianAbsoluteDeviation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMedianAbsoluteDeviation(period int) (*MedianAbsoluteDeviation, error) { + ptr := C.wickra_median_absolute_deviation_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MedianAbsoluteDeviation{handle: ptr} + runtime.SetFinalizer(obj, (*MedianAbsoluteDeviation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MedianAbsoluteDeviation) Update(value float64) float64 { + r := float64(C.wickra_median_absolute_deviation_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MedianAbsoluteDeviation) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_median_absolute_deviation_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MedianAbsoluteDeviation) Reset() { + C.wickra_median_absolute_deviation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MedianAbsoluteDeviation) Close() { + if ind.handle != nil { + C.wickra_median_absolute_deviation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MedianChannel wraps the MedianChannel indicator over the Wickra C ABI. +type MedianChannel struct { + handle *C.struct_MedianChannel +} + +// NewMedianChannel constructs a MedianChannel. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMedianChannel(period int, multiplier float64) (*MedianChannel, error) { + ptr := C.wickra_median_channel_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MedianChannel{handle: ptr} + runtime.SetFinalizer(obj, (*MedianChannel).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *MedianChannel) Update(value float64) (MedianChannelOutput, bool) { + var out C.struct_WickraMedianChannelOutput + ok := bool(C.wickra_median_channel_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return MedianChannelOutput{}, false + } + return MedianChannelOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MedianChannel) Reset() { + C.wickra_median_channel_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MedianChannel) Close() { + if ind.handle != nil { + C.wickra_median_channel_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MedianMa wraps the MedianMa indicator over the Wickra C ABI. +type MedianMa struct { + handle *C.struct_MedianMa +} + +// NewMedianMa constructs a MedianMa. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMedianMa(period int) (*MedianMa, error) { + ptr := C.wickra_median_ma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MedianMa{handle: ptr} + runtime.SetFinalizer(obj, (*MedianMa).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MedianMa) Update(value float64) float64 { + r := float64(C.wickra_median_ma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MedianMa) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_median_ma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MedianMa) Reset() { + C.wickra_median_ma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MedianMa) Close() { + if ind.handle != nil { + C.wickra_median_ma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MedianPrice wraps the MedianPrice indicator over the Wickra C ABI. +type MedianPrice struct { + handle *C.struct_MedianPrice +} + +// NewMedianPrice constructs a MedianPrice. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMedianPrice() (*MedianPrice, error) { + ptr := C.wickra_median_price_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MedianPrice{handle: ptr} + runtime.SetFinalizer(obj, (*MedianPrice).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MedianPrice) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_median_price_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MedianPrice) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_median_price_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MedianPrice) Reset() { + C.wickra_median_price_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MedianPrice) Close() { + if ind.handle != nil { + C.wickra_median_price_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Mfi wraps the Mfi indicator over the Wickra C ABI. +type Mfi struct { + handle *C.struct_Mfi +} + +// NewMfi constructs a Mfi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMfi(period int) (*Mfi, error) { + ptr := C.wickra_mfi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Mfi{handle: ptr} + runtime.SetFinalizer(obj, (*Mfi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Mfi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_mfi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Mfi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_mfi_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Mfi) Reset() { + C.wickra_mfi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Mfi) Close() { + if ind.handle != nil { + C.wickra_mfi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Microprice wraps the Microprice indicator over the Wickra C ABI. +type Microprice struct { + handle *C.struct_Microprice +} + +// NewMicroprice constructs a Microprice. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMicroprice() (*Microprice, error) { + ptr := C.wickra_microprice_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Microprice{handle: ptr} + runtime.SetFinalizer(obj, (*Microprice).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *Microprice) Update(bidPrice []float64, bidSize []float64, askPrice []float64, askSize []float64) float64 { + if len(bidSize) != len(bidPrice) { + panic("wickra: input slices in the same group must have equal length") + } + if len(askSize) != len(askPrice) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_microprice_update(ind.handle, (*C.double)(unsafe.Pointer(&bidPrice[0])), (*C.double)(unsafe.Pointer(&bidSize[0])), C.uintptr_t(len(bidPrice)), (*C.double)(unsafe.Pointer(&askPrice[0])), (*C.double)(unsafe.Pointer(&askSize[0])), C.uintptr_t(len(askPrice)))) + runtime.KeepAlive(ind) + runtime.KeepAlive(bidPrice) + runtime.KeepAlive(bidSize) + runtime.KeepAlive(askPrice) + runtime.KeepAlive(askSize) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Microprice) Reset() { + C.wickra_microprice_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Microprice) Close() { + if ind.handle != nil { + C.wickra_microprice_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MidPoint wraps the MidPoint indicator over the Wickra C ABI. +type MidPoint struct { + handle *C.struct_MidPoint +} + +// NewMidPoint constructs a MidPoint. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMidPoint(period int) (*MidPoint, error) { + ptr := C.wickra_mid_point_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MidPoint{handle: ptr} + runtime.SetFinalizer(obj, (*MidPoint).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MidPoint) Update(value float64) float64 { + r := float64(C.wickra_mid_point_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MidPoint) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_mid_point_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MidPoint) Reset() { + C.wickra_mid_point_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MidPoint) Close() { + if ind.handle != nil { + C.wickra_mid_point_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MidPrice wraps the MidPrice indicator over the Wickra C ABI. +type MidPrice struct { + handle *C.struct_MidPrice +} + +// NewMidPrice constructs a MidPrice. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMidPrice(period int) (*MidPrice, error) { + ptr := C.wickra_mid_price_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MidPrice{handle: ptr} + runtime.SetFinalizer(obj, (*MidPrice).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MidPrice) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_mid_price_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MidPrice) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_mid_price_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MidPrice) Reset() { + C.wickra_mid_price_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MidPrice) Close() { + if ind.handle != nil { + C.wickra_mid_price_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MinusDi wraps the MinusDi indicator over the Wickra C ABI. +type MinusDi struct { + handle *C.struct_MinusDi +} + +// NewMinusDi constructs a MinusDi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMinusDi(period int) (*MinusDi, error) { + ptr := C.wickra_minus_di_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MinusDi{handle: ptr} + runtime.SetFinalizer(obj, (*MinusDi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MinusDi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_minus_di_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MinusDi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_minus_di_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MinusDi) Reset() { + C.wickra_minus_di_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MinusDi) Close() { + if ind.handle != nil { + C.wickra_minus_di_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MinusDm wraps the MinusDm indicator over the Wickra C ABI. +type MinusDm struct { + handle *C.struct_MinusDm +} + +// NewMinusDm constructs a MinusDm. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMinusDm(period int) (*MinusDm, error) { + ptr := C.wickra_minus_dm_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MinusDm{handle: ptr} + runtime.SetFinalizer(obj, (*MinusDm).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MinusDm) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_minus_dm_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MinusDm) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_minus_dm_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MinusDm) Reset() { + C.wickra_minus_dm_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MinusDm) Close() { + if ind.handle != nil { + C.wickra_minus_dm_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ModifiedMaStop wraps the ModifiedMaStop indicator over the Wickra C ABI. +type ModifiedMaStop struct { + handle *C.struct_ModifiedMaStop +} + +// NewModifiedMaStop constructs a ModifiedMaStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewModifiedMaStop(period int) (*ModifiedMaStop, error) { + ptr := C.wickra_modified_ma_stop_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ModifiedMaStop{handle: ptr} + runtime.SetFinalizer(obj, (*ModifiedMaStop).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ModifiedMaStop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ModifiedMaStopOutput, bool) { + var out C.struct_WickraModifiedMaStopOutput + ok := bool(C.wickra_modified_ma_stop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ModifiedMaStopOutput{}, false + } + return ModifiedMaStopOutput{float64(out.value), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ModifiedMaStop) Reset() { + C.wickra_modified_ma_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ModifiedMaStop) Close() { + if ind.handle != nil { + C.wickra_modified_ma_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Mom wraps the Mom indicator over the Wickra C ABI. +type Mom struct { + handle *C.struct_Mom +} + +// NewMom constructs a Mom. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMom(period int) (*Mom, error) { + ptr := C.wickra_mom_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Mom{handle: ptr} + runtime.SetFinalizer(obj, (*Mom).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Mom) Update(value float64) float64 { + r := float64(C.wickra_mom_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Mom) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_mom_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Mom) Reset() { + C.wickra_mom_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Mom) Close() { + if ind.handle != nil { + C.wickra_mom_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MorningDojiStar wraps the MorningDojiStar indicator over the Wickra C ABI. +type MorningDojiStar struct { + handle *C.struct_MorningDojiStar +} + +// NewMorningDojiStar constructs a MorningDojiStar. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMorningDojiStar() (*MorningDojiStar, error) { + ptr := C.wickra_morning_doji_star_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MorningDojiStar{handle: ptr} + runtime.SetFinalizer(obj, (*MorningDojiStar).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MorningDojiStar) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_morning_doji_star_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MorningDojiStar) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_morning_doji_star_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MorningDojiStar) Reset() { + C.wickra_morning_doji_star_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MorningDojiStar) Close() { + if ind.handle != nil { + C.wickra_morning_doji_star_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MorningEveningStar wraps the MorningEveningStar indicator over the Wickra C ABI. +type MorningEveningStar struct { + handle *C.struct_MorningEveningStar +} + +// NewMorningEveningStar constructs a MorningEveningStar. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMorningEveningStar() (*MorningEveningStar, error) { + ptr := C.wickra_morning_evening_star_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MorningEveningStar{handle: ptr} + runtime.SetFinalizer(obj, (*MorningEveningStar).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *MorningEveningStar) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_morning_evening_star_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *MorningEveningStar) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_morning_evening_star_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MorningEveningStar) Reset() { + C.wickra_morning_evening_star_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MorningEveningStar) Close() { + if ind.handle != nil { + C.wickra_morning_evening_star_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// MurreyMathLines wraps the MurreyMathLines indicator over the Wickra C ABI. +type MurreyMathLines struct { + handle *C.struct_MurreyMathLines +} + +// NewMurreyMathLines constructs a MurreyMathLines. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewMurreyMathLines(period int) (*MurreyMathLines, error) { + ptr := C.wickra_murrey_math_lines_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &MurreyMathLines{handle: ptr} + runtime.SetFinalizer(obj, (*MurreyMathLines).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *MurreyMathLines) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (MurreyMathLinesOutput, bool) { + var out C.struct_WickraMurreyMathLinesOutput + ok := bool(C.wickra_murrey_math_lines_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return MurreyMathLinesOutput{}, false + } + return MurreyMathLinesOutput{float64(out.mm8_8), float64(out.mm7_8), float64(out.mm6_8), float64(out.mm5_8), float64(out.mm4_8), float64(out.mm3_8), float64(out.mm2_8), float64(out.mm1_8), float64(out.mm0_8)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *MurreyMathLines) Reset() { + C.wickra_murrey_math_lines_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *MurreyMathLines) Close() { + if ind.handle != nil { + C.wickra_murrey_math_lines_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// NakedPoc wraps the NakedPoc indicator over the Wickra C ABI. +type NakedPoc struct { + handle *C.struct_NakedPoc +} + +// NewNakedPoc constructs a NakedPoc. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewNakedPoc(sessionLen int, bins int) (*NakedPoc, error) { + ptr := C.wickra_naked_poc_new(C.uintptr_t(sessionLen), C.uintptr_t(bins)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &NakedPoc{handle: ptr} + runtime.SetFinalizer(obj, (*NakedPoc).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *NakedPoc) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_naked_poc_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *NakedPoc) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_naked_poc_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *NakedPoc) Reset() { + C.wickra_naked_poc_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *NakedPoc) Close() { + if ind.handle != nil { + C.wickra_naked_poc_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Natr wraps the Natr indicator over the Wickra C ABI. +type Natr struct { + handle *C.struct_Natr +} + +// NewNatr constructs a Natr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewNatr(period int) (*Natr, error) { + ptr := C.wickra_natr_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Natr{handle: ptr} + runtime.SetFinalizer(obj, (*Natr).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Natr) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_natr_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Natr) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_natr_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Natr) Reset() { + C.wickra_natr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Natr) Close() { + if ind.handle != nil { + C.wickra_natr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// NewHighsNewLows wraps the NewHighsNewLows indicator over the Wickra C ABI. +type NewHighsNewLows struct { + handle *C.struct_NewHighsNewLows +} + +// NewNewHighsNewLows constructs a NewHighsNewLows. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewNewHighsNewLows() (*NewHighsNewLows, error) { + ptr := C.wickra_new_highs_new_lows_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &NewHighsNewLows{handle: ptr} + runtime.SetFinalizer(obj, (*NewHighsNewLows).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *NewHighsNewLows) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_new_highs_new_lows_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *NewHighsNewLows) Reset() { + C.wickra_new_highs_new_lows_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *NewHighsNewLows) Close() { + if ind.handle != nil { + C.wickra_new_highs_new_lows_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// NewPriceLines wraps the NewPriceLines indicator over the Wickra C ABI. +type NewPriceLines struct { + handle *C.struct_NewPriceLines +} + +// NewNewPriceLines constructs a NewPriceLines. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewNewPriceLines(count int) (*NewPriceLines, error) { + ptr := C.wickra_new_price_lines_new(C.uintptr_t(count)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &NewPriceLines{handle: ptr} + runtime.SetFinalizer(obj, (*NewPriceLines).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *NewPriceLines) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_new_price_lines_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *NewPriceLines) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_new_price_lines_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *NewPriceLines) Reset() { + C.wickra_new_price_lines_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *NewPriceLines) Close() { + if ind.handle != nil { + C.wickra_new_price_lines_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Nrtr wraps the Nrtr indicator over the Wickra C ABI. +type Nrtr struct { + handle *C.struct_Nrtr +} + +// NewNrtr constructs a Nrtr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewNrtr(pct float64) (*Nrtr, error) { + ptr := C.wickra_nrtr_new(C.double(pct)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Nrtr{handle: ptr} + runtime.SetFinalizer(obj, (*Nrtr).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Nrtr) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (NrtrOutput, bool) { + var out C.struct_WickraNrtrOutput + ok := bool(C.wickra_nrtr_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return NrtrOutput{}, false + } + return NrtrOutput{float64(out.value), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Nrtr) Reset() { + C.wickra_nrtr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Nrtr) Close() { + if ind.handle != nil { + C.wickra_nrtr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Nvi wraps the Nvi indicator over the Wickra C ABI. +type Nvi struct { + handle *C.struct_Nvi +} + +// NewNvi constructs a Nvi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewNvi() (*Nvi, error) { + ptr := C.wickra_nvi_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Nvi{handle: ptr} + runtime.SetFinalizer(obj, (*Nvi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Nvi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_nvi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Nvi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_nvi_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Nvi) Reset() { + C.wickra_nvi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Nvi) Close() { + if ind.handle != nil { + C.wickra_nvi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Obv wraps the Obv indicator over the Wickra C ABI. +type Obv struct { + handle *C.struct_Obv +} + +// NewObv constructs a Obv. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewObv() (*Obv, error) { + ptr := C.wickra_obv_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Obv{handle: ptr} + runtime.SetFinalizer(obj, (*Obv).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Obv) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_obv_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Obv) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_obv_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Obv) Reset() { + C.wickra_obv_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Obv) Close() { + if ind.handle != nil { + C.wickra_obv_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OIPriceDivergence wraps the OIPriceDivergence indicator over the Wickra C ABI. +type OIPriceDivergence struct { + handle *C.struct_OIPriceDivergence +} + +// NewOIPriceDivergence constructs a OIPriceDivergence. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOIPriceDivergence(window int) (*OIPriceDivergence, error) { + ptr := C.wickra_oi_price_divergence_new(C.uintptr_t(window)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OIPriceDivergence{handle: ptr} + runtime.SetFinalizer(obj, (*OIPriceDivergence).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OIPriceDivergence) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_oi_price_divergence_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OIPriceDivergence) Reset() { + C.wickra_oi_price_divergence_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OIPriceDivergence) Close() { + if ind.handle != nil { + C.wickra_oi_price_divergence_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OiToVolumeRatio wraps the OiToVolumeRatio indicator over the Wickra C ABI. +type OiToVolumeRatio struct { + handle *C.struct_OiToVolumeRatio +} + +// NewOiToVolumeRatio constructs a OiToVolumeRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOiToVolumeRatio() (*OiToVolumeRatio, error) { + ptr := C.wickra_oi_to_volume_ratio_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OiToVolumeRatio{handle: ptr} + runtime.SetFinalizer(obj, (*OiToVolumeRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OiToVolumeRatio) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_oi_to_volume_ratio_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OiToVolumeRatio) Reset() { + C.wickra_oi_to_volume_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OiToVolumeRatio) Close() { + if ind.handle != nil { + C.wickra_oi_to_volume_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OIWeighted wraps the OIWeighted indicator over the Wickra C ABI. +type OIWeighted struct { + handle *C.struct_OIWeighted +} + +// NewOIWeighted constructs a OIWeighted. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOIWeighted() (*OIWeighted, error) { + ptr := C.wickra_oi_weighted_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OIWeighted{handle: ptr} + runtime.SetFinalizer(obj, (*OIWeighted).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OIWeighted) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_oi_weighted_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OIWeighted) Reset() { + C.wickra_oi_weighted_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OIWeighted) Close() { + if ind.handle != nil { + C.wickra_oi_weighted_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OmegaRatio wraps the OmegaRatio indicator over the Wickra C ABI. +type OmegaRatio struct { + handle *C.struct_OmegaRatio +} + +// NewOmegaRatio constructs a OmegaRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOmegaRatio(period int, threshold float64) (*OmegaRatio, error) { + ptr := C.wickra_omega_ratio_new(C.uintptr_t(period), C.double(threshold)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OmegaRatio{handle: ptr} + runtime.SetFinalizer(obj, (*OmegaRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OmegaRatio) Update(value float64) float64 { + r := float64(C.wickra_omega_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *OmegaRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_omega_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OmegaRatio) Reset() { + C.wickra_omega_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OmegaRatio) Close() { + if ind.handle != nil { + C.wickra_omega_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OnNeck wraps the OnNeck indicator over the Wickra C ABI. +type OnNeck struct { + handle *C.struct_OnNeck +} + +// NewOnNeck constructs a OnNeck. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOnNeck() (*OnNeck, error) { + ptr := C.wickra_on_neck_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OnNeck{handle: ptr} + runtime.SetFinalizer(obj, (*OnNeck).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OnNeck) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_on_neck_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *OnNeck) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_on_neck_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OnNeck) Reset() { + C.wickra_on_neck_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OnNeck) Close() { + if ind.handle != nil { + C.wickra_on_neck_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OpenInterestDelta wraps the OpenInterestDelta indicator over the Wickra C ABI. +type OpenInterestDelta struct { + handle *C.struct_OpenInterestDelta +} + +// NewOpenInterestDelta constructs a OpenInterestDelta. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOpenInterestDelta() (*OpenInterestDelta, error) { + ptr := C.wickra_open_interest_delta_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OpenInterestDelta{handle: ptr} + runtime.SetFinalizer(obj, (*OpenInterestDelta).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OpenInterestDelta) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_open_interest_delta_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OpenInterestDelta) Reset() { + C.wickra_open_interest_delta_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OpenInterestDelta) Close() { + if ind.handle != nil { + C.wickra_open_interest_delta_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OpenInterestMomentum wraps the OpenInterestMomentum indicator over the Wickra C ABI. +type OpenInterestMomentum struct { + handle *C.struct_OpenInterestMomentum +} + +// NewOpenInterestMomentum constructs a OpenInterestMomentum. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOpenInterestMomentum(period int) (*OpenInterestMomentum, error) { + ptr := C.wickra_open_interest_momentum_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OpenInterestMomentum{handle: ptr} + runtime.SetFinalizer(obj, (*OpenInterestMomentum).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OpenInterestMomentum) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_open_interest_momentum_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OpenInterestMomentum) Reset() { + C.wickra_open_interest_momentum_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OpenInterestMomentum) Close() { + if ind.handle != nil { + C.wickra_open_interest_momentum_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OpeningMarubozu wraps the OpeningMarubozu indicator over the Wickra C ABI. +type OpeningMarubozu struct { + handle *C.struct_OpeningMarubozu +} + +// NewOpeningMarubozu constructs a OpeningMarubozu. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOpeningMarubozu() (*OpeningMarubozu, error) { + ptr := C.wickra_opening_marubozu_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OpeningMarubozu{handle: ptr} + runtime.SetFinalizer(obj, (*OpeningMarubozu).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OpeningMarubozu) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_opening_marubozu_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *OpeningMarubozu) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_opening_marubozu_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OpeningMarubozu) Reset() { + C.wickra_opening_marubozu_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OpeningMarubozu) Close() { + if ind.handle != nil { + C.wickra_opening_marubozu_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OpeningRange wraps the OpeningRange indicator over the Wickra C ABI. +type OpeningRange struct { + handle *C.struct_OpeningRange +} + +// NewOpeningRange constructs a OpeningRange. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOpeningRange(period int) (*OpeningRange, error) { + ptr := C.wickra_opening_range_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OpeningRange{handle: ptr} + runtime.SetFinalizer(obj, (*OpeningRange).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *OpeningRange) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (OpeningRangeOutput, bool) { + var out C.struct_WickraOpeningRangeOutput + ok := bool(C.wickra_opening_range_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return OpeningRangeOutput{}, false + } + return OpeningRangeOutput{float64(out.high), float64(out.low), float64(out.breakout_distance)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OpeningRange) Reset() { + C.wickra_opening_range_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OpeningRange) Close() { + if ind.handle != nil { + C.wickra_opening_range_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OrderBookImbalanceFull wraps the OrderBookImbalanceFull indicator over the Wickra C ABI. +type OrderBookImbalanceFull struct { + handle *C.struct_OrderBookImbalanceFull +} + +// NewOrderBookImbalanceFull constructs a OrderBookImbalanceFull. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOrderBookImbalanceFull() (*OrderBookImbalanceFull, error) { + ptr := C.wickra_order_book_imbalance_full_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OrderBookImbalanceFull{handle: ptr} + runtime.SetFinalizer(obj, (*OrderBookImbalanceFull).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *OrderBookImbalanceFull) Update(bidPrice []float64, bidSize []float64, askPrice []float64, askSize []float64) float64 { + if len(bidSize) != len(bidPrice) { + panic("wickra: input slices in the same group must have equal length") + } + if len(askSize) != len(askPrice) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_order_book_imbalance_full_update(ind.handle, (*C.double)(unsafe.Pointer(&bidPrice[0])), (*C.double)(unsafe.Pointer(&bidSize[0])), C.uintptr_t(len(bidPrice)), (*C.double)(unsafe.Pointer(&askPrice[0])), (*C.double)(unsafe.Pointer(&askSize[0])), C.uintptr_t(len(askPrice)))) + runtime.KeepAlive(ind) + runtime.KeepAlive(bidPrice) + runtime.KeepAlive(bidSize) + runtime.KeepAlive(askPrice) + runtime.KeepAlive(askSize) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OrderBookImbalanceFull) Reset() { + C.wickra_order_book_imbalance_full_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OrderBookImbalanceFull) Close() { + if ind.handle != nil { + C.wickra_order_book_imbalance_full_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OrderBookImbalanceTop1 wraps the OrderBookImbalanceTop1 indicator over the Wickra C ABI. +type OrderBookImbalanceTop1 struct { + handle *C.struct_OrderBookImbalanceTop1 +} + +// NewOrderBookImbalanceTop1 constructs a OrderBookImbalanceTop1. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOrderBookImbalanceTop1() (*OrderBookImbalanceTop1, error) { + ptr := C.wickra_order_book_imbalance_top1_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OrderBookImbalanceTop1{handle: ptr} + runtime.SetFinalizer(obj, (*OrderBookImbalanceTop1).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *OrderBookImbalanceTop1) Update(bidPrice []float64, bidSize []float64, askPrice []float64, askSize []float64) float64 { + if len(bidSize) != len(bidPrice) { + panic("wickra: input slices in the same group must have equal length") + } + if len(askSize) != len(askPrice) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_order_book_imbalance_top1_update(ind.handle, (*C.double)(unsafe.Pointer(&bidPrice[0])), (*C.double)(unsafe.Pointer(&bidSize[0])), C.uintptr_t(len(bidPrice)), (*C.double)(unsafe.Pointer(&askPrice[0])), (*C.double)(unsafe.Pointer(&askSize[0])), C.uintptr_t(len(askPrice)))) + runtime.KeepAlive(ind) + runtime.KeepAlive(bidPrice) + runtime.KeepAlive(bidSize) + runtime.KeepAlive(askPrice) + runtime.KeepAlive(askSize) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OrderBookImbalanceTop1) Reset() { + C.wickra_order_book_imbalance_top1_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OrderBookImbalanceTop1) Close() { + if ind.handle != nil { + C.wickra_order_book_imbalance_top1_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OrderBookImbalanceTopN wraps the OrderBookImbalanceTopN indicator over the Wickra C ABI. +type OrderBookImbalanceTopN struct { + handle *C.struct_OrderBookImbalanceTopN +} + +// NewOrderBookImbalanceTopN constructs a OrderBookImbalanceTopN. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOrderBookImbalanceTopN(levels int) (*OrderBookImbalanceTopN, error) { + ptr := C.wickra_order_book_imbalance_top_n_new(C.uintptr_t(levels)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OrderBookImbalanceTopN{handle: ptr} + runtime.SetFinalizer(obj, (*OrderBookImbalanceTopN).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *OrderBookImbalanceTopN) Update(bidPrice []float64, bidSize []float64, askPrice []float64, askSize []float64) float64 { + if len(bidSize) != len(bidPrice) { + panic("wickra: input slices in the same group must have equal length") + } + if len(askSize) != len(askPrice) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_order_book_imbalance_top_n_update(ind.handle, (*C.double)(unsafe.Pointer(&bidPrice[0])), (*C.double)(unsafe.Pointer(&bidSize[0])), C.uintptr_t(len(bidPrice)), (*C.double)(unsafe.Pointer(&askPrice[0])), (*C.double)(unsafe.Pointer(&askSize[0])), C.uintptr_t(len(askPrice)))) + runtime.KeepAlive(ind) + runtime.KeepAlive(bidPrice) + runtime.KeepAlive(bidSize) + runtime.KeepAlive(askPrice) + runtime.KeepAlive(askSize) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OrderBookImbalanceTopN) Reset() { + C.wickra_order_book_imbalance_top_n_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OrderBookImbalanceTopN) Close() { + if ind.handle != nil { + C.wickra_order_book_imbalance_top_n_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OrderFlowImbalance wraps the OrderFlowImbalance indicator over the Wickra C ABI. +type OrderFlowImbalance struct { + handle *C.struct_OrderFlowImbalance +} + +// NewOrderFlowImbalance constructs a OrderFlowImbalance. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOrderFlowImbalance(period int) (*OrderFlowImbalance, error) { + ptr := C.wickra_order_flow_imbalance_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OrderFlowImbalance{handle: ptr} + runtime.SetFinalizer(obj, (*OrderFlowImbalance).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *OrderFlowImbalance) Update(bidPrice []float64, bidSize []float64, askPrice []float64, askSize []float64) float64 { + if len(bidSize) != len(bidPrice) { + panic("wickra: input slices in the same group must have equal length") + } + if len(askSize) != len(askPrice) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_order_flow_imbalance_update(ind.handle, (*C.double)(unsafe.Pointer(&bidPrice[0])), (*C.double)(unsafe.Pointer(&bidSize[0])), C.uintptr_t(len(bidPrice)), (*C.double)(unsafe.Pointer(&askPrice[0])), (*C.double)(unsafe.Pointer(&askSize[0])), C.uintptr_t(len(askPrice)))) + runtime.KeepAlive(ind) + runtime.KeepAlive(bidPrice) + runtime.KeepAlive(bidSize) + runtime.KeepAlive(askPrice) + runtime.KeepAlive(askSize) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OrderFlowImbalance) Reset() { + C.wickra_order_flow_imbalance_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OrderFlowImbalance) Close() { + if ind.handle != nil { + C.wickra_order_flow_imbalance_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OuHalfLife wraps the OuHalfLife indicator over the Wickra C ABI. +type OuHalfLife struct { + handle *C.struct_OuHalfLife +} + +// NewOuHalfLife constructs a OuHalfLife. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOuHalfLife(period int) (*OuHalfLife, error) { + ptr := C.wickra_ou_half_life_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OuHalfLife{handle: ptr} + runtime.SetFinalizer(obj, (*OuHalfLife).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OuHalfLife) Update(x float64, y float64) float64 { + r := float64(C.wickra_ou_half_life_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *OuHalfLife) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ou_half_life_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OuHalfLife) Reset() { + C.wickra_ou_half_life_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OuHalfLife) Close() { + if ind.handle != nil { + C.wickra_ou_half_life_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OvernightGap wraps the OvernightGap indicator over the Wickra C ABI. +type OvernightGap struct { + handle *C.struct_OvernightGap +} + +// NewOvernightGap constructs a OvernightGap. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOvernightGap(utcOffsetMinutes int32) (*OvernightGap, error) { + ptr := C.wickra_overnight_gap_new(C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OvernightGap{handle: ptr} + runtime.SetFinalizer(obj, (*OvernightGap).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *OvernightGap) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_overnight_gap_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *OvernightGap) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_overnight_gap_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OvernightGap) Reset() { + C.wickra_overnight_gap_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OvernightGap) Close() { + if ind.handle != nil { + C.wickra_overnight_gap_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// OvernightIntradayReturn wraps the OvernightIntradayReturn indicator over the Wickra C ABI. +type OvernightIntradayReturn struct { + handle *C.struct_OvernightIntradayReturn +} + +// NewOvernightIntradayReturn constructs a OvernightIntradayReturn. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewOvernightIntradayReturn(utcOffsetMinutes int32) (*OvernightIntradayReturn, error) { + ptr := C.wickra_overnight_intraday_return_new(C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &OvernightIntradayReturn{handle: ptr} + runtime.SetFinalizer(obj, (*OvernightIntradayReturn).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *OvernightIntradayReturn) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (OvernightIntradayReturnOutput, bool) { + var out C.struct_WickraOvernightIntradayReturnOutput + ok := bool(C.wickra_overnight_intraday_return_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return OvernightIntradayReturnOutput{}, false + } + return OvernightIntradayReturnOutput{float64(out.overnight), float64(out.intraday)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *OvernightIntradayReturn) Reset() { + C.wickra_overnight_intraday_return_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *OvernightIntradayReturn) Close() { + if ind.handle != nil { + C.wickra_overnight_intraday_return_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PainIndex wraps the PainIndex indicator over the Wickra C ABI. +type PainIndex struct { + handle *C.struct_PainIndex +} + +// NewPainIndex constructs a PainIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPainIndex(period int) (*PainIndex, error) { + ptr := C.wickra_pain_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PainIndex{handle: ptr} + runtime.SetFinalizer(obj, (*PainIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PainIndex) Update(value float64) float64 { + r := float64(C.wickra_pain_index_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PainIndex) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pain_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PainIndex) Reset() { + C.wickra_pain_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PainIndex) Close() { + if ind.handle != nil { + C.wickra_pain_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PairSpreadZScore wraps the PairSpreadZScore indicator over the Wickra C ABI. +type PairSpreadZScore struct { + handle *C.struct_PairSpreadZScore +} + +// NewPairSpreadZScore constructs a PairSpreadZScore. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPairSpreadZScore(betaPeriod int, zPeriod int) (*PairSpreadZScore, error) { + ptr := C.wickra_pair_spread_z_score_new(C.uintptr_t(betaPeriod), C.uintptr_t(zPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PairSpreadZScore{handle: ptr} + runtime.SetFinalizer(obj, (*PairSpreadZScore).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PairSpreadZScore) Update(x float64, y float64) float64 { + r := float64(C.wickra_pair_spread_z_score_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PairSpreadZScore) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pair_spread_z_score_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PairSpreadZScore) Reset() { + C.wickra_pair_spread_z_score_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PairSpreadZScore) Close() { + if ind.handle != nil { + C.wickra_pair_spread_z_score_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PairwiseBeta wraps the PairwiseBeta indicator over the Wickra C ABI. +type PairwiseBeta struct { + handle *C.struct_PairwiseBeta +} + +// NewPairwiseBeta constructs a PairwiseBeta. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPairwiseBeta(period int) (*PairwiseBeta, error) { + ptr := C.wickra_pairwise_beta_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PairwiseBeta{handle: ptr} + runtime.SetFinalizer(obj, (*PairwiseBeta).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PairwiseBeta) Update(x float64, y float64) float64 { + r := float64(C.wickra_pairwise_beta_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PairwiseBeta) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pairwise_beta_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PairwiseBeta) Reset() { + C.wickra_pairwise_beta_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PairwiseBeta) Close() { + if ind.handle != nil { + C.wickra_pairwise_beta_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ParkinsonVolatility wraps the ParkinsonVolatility indicator over the Wickra C ABI. +type ParkinsonVolatility struct { + handle *C.struct_ParkinsonVolatility +} + +// NewParkinsonVolatility constructs a ParkinsonVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewParkinsonVolatility(period int, tradingPeriods int) (*ParkinsonVolatility, error) { + ptr := C.wickra_parkinson_volatility_new(C.uintptr_t(period), C.uintptr_t(tradingPeriods)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ParkinsonVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*ParkinsonVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ParkinsonVolatility) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_parkinson_volatility_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ParkinsonVolatility) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_parkinson_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ParkinsonVolatility) Reset() { + C.wickra_parkinson_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ParkinsonVolatility) Close() { + if ind.handle != nil { + C.wickra_parkinson_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PearsonCorrelation wraps the PearsonCorrelation indicator over the Wickra C ABI. +type PearsonCorrelation struct { + handle *C.struct_PearsonCorrelation +} + +// NewPearsonCorrelation constructs a PearsonCorrelation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPearsonCorrelation(period int) (*PearsonCorrelation, error) { + ptr := C.wickra_pearson_correlation_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PearsonCorrelation{handle: ptr} + runtime.SetFinalizer(obj, (*PearsonCorrelation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PearsonCorrelation) Update(x float64, y float64) float64 { + r := float64(C.wickra_pearson_correlation_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PearsonCorrelation) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pearson_correlation_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PearsonCorrelation) Reset() { + C.wickra_pearson_correlation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PearsonCorrelation) Close() { + if ind.handle != nil { + C.wickra_pearson_correlation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PercentAboveMa wraps the PercentAboveMa indicator over the Wickra C ABI. +type PercentAboveMa struct { + handle *C.struct_PercentAboveMa +} + +// NewPercentAboveMa constructs a PercentAboveMa. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPercentAboveMa() (*PercentAboveMa, error) { + ptr := C.wickra_percent_above_ma_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PercentAboveMa{handle: ptr} + runtime.SetFinalizer(obj, (*PercentAboveMa).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *PercentAboveMa) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_percent_above_ma_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PercentAboveMa) Reset() { + C.wickra_percent_above_ma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PercentAboveMa) Close() { + if ind.handle != nil { + C.wickra_percent_above_ma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PercentB wraps the PercentB indicator over the Wickra C ABI. +type PercentB struct { + handle *C.struct_PercentB +} + +// NewPercentB constructs a PercentB. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPercentB(period int, multiplier float64) (*PercentB, error) { + ptr := C.wickra_percent_b_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PercentB{handle: ptr} + runtime.SetFinalizer(obj, (*PercentB).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PercentB) Update(value float64) float64 { + r := float64(C.wickra_percent_b_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PercentB) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_percent_b_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PercentB) Reset() { + C.wickra_percent_b_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PercentB) Close() { + if ind.handle != nil { + C.wickra_percent_b_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PercentageTrailingStop wraps the PercentageTrailingStop indicator over the Wickra C ABI. +type PercentageTrailingStop struct { + handle *C.struct_PercentageTrailingStop +} + +// NewPercentageTrailingStop constructs a PercentageTrailingStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPercentageTrailingStop(percent float64) (*PercentageTrailingStop, error) { + ptr := C.wickra_percentage_trailing_stop_new(C.double(percent)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PercentageTrailingStop{handle: ptr} + runtime.SetFinalizer(obj, (*PercentageTrailingStop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PercentageTrailingStop) Update(value float64) float64 { + r := float64(C.wickra_percentage_trailing_stop_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PercentageTrailingStop) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_percentage_trailing_stop_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PercentageTrailingStop) Reset() { + C.wickra_percentage_trailing_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PercentageTrailingStop) Close() { + if ind.handle != nil { + C.wickra_percentage_trailing_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PerpetualPremiumIndex wraps the PerpetualPremiumIndex indicator over the Wickra C ABI. +type PerpetualPremiumIndex struct { + handle *C.struct_PerpetualPremiumIndex +} + +// NewPerpetualPremiumIndex constructs a PerpetualPremiumIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPerpetualPremiumIndex() (*PerpetualPremiumIndex, error) { + ptr := C.wickra_perpetual_premium_index_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PerpetualPremiumIndex{handle: ptr} + runtime.SetFinalizer(obj, (*PerpetualPremiumIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PerpetualPremiumIndex) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_perpetual_premium_index_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PerpetualPremiumIndex) Reset() { + C.wickra_perpetual_premium_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PerpetualPremiumIndex) Close() { + if ind.handle != nil { + C.wickra_perpetual_premium_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Pgo wraps the Pgo indicator over the Wickra C ABI. +type Pgo struct { + handle *C.struct_Pgo +} + +// NewPgo constructs a Pgo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPgo(period int) (*Pgo, error) { + ptr := C.wickra_pgo_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Pgo{handle: ptr} + runtime.SetFinalizer(obj, (*Pgo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Pgo) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_pgo_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Pgo) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pgo_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Pgo) Reset() { + C.wickra_pgo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Pgo) Close() { + if ind.handle != nil { + C.wickra_pgo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PiercingDarkCloud wraps the PiercingDarkCloud indicator over the Wickra C ABI. +type PiercingDarkCloud struct { + handle *C.struct_PiercingDarkCloud +} + +// NewPiercingDarkCloud constructs a PiercingDarkCloud. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPiercingDarkCloud() (*PiercingDarkCloud, error) { + ptr := C.wickra_piercing_dark_cloud_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PiercingDarkCloud{handle: ptr} + runtime.SetFinalizer(obj, (*PiercingDarkCloud).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PiercingDarkCloud) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_piercing_dark_cloud_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PiercingDarkCloud) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_piercing_dark_cloud_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PiercingDarkCloud) Reset() { + C.wickra_piercing_dark_cloud_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PiercingDarkCloud) Close() { + if ind.handle != nil { + C.wickra_piercing_dark_cloud_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Pin wraps the Pin indicator over the Wickra C ABI. +type Pin struct { + handle *C.struct_Pin +} + +// NewPin constructs a Pin. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPin(window int) (*Pin, error) { + ptr := C.wickra_pin_new(C.uintptr_t(window)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Pin{handle: ptr} + runtime.SetFinalizer(obj, (*Pin).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Pin) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_pin_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Pin) Reset() { + C.wickra_pin_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Pin) Close() { + if ind.handle != nil { + C.wickra_pin_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PivotReversal wraps the PivotReversal indicator over the Wickra C ABI. +type PivotReversal struct { + handle *C.struct_PivotReversal +} + +// NewPivotReversal constructs a PivotReversal. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPivotReversal(left int, right int) (*PivotReversal, error) { + ptr := C.wickra_pivot_reversal_new(C.uintptr_t(left), C.uintptr_t(right)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PivotReversal{handle: ptr} + runtime.SetFinalizer(obj, (*PivotReversal).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PivotReversal) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_pivot_reversal_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PivotReversal) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pivot_reversal_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PivotReversal) Reset() { + C.wickra_pivot_reversal_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PivotReversal) Close() { + if ind.handle != nil { + C.wickra_pivot_reversal_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PlusDi wraps the PlusDi indicator over the Wickra C ABI. +type PlusDi struct { + handle *C.struct_PlusDi +} + +// NewPlusDi constructs a PlusDi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPlusDi(period int) (*PlusDi, error) { + ptr := C.wickra_plus_di_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PlusDi{handle: ptr} + runtime.SetFinalizer(obj, (*PlusDi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PlusDi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_plus_di_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PlusDi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_plus_di_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PlusDi) Reset() { + C.wickra_plus_di_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PlusDi) Close() { + if ind.handle != nil { + C.wickra_plus_di_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PlusDm wraps the PlusDm indicator over the Wickra C ABI. +type PlusDm struct { + handle *C.struct_PlusDm +} + +// NewPlusDm constructs a PlusDm. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPlusDm(period int) (*PlusDm, error) { + ptr := C.wickra_plus_dm_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PlusDm{handle: ptr} + runtime.SetFinalizer(obj, (*PlusDm).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PlusDm) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_plus_dm_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PlusDm) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_plus_dm_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PlusDm) Reset() { + C.wickra_plus_dm_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PlusDm) Close() { + if ind.handle != nil { + C.wickra_plus_dm_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Pmo wraps the Pmo indicator over the Wickra C ABI. +type Pmo struct { + handle *C.struct_Pmo +} + +// NewPmo constructs a Pmo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPmo(smoothing1 int, smoothing2 int) (*Pmo, error) { + ptr := C.wickra_pmo_new(C.uintptr_t(smoothing1), C.uintptr_t(smoothing2)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Pmo{handle: ptr} + runtime.SetFinalizer(obj, (*Pmo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Pmo) Update(value float64) float64 { + r := float64(C.wickra_pmo_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Pmo) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pmo_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Pmo) Reset() { + C.wickra_pmo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Pmo) Close() { + if ind.handle != nil { + C.wickra_pmo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PointAndFigureBars wraps the PointAndFigureBars indicator over the Wickra C ABI. +type PointAndFigureBars struct { + handle *C.struct_PointAndFigureBars +} + +// NewPointAndFigureBars constructs a PointAndFigureBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPointAndFigureBars(boxSize float64, reversal int) (*PointAndFigureBars, error) { + ptr := C.wickra_point_and_figure_bars_new(C.double(boxSize), C.uintptr_t(reversal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PointAndFigureBars{handle: ptr} + runtime.SetFinalizer(obj, (*PointAndFigureBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *PointAndFigureBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []PnfColumn { + const capacity = 64 + var buf [capacity]C.struct_WickraPnfColumn + n := int(C.wickra_point_and_figure_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]PnfColumn, n) + for i := 0; i < n; i++ { + out[i] = PnfColumn{int8(buf[i].direction), float64(buf[i].high), float64(buf[i].low)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PointAndFigureBars) Reset() { + C.wickra_point_and_figure_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PointAndFigureBars) Close() { + if ind.handle != nil { + C.wickra_point_and_figure_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PolarizedFractalEfficiency wraps the PolarizedFractalEfficiency indicator over the Wickra C ABI. +type PolarizedFractalEfficiency struct { + handle *C.struct_PolarizedFractalEfficiency +} + +// NewPolarizedFractalEfficiency constructs a PolarizedFractalEfficiency. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPolarizedFractalEfficiency(period int, smoothing int) (*PolarizedFractalEfficiency, error) { + ptr := C.wickra_polarized_fractal_efficiency_new(C.uintptr_t(period), C.uintptr_t(smoothing)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PolarizedFractalEfficiency{handle: ptr} + runtime.SetFinalizer(obj, (*PolarizedFractalEfficiency).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PolarizedFractalEfficiency) Update(value float64) float64 { + r := float64(C.wickra_polarized_fractal_efficiency_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PolarizedFractalEfficiency) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_polarized_fractal_efficiency_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PolarizedFractalEfficiency) Reset() { + C.wickra_polarized_fractal_efficiency_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PolarizedFractalEfficiency) Close() { + if ind.handle != nil { + C.wickra_polarized_fractal_efficiency_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Ppo wraps the Ppo indicator over the Wickra C ABI. +type Ppo struct { + handle *C.struct_Ppo +} + +// NewPpo constructs a Ppo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPpo(fast int, slow int) (*Ppo, error) { + ptr := C.wickra_ppo_new(C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Ppo{handle: ptr} + runtime.SetFinalizer(obj, (*Ppo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Ppo) Update(value float64) float64 { + r := float64(C.wickra_ppo_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Ppo) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ppo_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Ppo) Reset() { + C.wickra_ppo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Ppo) Close() { + if ind.handle != nil { + C.wickra_ppo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// PpoHistogram wraps the PpoHistogram indicator over the Wickra C ABI. +type PpoHistogram struct { + handle *C.struct_PpoHistogram +} + +// NewPpoHistogram constructs a PpoHistogram. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPpoHistogram(fast int, slow int, signal int) (*PpoHistogram, error) { + ptr := C.wickra_ppo_histogram_new(C.uintptr_t(fast), C.uintptr_t(slow), C.uintptr_t(signal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &PpoHistogram{handle: ptr} + runtime.SetFinalizer(obj, (*PpoHistogram).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *PpoHistogram) Update(value float64) float64 { + r := float64(C.wickra_ppo_histogram_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *PpoHistogram) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ppo_histogram_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *PpoHistogram) Reset() { + C.wickra_ppo_histogram_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *PpoHistogram) Close() { + if ind.handle != nil { + C.wickra_ppo_histogram_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ProfileShape wraps the ProfileShape indicator over the Wickra C ABI. +type ProfileShape struct { + handle *C.struct_ProfileShape +} + +// NewProfileShape constructs a ProfileShape. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewProfileShape(period int, bins int) (*ProfileShape, error) { + ptr := C.wickra_profile_shape_new(C.uintptr_t(period), C.uintptr_t(bins)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ProfileShape{handle: ptr} + runtime.SetFinalizer(obj, (*ProfileShape).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ProfileShape) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_profile_shape_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ProfileShape) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_profile_shape_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ProfileShape) Reset() { + C.wickra_profile_shape_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ProfileShape) Close() { + if ind.handle != nil { + C.wickra_profile_shape_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ProfitFactor wraps the ProfitFactor indicator over the Wickra C ABI. +type ProfitFactor struct { + handle *C.struct_ProfitFactor +} + +// NewProfitFactor constructs a ProfitFactor. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewProfitFactor(period int) (*ProfitFactor, error) { + ptr := C.wickra_profit_factor_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ProfitFactor{handle: ptr} + runtime.SetFinalizer(obj, (*ProfitFactor).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ProfitFactor) Update(value float64) float64 { + r := float64(C.wickra_profit_factor_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ProfitFactor) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_profit_factor_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ProfitFactor) Reset() { + C.wickra_profit_factor_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ProfitFactor) Close() { + if ind.handle != nil { + C.wickra_profit_factor_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ProjectionBands wraps the ProjectionBands indicator over the Wickra C ABI. +type ProjectionBands struct { + handle *C.struct_ProjectionBands +} + +// NewProjectionBands constructs a ProjectionBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewProjectionBands(period int) (*ProjectionBands, error) { + ptr := C.wickra_projection_bands_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ProjectionBands{handle: ptr} + runtime.SetFinalizer(obj, (*ProjectionBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ProjectionBands) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ProjectionBandsOutput, bool) { + var out C.struct_WickraProjectionBandsOutput + ok := bool(C.wickra_projection_bands_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ProjectionBandsOutput{}, false + } + return ProjectionBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ProjectionBands) Reset() { + C.wickra_projection_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ProjectionBands) Close() { + if ind.handle != nil { + C.wickra_projection_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ProjectionOscillator wraps the ProjectionOscillator indicator over the Wickra C ABI. +type ProjectionOscillator struct { + handle *C.struct_ProjectionOscillator +} + +// NewProjectionOscillator constructs a ProjectionOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewProjectionOscillator(period int) (*ProjectionOscillator, error) { + ptr := C.wickra_projection_oscillator_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ProjectionOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*ProjectionOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ProjectionOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_projection_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ProjectionOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_projection_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ProjectionOscillator) Reset() { + C.wickra_projection_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ProjectionOscillator) Close() { + if ind.handle != nil { + C.wickra_projection_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Psar wraps the Psar indicator over the Wickra C ABI. +type Psar struct { + handle *C.struct_Psar +} + +// NewPsar constructs a Psar. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPsar(afStart float64, afStep float64, afMax float64) (*Psar, error) { + ptr := C.wickra_psar_new(C.double(afStart), C.double(afStep), C.double(afMax)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Psar{handle: ptr} + runtime.SetFinalizer(obj, (*Psar).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Psar) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_psar_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Psar) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_psar_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Psar) Reset() { + C.wickra_psar_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Psar) Close() { + if ind.handle != nil { + C.wickra_psar_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Pvi wraps the Pvi indicator over the Wickra C ABI. +type Pvi struct { + handle *C.struct_Pvi +} + +// NewPvi constructs a Pvi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewPvi() (*Pvi, error) { + ptr := C.wickra_pvi_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Pvi{handle: ptr} + runtime.SetFinalizer(obj, (*Pvi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Pvi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_pvi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Pvi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_pvi_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Pvi) Reset() { + C.wickra_pvi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Pvi) Close() { + if ind.handle != nil { + C.wickra_pvi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Qqe wraps the Qqe indicator over the Wickra C ABI. +type Qqe struct { + handle *C.struct_Qqe +} + +// NewQqe constructs a Qqe. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewQqe(rsiPeriod int, smoothing int, factor float64) (*Qqe, error) { + ptr := C.wickra_qqe_new(C.uintptr_t(rsiPeriod), C.uintptr_t(smoothing), C.double(factor)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Qqe{handle: ptr} + runtime.SetFinalizer(obj, (*Qqe).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Qqe) Update(value float64) (QqeOutput, bool) { + var out C.struct_WickraQqeOutput + ok := bool(C.wickra_qqe_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return QqeOutput{}, false + } + return QqeOutput{float64(out.rsi_ma), float64(out.trailing_line)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Qqe) Reset() { + C.wickra_qqe_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Qqe) Close() { + if ind.handle != nil { + C.wickra_qqe_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Qstick wraps the Qstick indicator over the Wickra C ABI. +type Qstick struct { + handle *C.struct_Qstick +} + +// NewQstick constructs a Qstick. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewQstick(period int) (*Qstick, error) { + ptr := C.wickra_qstick_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Qstick{handle: ptr} + runtime.SetFinalizer(obj, (*Qstick).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Qstick) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_qstick_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Qstick) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_qstick_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Qstick) Reset() { + C.wickra_qstick_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Qstick) Close() { + if ind.handle != nil { + C.wickra_qstick_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// QuartileBands wraps the QuartileBands indicator over the Wickra C ABI. +type QuartileBands struct { + handle *C.struct_QuartileBands +} + +// NewQuartileBands constructs a QuartileBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewQuartileBands(period int) (*QuartileBands, error) { + ptr := C.wickra_quartile_bands_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &QuartileBands{handle: ptr} + runtime.SetFinalizer(obj, (*QuartileBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *QuartileBands) Update(value float64) (QuartileBandsOutput, bool) { + var out C.struct_WickraQuartileBandsOutput + ok := bool(C.wickra_quartile_bands_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return QuartileBandsOutput{}, false + } + return QuartileBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *QuartileBands) Reset() { + C.wickra_quartile_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *QuartileBands) Close() { + if ind.handle != nil { + C.wickra_quartile_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// QuotedSpread wraps the QuotedSpread indicator over the Wickra C ABI. +type QuotedSpread struct { + handle *C.struct_QuotedSpread +} + +// NewQuotedSpread constructs a QuotedSpread. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewQuotedSpread() (*QuotedSpread, error) { + ptr := C.wickra_quoted_spread_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &QuotedSpread{handle: ptr} + runtime.SetFinalizer(obj, (*QuotedSpread).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *QuotedSpread) Update(bidPrice []float64, bidSize []float64, askPrice []float64, askSize []float64) float64 { + if len(bidSize) != len(bidPrice) { + panic("wickra: input slices in the same group must have equal length") + } + if len(askSize) != len(askPrice) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_quoted_spread_update(ind.handle, (*C.double)(unsafe.Pointer(&bidPrice[0])), (*C.double)(unsafe.Pointer(&bidSize[0])), C.uintptr_t(len(bidPrice)), (*C.double)(unsafe.Pointer(&askPrice[0])), (*C.double)(unsafe.Pointer(&askSize[0])), C.uintptr_t(len(askPrice)))) + runtime.KeepAlive(ind) + runtime.KeepAlive(bidPrice) + runtime.KeepAlive(bidSize) + runtime.KeepAlive(askPrice) + runtime.KeepAlive(askSize) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *QuotedSpread) Reset() { + C.wickra_quoted_spread_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *QuotedSpread) Close() { + if ind.handle != nil { + C.wickra_quoted_spread_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RSquared wraps the RSquared indicator over the Wickra C ABI. +type RSquared struct { + handle *C.struct_RSquared +} + +// NewRSquared constructs a RSquared. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRSquared(period int) (*RSquared, error) { + ptr := C.wickra_r_squared_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RSquared{handle: ptr} + runtime.SetFinalizer(obj, (*RSquared).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RSquared) Update(value float64) float64 { + r := float64(C.wickra_r_squared_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RSquared) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_r_squared_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RSquared) Reset() { + C.wickra_r_squared_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RSquared) Close() { + if ind.handle != nil { + C.wickra_r_squared_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RangeBars wraps the RangeBars indicator over the Wickra C ABI. +type RangeBars struct { + handle *C.struct_RangeBars +} + +// NewRangeBars constructs a RangeBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRangeBars(range_ float64) (*RangeBars, error) { + ptr := C.wickra_range_bars_new(C.double(range_)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RangeBars{handle: ptr} + runtime.SetFinalizer(obj, (*RangeBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *RangeBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []RangeBar { + const capacity = 64 + var buf [capacity]C.struct_WickraRangeBar + n := int(C.wickra_range_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]RangeBar, n) + for i := 0; i < n; i++ { + out[i] = RangeBar{float64(buf[i].open), float64(buf[i].close), int8(buf[i].direction)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RangeBars) Reset() { + C.wickra_range_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RangeBars) Close() { + if ind.handle != nil { + C.wickra_range_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RealizedSpread wraps the RealizedSpread indicator over the Wickra C ABI. +type RealizedSpread struct { + handle *C.struct_RealizedSpread +} + +// NewRealizedSpread constructs a RealizedSpread. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRealizedSpread(horizon int) (*RealizedSpread, error) { + ptr := C.wickra_realized_spread_new(C.uintptr_t(horizon)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RealizedSpread{handle: ptr} + runtime.SetFinalizer(obj, (*RealizedSpread).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RealizedSpread) Update(price float64, size float64, isBuy bool, timestamp int64, mid float64) float64 { + r := float64(C.wickra_realized_spread_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp), C.double(mid))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RealizedSpread) Reset() { + C.wickra_realized_spread_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RealizedSpread) Close() { + if ind.handle != nil { + C.wickra_realized_spread_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RealizedVolatility wraps the RealizedVolatility indicator over the Wickra C ABI. +type RealizedVolatility struct { + handle *C.struct_RealizedVolatility +} + +// NewRealizedVolatility constructs a RealizedVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRealizedVolatility(period int) (*RealizedVolatility, error) { + ptr := C.wickra_realized_volatility_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RealizedVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*RealizedVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RealizedVolatility) Update(value float64) float64 { + r := float64(C.wickra_realized_volatility_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RealizedVolatility) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_realized_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RealizedVolatility) Reset() { + C.wickra_realized_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RealizedVolatility) Close() { + if ind.handle != nil { + C.wickra_realized_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RecoveryFactor wraps the RecoveryFactor indicator over the Wickra C ABI. +type RecoveryFactor struct { + handle *C.struct_RecoveryFactor +} + +// NewRecoveryFactor constructs a RecoveryFactor. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRecoveryFactor() (*RecoveryFactor, error) { + ptr := C.wickra_recovery_factor_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RecoveryFactor{handle: ptr} + runtime.SetFinalizer(obj, (*RecoveryFactor).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RecoveryFactor) Update(value float64) float64 { + r := float64(C.wickra_recovery_factor_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RecoveryFactor) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_recovery_factor_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RecoveryFactor) Reset() { + C.wickra_recovery_factor_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RecoveryFactor) Close() { + if ind.handle != nil { + C.wickra_recovery_factor_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RectangleRange wraps the RectangleRange indicator over the Wickra C ABI. +type RectangleRange struct { + handle *C.struct_RectangleRange +} + +// NewRectangleRange constructs a RectangleRange. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRectangleRange() (*RectangleRange, error) { + ptr := C.wickra_rectangle_range_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RectangleRange{handle: ptr} + runtime.SetFinalizer(obj, (*RectangleRange).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RectangleRange) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_rectangle_range_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RectangleRange) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rectangle_range_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RectangleRange) Reset() { + C.wickra_rectangle_range_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RectangleRange) Close() { + if ind.handle != nil { + C.wickra_rectangle_range_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Reflex wraps the Reflex indicator over the Wickra C ABI. +type Reflex struct { + handle *C.struct_Reflex +} + +// NewReflex constructs a Reflex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewReflex(period int) (*Reflex, error) { + ptr := C.wickra_reflex_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Reflex{handle: ptr} + runtime.SetFinalizer(obj, (*Reflex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Reflex) Update(value float64) float64 { + r := float64(C.wickra_reflex_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Reflex) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_reflex_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Reflex) Reset() { + C.wickra_reflex_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Reflex) Close() { + if ind.handle != nil { + C.wickra_reflex_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RegimeLabel wraps the RegimeLabel indicator over the Wickra C ABI. +type RegimeLabel struct { + handle *C.struct_RegimeLabel +} + +// NewRegimeLabel constructs a RegimeLabel. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRegimeLabel(volPeriod int, lookback int) (*RegimeLabel, error) { + ptr := C.wickra_regime_label_new(C.uintptr_t(volPeriod), C.uintptr_t(lookback)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RegimeLabel{handle: ptr} + runtime.SetFinalizer(obj, (*RegimeLabel).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RegimeLabel) Update(value float64) float64 { + r := float64(C.wickra_regime_label_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RegimeLabel) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_regime_label_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RegimeLabel) Reset() { + C.wickra_regime_label_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RegimeLabel) Close() { + if ind.handle != nil { + C.wickra_regime_label_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RelativeStrengthAB wraps the RelativeStrengthAB indicator over the Wickra C ABI. +type RelativeStrengthAB struct { + handle *C.struct_RelativeStrengthAB +} + +// NewRelativeStrengthAB constructs a RelativeStrengthAB. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRelativeStrengthAB(maPeriod int, rsiPeriod int) (*RelativeStrengthAB, error) { + ptr := C.wickra_relative_strength_ab_new(C.uintptr_t(maPeriod), C.uintptr_t(rsiPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RelativeStrengthAB{handle: ptr} + runtime.SetFinalizer(obj, (*RelativeStrengthAB).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *RelativeStrengthAB) Update(x float64, y float64) (RelativeStrengthOutput, bool) { + var out C.struct_WickraRelativeStrengthOutput + ok := bool(C.wickra_relative_strength_ab_update(ind.handle, C.double(x), C.double(y), &out)) + runtime.KeepAlive(ind) + if !ok { + return RelativeStrengthOutput{}, false + } + return RelativeStrengthOutput{float64(out.ratio), float64(out.ratio_ma), float64(out.ratio_rsi)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RelativeStrengthAB) Reset() { + C.wickra_relative_strength_ab_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RelativeStrengthAB) Close() { + if ind.handle != nil { + C.wickra_relative_strength_ab_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RenkoBars wraps the RenkoBars indicator over the Wickra C ABI. +type RenkoBars struct { + handle *C.struct_RenkoBars +} + +// NewRenkoBars constructs a RenkoBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRenkoBars(boxSize float64) (*RenkoBars, error) { + ptr := C.wickra_renko_bars_new(C.double(boxSize)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RenkoBars{handle: ptr} + runtime.SetFinalizer(obj, (*RenkoBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *RenkoBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []RenkoBrick { + const capacity = 64 + var buf [capacity]C.struct_WickraRenkoBrick + n := int(C.wickra_renko_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]RenkoBrick, n) + for i := 0; i < n; i++ { + out[i] = RenkoBrick{float64(buf[i].open), float64(buf[i].close), int8(buf[i].direction)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RenkoBars) Reset() { + C.wickra_renko_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RenkoBars) Close() { + if ind.handle != nil { + C.wickra_renko_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RenkoTrailingStop wraps the RenkoTrailingStop indicator over the Wickra C ABI. +type RenkoTrailingStop struct { + handle *C.struct_RenkoTrailingStop +} + +// NewRenkoTrailingStop constructs a RenkoTrailingStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRenkoTrailingStop(blockSize float64) (*RenkoTrailingStop, error) { + ptr := C.wickra_renko_trailing_stop_new(C.double(blockSize)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RenkoTrailingStop{handle: ptr} + runtime.SetFinalizer(obj, (*RenkoTrailingStop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RenkoTrailingStop) Update(value float64) float64 { + r := float64(C.wickra_renko_trailing_stop_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RenkoTrailingStop) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_renko_trailing_stop_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RenkoTrailingStop) Reset() { + C.wickra_renko_trailing_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RenkoTrailingStop) Close() { + if ind.handle != nil { + C.wickra_renko_trailing_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RickshawMan wraps the RickshawMan indicator over the Wickra C ABI. +type RickshawMan struct { + handle *C.struct_RickshawMan +} + +// NewRickshawMan constructs a RickshawMan. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRickshawMan() (*RickshawMan, error) { + ptr := C.wickra_rickshaw_man_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RickshawMan{handle: ptr} + runtime.SetFinalizer(obj, (*RickshawMan).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RickshawMan) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_rickshaw_man_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RickshawMan) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rickshaw_man_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RickshawMan) Reset() { + C.wickra_rickshaw_man_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RickshawMan) Close() { + if ind.handle != nil { + C.wickra_rickshaw_man_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RisingThreeMethods wraps the RisingThreeMethods indicator over the Wickra C ABI. +type RisingThreeMethods struct { + handle *C.struct_RisingThreeMethods +} + +// NewRisingThreeMethods constructs a RisingThreeMethods. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRisingThreeMethods() (*RisingThreeMethods, error) { + ptr := C.wickra_rising_three_methods_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RisingThreeMethods{handle: ptr} + runtime.SetFinalizer(obj, (*RisingThreeMethods).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RisingThreeMethods) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_rising_three_methods_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RisingThreeMethods) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rising_three_methods_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RisingThreeMethods) Reset() { + C.wickra_rising_three_methods_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RisingThreeMethods) Close() { + if ind.handle != nil { + C.wickra_rising_three_methods_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rmi wraps the Rmi indicator over the Wickra C ABI. +type Rmi struct { + handle *C.struct_Rmi +} + +// NewRmi constructs a Rmi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRmi(period int, momentum int) (*Rmi, error) { + ptr := C.wickra_rmi_new(C.uintptr_t(period), C.uintptr_t(momentum)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rmi{handle: ptr} + runtime.SetFinalizer(obj, (*Rmi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Rmi) Update(value float64) float64 { + r := float64(C.wickra_rmi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Rmi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rmi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rmi) Reset() { + C.wickra_rmi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rmi) Close() { + if ind.handle != nil { + C.wickra_rmi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Roc wraps the Roc indicator over the Wickra C ABI. +type Roc struct { + handle *C.struct_Roc +} + +// NewRoc constructs a Roc. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRoc(period int) (*Roc, error) { + ptr := C.wickra_roc_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Roc{handle: ptr} + runtime.SetFinalizer(obj, (*Roc).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Roc) Update(value float64) float64 { + r := float64(C.wickra_roc_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Roc) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_roc_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Roc) Reset() { + C.wickra_roc_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Roc) Close() { + if ind.handle != nil { + C.wickra_roc_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rocp wraps the Rocp indicator over the Wickra C ABI. +type Rocp struct { + handle *C.struct_Rocp +} + +// NewRocp constructs a Rocp. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRocp(period int) (*Rocp, error) { + ptr := C.wickra_rocp_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rocp{handle: ptr} + runtime.SetFinalizer(obj, (*Rocp).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Rocp) Update(value float64) float64 { + r := float64(C.wickra_rocp_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Rocp) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rocp_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rocp) Reset() { + C.wickra_rocp_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rocp) Close() { + if ind.handle != nil { + C.wickra_rocp_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rocr wraps the Rocr indicator over the Wickra C ABI. +type Rocr struct { + handle *C.struct_Rocr +} + +// NewRocr constructs a Rocr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRocr(period int) (*Rocr, error) { + ptr := C.wickra_rocr_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rocr{handle: ptr} + runtime.SetFinalizer(obj, (*Rocr).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Rocr) Update(value float64) float64 { + r := float64(C.wickra_rocr_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Rocr) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rocr_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rocr) Reset() { + C.wickra_rocr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rocr) Close() { + if ind.handle != nil { + C.wickra_rocr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rocr100 wraps the Rocr100 indicator over the Wickra C ABI. +type Rocr100 struct { + handle *C.struct_Rocr100 +} + +// NewRocr100 constructs a Rocr100. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRocr100(period int) (*Rocr100, error) { + ptr := C.wickra_rocr100_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rocr100{handle: ptr} + runtime.SetFinalizer(obj, (*Rocr100).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Rocr100) Update(value float64) float64 { + r := float64(C.wickra_rocr100_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Rocr100) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rocr100_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rocr100) Reset() { + C.wickra_rocr100_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rocr100) Close() { + if ind.handle != nil { + C.wickra_rocr100_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RogersSatchellVolatility wraps the RogersSatchellVolatility indicator over the Wickra C ABI. +type RogersSatchellVolatility struct { + handle *C.struct_RogersSatchellVolatility +} + +// NewRogersSatchellVolatility constructs a RogersSatchellVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRogersSatchellVolatility(period int, tradingPeriods int) (*RogersSatchellVolatility, error) { + ptr := C.wickra_rogers_satchell_volatility_new(C.uintptr_t(period), C.uintptr_t(tradingPeriods)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RogersSatchellVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*RogersSatchellVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RogersSatchellVolatility) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_rogers_satchell_volatility_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RogersSatchellVolatility) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rogers_satchell_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RogersSatchellVolatility) Reset() { + C.wickra_rogers_satchell_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RogersSatchellVolatility) Close() { + if ind.handle != nil { + C.wickra_rogers_satchell_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollMeasure wraps the RollMeasure indicator over the Wickra C ABI. +type RollMeasure struct { + handle *C.struct_RollMeasure +} + +// NewRollMeasure constructs a RollMeasure. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollMeasure(period int) (*RollMeasure, error) { + ptr := C.wickra_roll_measure_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollMeasure{handle: ptr} + runtime.SetFinalizer(obj, (*RollMeasure).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollMeasure) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_roll_measure_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollMeasure) Reset() { + C.wickra_roll_measure_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollMeasure) Close() { + if ind.handle != nil { + C.wickra_roll_measure_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollingCorrelation wraps the RollingCorrelation indicator over the Wickra C ABI. +type RollingCorrelation struct { + handle *C.struct_RollingCorrelation +} + +// NewRollingCorrelation constructs a RollingCorrelation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollingCorrelation(period int) (*RollingCorrelation, error) { + ptr := C.wickra_rolling_correlation_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollingCorrelation{handle: ptr} + runtime.SetFinalizer(obj, (*RollingCorrelation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollingCorrelation) Update(x float64, y float64) float64 { + r := float64(C.wickra_rolling_correlation_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RollingCorrelation) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rolling_correlation_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollingCorrelation) Reset() { + C.wickra_rolling_correlation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollingCorrelation) Close() { + if ind.handle != nil { + C.wickra_rolling_correlation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollingCovariance wraps the RollingCovariance indicator over the Wickra C ABI. +type RollingCovariance struct { + handle *C.struct_RollingCovariance +} + +// NewRollingCovariance constructs a RollingCovariance. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollingCovariance(period int) (*RollingCovariance, error) { + ptr := C.wickra_rolling_covariance_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollingCovariance{handle: ptr} + runtime.SetFinalizer(obj, (*RollingCovariance).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollingCovariance) Update(x float64, y float64) float64 { + r := float64(C.wickra_rolling_covariance_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RollingCovariance) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rolling_covariance_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollingCovariance) Reset() { + C.wickra_rolling_covariance_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollingCovariance) Close() { + if ind.handle != nil { + C.wickra_rolling_covariance_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollingIqr wraps the RollingIqr indicator over the Wickra C ABI. +type RollingIqr struct { + handle *C.struct_RollingIqr +} + +// NewRollingIqr constructs a RollingIqr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollingIqr(period int) (*RollingIqr, error) { + ptr := C.wickra_rolling_iqr_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollingIqr{handle: ptr} + runtime.SetFinalizer(obj, (*RollingIqr).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollingIqr) Update(value float64) float64 { + r := float64(C.wickra_rolling_iqr_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RollingIqr) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rolling_iqr_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollingIqr) Reset() { + C.wickra_rolling_iqr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollingIqr) Close() { + if ind.handle != nil { + C.wickra_rolling_iqr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollingMinMaxScaler wraps the RollingMinMaxScaler indicator over the Wickra C ABI. +type RollingMinMaxScaler struct { + handle *C.struct_RollingMinMaxScaler +} + +// NewRollingMinMaxScaler constructs a RollingMinMaxScaler. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollingMinMaxScaler(period int) (*RollingMinMaxScaler, error) { + ptr := C.wickra_rolling_min_max_scaler_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollingMinMaxScaler{handle: ptr} + runtime.SetFinalizer(obj, (*RollingMinMaxScaler).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollingMinMaxScaler) Update(value float64) float64 { + r := float64(C.wickra_rolling_min_max_scaler_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RollingMinMaxScaler) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rolling_min_max_scaler_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollingMinMaxScaler) Reset() { + C.wickra_rolling_min_max_scaler_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollingMinMaxScaler) Close() { + if ind.handle != nil { + C.wickra_rolling_min_max_scaler_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollingPercentileRank wraps the RollingPercentileRank indicator over the Wickra C ABI. +type RollingPercentileRank struct { + handle *C.struct_RollingPercentileRank +} + +// NewRollingPercentileRank constructs a RollingPercentileRank. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollingPercentileRank(period int) (*RollingPercentileRank, error) { + ptr := C.wickra_rolling_percentile_rank_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollingPercentileRank{handle: ptr} + runtime.SetFinalizer(obj, (*RollingPercentileRank).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollingPercentileRank) Update(value float64) float64 { + r := float64(C.wickra_rolling_percentile_rank_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RollingPercentileRank) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rolling_percentile_rank_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollingPercentileRank) Reset() { + C.wickra_rolling_percentile_rank_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollingPercentileRank) Close() { + if ind.handle != nil { + C.wickra_rolling_percentile_rank_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollingQuantile wraps the RollingQuantile indicator over the Wickra C ABI. +type RollingQuantile struct { + handle *C.struct_RollingQuantile +} + +// NewRollingQuantile constructs a RollingQuantile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollingQuantile(period int, quantile float64) (*RollingQuantile, error) { + ptr := C.wickra_rolling_quantile_new(C.uintptr_t(period), C.double(quantile)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollingQuantile{handle: ptr} + runtime.SetFinalizer(obj, (*RollingQuantile).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollingQuantile) Update(value float64) float64 { + r := float64(C.wickra_rolling_quantile_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RollingQuantile) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rolling_quantile_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollingQuantile) Reset() { + C.wickra_rolling_quantile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollingQuantile) Close() { + if ind.handle != nil { + C.wickra_rolling_quantile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RollingVwap wraps the RollingVwap indicator over the Wickra C ABI. +type RollingVwap struct { + handle *C.struct_RollingVwap +} + +// NewRollingVwap constructs a RollingVwap. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRollingVwap(period int) (*RollingVwap, error) { + ptr := C.wickra_rolling_vwap_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RollingVwap{handle: ptr} + runtime.SetFinalizer(obj, (*RollingVwap).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RollingVwap) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_rolling_vwap_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RollingVwap) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rolling_vwap_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RollingVwap) Reset() { + C.wickra_rolling_vwap_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RollingVwap) Close() { + if ind.handle != nil { + C.wickra_rolling_vwap_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RoofingFilter wraps the RoofingFilter indicator over the Wickra C ABI. +type RoofingFilter struct { + handle *C.struct_RoofingFilter +} + +// NewRoofingFilter constructs a RoofingFilter. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRoofingFilter(lpPeriod int, hpPeriod int) (*RoofingFilter, error) { + ptr := C.wickra_roofing_filter_new(C.uintptr_t(lpPeriod), C.uintptr_t(hpPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RoofingFilter{handle: ptr} + runtime.SetFinalizer(obj, (*RoofingFilter).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RoofingFilter) Update(value float64) float64 { + r := float64(C.wickra_roofing_filter_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RoofingFilter) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_roofing_filter_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RoofingFilter) Reset() { + C.wickra_roofing_filter_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RoofingFilter) Close() { + if ind.handle != nil { + C.wickra_roofing_filter_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rsi wraps the Rsi indicator over the Wickra C ABI. +type Rsi struct { + handle *C.struct_Rsi +} + +// NewRsi constructs a Rsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRsi(period int) (*Rsi, error) { + ptr := C.wickra_rsi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rsi{handle: ptr} + runtime.SetFinalizer(obj, (*Rsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Rsi) Update(value float64) float64 { + r := float64(C.wickra_rsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Rsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rsi) Reset() { + C.wickra_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rsi) Close() { + if ind.handle != nil { + C.wickra_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rsx wraps the Rsx indicator over the Wickra C ABI. +type Rsx struct { + handle *C.struct_Rsx +} + +// NewRsx constructs a Rsx. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRsx(length int) (*Rsx, error) { + ptr := C.wickra_rsx_new(C.uintptr_t(length)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rsx{handle: ptr} + runtime.SetFinalizer(obj, (*Rsx).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Rsx) Update(value float64) float64 { + r := float64(C.wickra_rsx_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Rsx) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rsx_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rsx) Reset() { + C.wickra_rsx_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rsx) Close() { + if ind.handle != nil { + C.wickra_rsx_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RunBars wraps the RunBars indicator over the Wickra C ABI. +type RunBars struct { + handle *C.struct_RunBars +} + +// NewRunBars constructs a RunBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRunBars(runLength int) (*RunBars, error) { + ptr := C.wickra_run_bars_new(C.uintptr_t(runLength)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RunBars{handle: ptr} + runtime.SetFinalizer(obj, (*RunBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *RunBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []RunBar { + const capacity = 64 + var buf [capacity]C.struct_WickraRunBar + n := int(C.wickra_run_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]RunBar, n) + for i := 0; i < n; i++ { + out[i] = RunBar{float64(buf[i].open), float64(buf[i].high), float64(buf[i].low), float64(buf[i].close), int(buf[i].length), int8(buf[i].direction)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RunBars) Reset() { + C.wickra_run_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RunBars) Close() { + if ind.handle != nil { + C.wickra_run_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rvi wraps the Rvi indicator over the Wickra C ABI. +type Rvi struct { + handle *C.struct_Rvi +} + +// NewRvi constructs a Rvi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRvi(period int) (*Rvi, error) { + ptr := C.wickra_rvi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rvi{handle: ptr} + runtime.SetFinalizer(obj, (*Rvi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Rvi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_rvi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Rvi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rvi_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rvi) Reset() { + C.wickra_rvi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rvi) Close() { + if ind.handle != nil { + C.wickra_rvi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// RviVolatility wraps the RviVolatility indicator over the Wickra C ABI. +type RviVolatility struct { + handle *C.struct_RviVolatility +} + +// NewRviVolatility constructs a RviVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRviVolatility(period int) (*RviVolatility, error) { + ptr := C.wickra_rvi_volatility_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &RviVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*RviVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *RviVolatility) Update(value float64) float64 { + r := float64(C.wickra_rvi_volatility_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *RviVolatility) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_rvi_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *RviVolatility) Reset() { + C.wickra_rvi_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *RviVolatility) Close() { + if ind.handle != nil { + C.wickra_rvi_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Rwi wraps the Rwi indicator over the Wickra C ABI. +type Rwi struct { + handle *C.struct_Rwi +} + +// NewRwi constructs a Rwi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewRwi(period int) (*Rwi, error) { + ptr := C.wickra_rwi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Rwi{handle: ptr} + runtime.SetFinalizer(obj, (*Rwi).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Rwi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (RwiOutput, bool) { + var out C.struct_WickraRwiOutput + ok := bool(C.wickra_rwi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return RwiOutput{}, false + } + return RwiOutput{float64(out.high), float64(out.low)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Rwi) Reset() { + C.wickra_rwi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Rwi) Close() { + if ind.handle != nil { + C.wickra_rwi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SampleEntropy wraps the SampleEntropy indicator over the Wickra C ABI. +type SampleEntropy struct { + handle *C.struct_SampleEntropy +} + +// NewSampleEntropy constructs a SampleEntropy. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSampleEntropy(period int, m int, rFactor float64) (*SampleEntropy, error) { + ptr := C.wickra_sample_entropy_new(C.uintptr_t(period), C.uintptr_t(m), C.double(rFactor)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SampleEntropy{handle: ptr} + runtime.SetFinalizer(obj, (*SampleEntropy).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SampleEntropy) Update(value float64) float64 { + r := float64(C.wickra_sample_entropy_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SampleEntropy) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sample_entropy_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SampleEntropy) Reset() { + C.wickra_sample_entropy_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SampleEntropy) Close() { + if ind.handle != nil { + C.wickra_sample_entropy_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SarExt wraps the SarExt indicator over the Wickra C ABI. +type SarExt struct { + handle *C.struct_SarExt +} + +// NewSarExt constructs a SarExt. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSarExt(startValue float64, offsetOnReverse float64, accelInitLong float64, accelLong float64, accelMaxLong float64, accelInitShort float64, accelShort float64, accelMaxShort float64) (*SarExt, error) { + ptr := C.wickra_sar_ext_new(C.double(startValue), C.double(offsetOnReverse), C.double(accelInitLong), C.double(accelLong), C.double(accelMaxLong), C.double(accelInitShort), C.double(accelShort), C.double(accelMaxShort)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SarExt{handle: ptr} + runtime.SetFinalizer(obj, (*SarExt).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SarExt) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_sar_ext_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SarExt) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sar_ext_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SarExt) Reset() { + C.wickra_sar_ext_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SarExt) Close() { + if ind.handle != nil { + C.wickra_sar_ext_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SeasonalZScore wraps the SeasonalZScore indicator over the Wickra C ABI. +type SeasonalZScore struct { + handle *C.struct_SeasonalZScore +} + +// NewSeasonalZScore constructs a SeasonalZScore. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSeasonalZScore(utcOffsetMinutes int32) (*SeasonalZScore, error) { + ptr := C.wickra_seasonal_z_score_new(C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SeasonalZScore{handle: ptr} + runtime.SetFinalizer(obj, (*SeasonalZScore).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SeasonalZScore) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_seasonal_z_score_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SeasonalZScore) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_seasonal_z_score_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SeasonalZScore) Reset() { + C.wickra_seasonal_z_score_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SeasonalZScore) Close() { + if ind.handle != nil { + C.wickra_seasonal_z_score_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SeparatingLines wraps the SeparatingLines indicator over the Wickra C ABI. +type SeparatingLines struct { + handle *C.struct_SeparatingLines +} + +// NewSeparatingLines constructs a SeparatingLines. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSeparatingLines() (*SeparatingLines, error) { + ptr := C.wickra_separating_lines_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SeparatingLines{handle: ptr} + runtime.SetFinalizer(obj, (*SeparatingLines).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SeparatingLines) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_separating_lines_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SeparatingLines) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_separating_lines_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SeparatingLines) Reset() { + C.wickra_separating_lines_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SeparatingLines) Close() { + if ind.handle != nil { + C.wickra_separating_lines_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SessionHighLow wraps the SessionHighLow indicator over the Wickra C ABI. +type SessionHighLow struct { + handle *C.struct_SessionHighLow +} + +// NewSessionHighLow constructs a SessionHighLow. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSessionHighLow(utcOffsetMinutes int32) (*SessionHighLow, error) { + ptr := C.wickra_session_high_low_new(C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SessionHighLow{handle: ptr} + runtime.SetFinalizer(obj, (*SessionHighLow).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *SessionHighLow) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (SessionHighLowOutput, bool) { + var out C.struct_WickraSessionHighLowOutput + ok := bool(C.wickra_session_high_low_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return SessionHighLowOutput{}, false + } + return SessionHighLowOutput{float64(out.high), float64(out.low)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SessionHighLow) Reset() { + C.wickra_session_high_low_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SessionHighLow) Close() { + if ind.handle != nil { + C.wickra_session_high_low_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SessionRange wraps the SessionRange indicator over the Wickra C ABI. +type SessionRange struct { + handle *C.struct_SessionRange +} + +// NewSessionRange constructs a SessionRange. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSessionRange(utcOffsetMinutes int32) (*SessionRange, error) { + ptr := C.wickra_session_range_new(C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SessionRange{handle: ptr} + runtime.SetFinalizer(obj, (*SessionRange).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *SessionRange) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (SessionRangeOutput, bool) { + var out C.struct_WickraSessionRangeOutput + ok := bool(C.wickra_session_range_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return SessionRangeOutput{}, false + } + return SessionRangeOutput{float64(out.asia), float64(out.eu), float64(out.us)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SessionRange) Reset() { + C.wickra_session_range_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SessionRange) Close() { + if ind.handle != nil { + C.wickra_session_range_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SessionVwap wraps the SessionVwap indicator over the Wickra C ABI. +type SessionVwap struct { + handle *C.struct_SessionVwap +} + +// NewSessionVwap constructs a SessionVwap. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSessionVwap(utcOffsetMinutes int32) (*SessionVwap, error) { + ptr := C.wickra_session_vwap_new(C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SessionVwap{handle: ptr} + runtime.SetFinalizer(obj, (*SessionVwap).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SessionVwap) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_session_vwap_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SessionVwap) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_session_vwap_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SessionVwap) Reset() { + C.wickra_session_vwap_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SessionVwap) Close() { + if ind.handle != nil { + C.wickra_session_vwap_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ShannonEntropy wraps the ShannonEntropy indicator over the Wickra C ABI. +type ShannonEntropy struct { + handle *C.struct_ShannonEntropy +} + +// NewShannonEntropy constructs a ShannonEntropy. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewShannonEntropy(period int, bins int) (*ShannonEntropy, error) { + ptr := C.wickra_shannon_entropy_new(C.uintptr_t(period), C.uintptr_t(bins)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ShannonEntropy{handle: ptr} + runtime.SetFinalizer(obj, (*ShannonEntropy).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ShannonEntropy) Update(value float64) float64 { + r := float64(C.wickra_shannon_entropy_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ShannonEntropy) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_shannon_entropy_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ShannonEntropy) Reset() { + C.wickra_shannon_entropy_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ShannonEntropy) Close() { + if ind.handle != nil { + C.wickra_shannon_entropy_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Shark wraps the Shark indicator over the Wickra C ABI. +type Shark struct { + handle *C.struct_Shark +} + +// NewShark constructs a Shark. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewShark() (*Shark, error) { + ptr := C.wickra_shark_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Shark{handle: ptr} + runtime.SetFinalizer(obj, (*Shark).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Shark) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_shark_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Shark) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_shark_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Shark) Reset() { + C.wickra_shark_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Shark) Close() { + if ind.handle != nil { + C.wickra_shark_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SharpeRatio wraps the SharpeRatio indicator over the Wickra C ABI. +type SharpeRatio struct { + handle *C.struct_SharpeRatio +} + +// NewSharpeRatio constructs a SharpeRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSharpeRatio(period int, riskFree float64) (*SharpeRatio, error) { + ptr := C.wickra_sharpe_ratio_new(C.uintptr_t(period), C.double(riskFree)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SharpeRatio{handle: ptr} + runtime.SetFinalizer(obj, (*SharpeRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SharpeRatio) Update(value float64) float64 { + r := float64(C.wickra_sharpe_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SharpeRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sharpe_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SharpeRatio) Reset() { + C.wickra_sharpe_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SharpeRatio) Close() { + if ind.handle != nil { + C.wickra_sharpe_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ShootingStar wraps the ShootingStar indicator over the Wickra C ABI. +type ShootingStar struct { + handle *C.struct_ShootingStar +} + +// NewShootingStar constructs a ShootingStar. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewShootingStar() (*ShootingStar, error) { + ptr := C.wickra_shooting_star_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ShootingStar{handle: ptr} + runtime.SetFinalizer(obj, (*ShootingStar).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ShootingStar) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_shooting_star_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ShootingStar) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_shooting_star_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ShootingStar) Reset() { + C.wickra_shooting_star_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ShootingStar) Close() { + if ind.handle != nil { + C.wickra_shooting_star_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ShortLine wraps the ShortLine indicator over the Wickra C ABI. +type ShortLine struct { + handle *C.struct_ShortLine +} + +// NewShortLine constructs a ShortLine. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewShortLine() (*ShortLine, error) { + ptr := C.wickra_short_line_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ShortLine{handle: ptr} + runtime.SetFinalizer(obj, (*ShortLine).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ShortLine) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_short_line_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ShortLine) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_short_line_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ShortLine) Reset() { + C.wickra_short_line_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ShortLine) Close() { + if ind.handle != nil { + C.wickra_short_line_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SignedVolume wraps the SignedVolume indicator over the Wickra C ABI. +type SignedVolume struct { + handle *C.struct_SignedVolume +} + +// NewSignedVolume constructs a SignedVolume. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSignedVolume() (*SignedVolume, error) { + ptr := C.wickra_signed_volume_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SignedVolume{handle: ptr} + runtime.SetFinalizer(obj, (*SignedVolume).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SignedVolume) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_signed_volume_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SignedVolume) Reset() { + C.wickra_signed_volume_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SignedVolume) Close() { + if ind.handle != nil { + C.wickra_signed_volume_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SineWave wraps the SineWave indicator over the Wickra C ABI. +type SineWave struct { + handle *C.struct_SineWave +} + +// NewSineWave constructs a SineWave. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSineWave() (*SineWave, error) { + ptr := C.wickra_sine_wave_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SineWave{handle: ptr} + runtime.SetFinalizer(obj, (*SineWave).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SineWave) Update(value float64) float64 { + r := float64(C.wickra_sine_wave_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SineWave) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sine_wave_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SineWave) Reset() { + C.wickra_sine_wave_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SineWave) Close() { + if ind.handle != nil { + C.wickra_sine_wave_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SineWeightedMa wraps the SineWeightedMa indicator over the Wickra C ABI. +type SineWeightedMa struct { + handle *C.struct_SineWeightedMa +} + +// NewSineWeightedMa constructs a SineWeightedMa. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSineWeightedMa(period int) (*SineWeightedMa, error) { + ptr := C.wickra_sine_weighted_ma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SineWeightedMa{handle: ptr} + runtime.SetFinalizer(obj, (*SineWeightedMa).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SineWeightedMa) Update(value float64) float64 { + r := float64(C.wickra_sine_weighted_ma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SineWeightedMa) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sine_weighted_ma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SineWeightedMa) Reset() { + C.wickra_sine_weighted_ma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SineWeightedMa) Close() { + if ind.handle != nil { + C.wickra_sine_weighted_ma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SinglePrints wraps the SinglePrints indicator over the Wickra C ABI. +type SinglePrints struct { + handle *C.struct_SinglePrints +} + +// NewSinglePrints constructs a SinglePrints. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSinglePrints(period int, bins int) (*SinglePrints, error) { + ptr := C.wickra_single_prints_new(C.uintptr_t(period), C.uintptr_t(bins)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SinglePrints{handle: ptr} + runtime.SetFinalizer(obj, (*SinglePrints).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SinglePrints) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_single_prints_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SinglePrints) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_single_prints_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SinglePrints) Reset() { + C.wickra_single_prints_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SinglePrints) Close() { + if ind.handle != nil { + C.wickra_single_prints_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Skewness wraps the Skewness indicator over the Wickra C ABI. +type Skewness struct { + handle *C.struct_Skewness +} + +// NewSkewness constructs a Skewness. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSkewness(period int) (*Skewness, error) { + ptr := C.wickra_skewness_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Skewness{handle: ptr} + runtime.SetFinalizer(obj, (*Skewness).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Skewness) Update(value float64) float64 { + r := float64(C.wickra_skewness_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Skewness) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_skewness_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Skewness) Reset() { + C.wickra_skewness_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Skewness) Close() { + if ind.handle != nil { + C.wickra_skewness_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Sma wraps the Sma indicator over the Wickra C ABI. +type Sma struct { + handle *C.struct_Sma +} + +// NewSma constructs a Sma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSma(period int) (*Sma, error) { + ptr := C.wickra_sma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Sma{handle: ptr} + runtime.SetFinalizer(obj, (*Sma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Sma) Update(value float64) float64 { + r := float64(C.wickra_sma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Sma) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Sma) Reset() { + C.wickra_sma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Sma) Close() { + if ind.handle != nil { + C.wickra_sma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Smi wraps the Smi indicator over the Wickra C ABI. +type Smi struct { + handle *C.struct_Smi +} + +// NewSmi constructs a Smi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSmi(period int, dPeriod int, d2Period int) (*Smi, error) { + ptr := C.wickra_smi_new(C.uintptr_t(period), C.uintptr_t(dPeriod), C.uintptr_t(d2Period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Smi{handle: ptr} + runtime.SetFinalizer(obj, (*Smi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Smi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_smi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Smi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_smi_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Smi) Reset() { + C.wickra_smi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Smi) Close() { + if ind.handle != nil { + C.wickra_smi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Smma wraps the Smma indicator over the Wickra C ABI. +type Smma struct { + handle *C.struct_Smma +} + +// NewSmma constructs a Smma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSmma(period int) (*Smma, error) { + ptr := C.wickra_smma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Smma{handle: ptr} + runtime.SetFinalizer(obj, (*Smma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Smma) Update(value float64) float64 { + r := float64(C.wickra_smma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Smma) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_smma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Smma) Reset() { + C.wickra_smma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Smma) Close() { + if ind.handle != nil { + C.wickra_smma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SmoothedHeikinAshi wraps the SmoothedHeikinAshi indicator over the Wickra C ABI. +type SmoothedHeikinAshi struct { + handle *C.struct_SmoothedHeikinAshi +} + +// NewSmoothedHeikinAshi constructs a SmoothedHeikinAshi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSmoothedHeikinAshi(period int) (*SmoothedHeikinAshi, error) { + ptr := C.wickra_smoothed_heikin_ashi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SmoothedHeikinAshi{handle: ptr} + runtime.SetFinalizer(obj, (*SmoothedHeikinAshi).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *SmoothedHeikinAshi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (SmoothedHeikinAshiOutput, bool) { + var out C.struct_WickraSmoothedHeikinAshiOutput + ok := bool(C.wickra_smoothed_heikin_ashi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return SmoothedHeikinAshiOutput{}, false + } + return SmoothedHeikinAshiOutput{float64(out.open), float64(out.high), float64(out.low), float64(out.close)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SmoothedHeikinAshi) Reset() { + C.wickra_smoothed_heikin_ashi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SmoothedHeikinAshi) Close() { + if ind.handle != nil { + C.wickra_smoothed_heikin_ashi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SortinoRatio wraps the SortinoRatio indicator over the Wickra C ABI. +type SortinoRatio struct { + handle *C.struct_SortinoRatio +} + +// NewSortinoRatio constructs a SortinoRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSortinoRatio(period int, mar float64) (*SortinoRatio, error) { + ptr := C.wickra_sortino_ratio_new(C.uintptr_t(period), C.double(mar)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SortinoRatio{handle: ptr} + runtime.SetFinalizer(obj, (*SortinoRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SortinoRatio) Update(value float64) float64 { + r := float64(C.wickra_sortino_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SortinoRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sortino_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SortinoRatio) Reset() { + C.wickra_sortino_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SortinoRatio) Close() { + if ind.handle != nil { + C.wickra_sortino_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SpearmanCorrelation wraps the SpearmanCorrelation indicator over the Wickra C ABI. +type SpearmanCorrelation struct { + handle *C.struct_SpearmanCorrelation +} + +// NewSpearmanCorrelation constructs a SpearmanCorrelation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSpearmanCorrelation(period int) (*SpearmanCorrelation, error) { + ptr := C.wickra_spearman_correlation_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SpearmanCorrelation{handle: ptr} + runtime.SetFinalizer(obj, (*SpearmanCorrelation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SpearmanCorrelation) Update(x float64, y float64) float64 { + r := float64(C.wickra_spearman_correlation_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SpearmanCorrelation) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_spearman_correlation_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SpearmanCorrelation) Reset() { + C.wickra_spearman_correlation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SpearmanCorrelation) Close() { + if ind.handle != nil { + C.wickra_spearman_correlation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SpinningTop wraps the SpinningTop indicator over the Wickra C ABI. +type SpinningTop struct { + handle *C.struct_SpinningTop +} + +// NewSpinningTop constructs a SpinningTop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSpinningTop() (*SpinningTop, error) { + ptr := C.wickra_spinning_top_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SpinningTop{handle: ptr} + runtime.SetFinalizer(obj, (*SpinningTop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SpinningTop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_spinning_top_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SpinningTop) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_spinning_top_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SpinningTop) Reset() { + C.wickra_spinning_top_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SpinningTop) Close() { + if ind.handle != nil { + C.wickra_spinning_top_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SpreadAr1Coefficient wraps the SpreadAr1Coefficient indicator over the Wickra C ABI. +type SpreadAr1Coefficient struct { + handle *C.struct_SpreadAr1Coefficient +} + +// NewSpreadAr1Coefficient constructs a SpreadAr1Coefficient. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSpreadAr1Coefficient(period int) (*SpreadAr1Coefficient, error) { + ptr := C.wickra_spread_ar1_coefficient_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SpreadAr1Coefficient{handle: ptr} + runtime.SetFinalizer(obj, (*SpreadAr1Coefficient).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SpreadAr1Coefficient) Update(x float64, y float64) float64 { + r := float64(C.wickra_spread_ar1_coefficient_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SpreadAr1Coefficient) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_spread_ar1_coefficient_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SpreadAr1Coefficient) Reset() { + C.wickra_spread_ar1_coefficient_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SpreadAr1Coefficient) Close() { + if ind.handle != nil { + C.wickra_spread_ar1_coefficient_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SpreadBollingerBands wraps the SpreadBollingerBands indicator over the Wickra C ABI. +type SpreadBollingerBands struct { + handle *C.struct_SpreadBollingerBands +} + +// NewSpreadBollingerBands constructs a SpreadBollingerBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSpreadBollingerBands(period int, numStd float64) (*SpreadBollingerBands, error) { + ptr := C.wickra_spread_bollinger_bands_new(C.uintptr_t(period), C.double(numStd)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SpreadBollingerBands{handle: ptr} + runtime.SetFinalizer(obj, (*SpreadBollingerBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *SpreadBollingerBands) Update(x float64, y float64) (SpreadBollingerBandsOutput, bool) { + var out C.struct_WickraSpreadBollingerBandsOutput + ok := bool(C.wickra_spread_bollinger_bands_update(ind.handle, C.double(x), C.double(y), &out)) + runtime.KeepAlive(ind) + if !ok { + return SpreadBollingerBandsOutput{}, false + } + return SpreadBollingerBandsOutput{float64(out.middle), float64(out.upper), float64(out.lower), float64(out.percent_b)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SpreadBollingerBands) Reset() { + C.wickra_spread_bollinger_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SpreadBollingerBands) Close() { + if ind.handle != nil { + C.wickra_spread_bollinger_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SpreadHurst wraps the SpreadHurst indicator over the Wickra C ABI. +type SpreadHurst struct { + handle *C.struct_SpreadHurst +} + +// NewSpreadHurst constructs a SpreadHurst. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSpreadHurst(period int) (*SpreadHurst, error) { + ptr := C.wickra_spread_hurst_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SpreadHurst{handle: ptr} + runtime.SetFinalizer(obj, (*SpreadHurst).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SpreadHurst) Update(x float64, y float64) float64 { + r := float64(C.wickra_spread_hurst_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SpreadHurst) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_spread_hurst_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SpreadHurst) Reset() { + C.wickra_spread_hurst_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SpreadHurst) Close() { + if ind.handle != nil { + C.wickra_spread_hurst_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StalledPattern wraps the StalledPattern indicator over the Wickra C ABI. +type StalledPattern struct { + handle *C.struct_StalledPattern +} + +// NewStalledPattern constructs a StalledPattern. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStalledPattern() (*StalledPattern, error) { + ptr := C.wickra_stalled_pattern_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StalledPattern{handle: ptr} + runtime.SetFinalizer(obj, (*StalledPattern).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *StalledPattern) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_stalled_pattern_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *StalledPattern) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_stalled_pattern_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StalledPattern) Reset() { + C.wickra_stalled_pattern_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StalledPattern) Close() { + if ind.handle != nil { + C.wickra_stalled_pattern_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StandardError wraps the StandardError indicator over the Wickra C ABI. +type StandardError struct { + handle *C.struct_StandardError +} + +// NewStandardError constructs a StandardError. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStandardError(period int) (*StandardError, error) { + ptr := C.wickra_standard_error_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StandardError{handle: ptr} + runtime.SetFinalizer(obj, (*StandardError).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *StandardError) Update(value float64) float64 { + r := float64(C.wickra_standard_error_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *StandardError) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_standard_error_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StandardError) Reset() { + C.wickra_standard_error_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StandardError) Close() { + if ind.handle != nil { + C.wickra_standard_error_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StandardErrorBands wraps the StandardErrorBands indicator over the Wickra C ABI. +type StandardErrorBands struct { + handle *C.struct_StandardErrorBands +} + +// NewStandardErrorBands constructs a StandardErrorBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStandardErrorBands(period int, multiplier float64) (*StandardErrorBands, error) { + ptr := C.wickra_standard_error_bands_new(C.uintptr_t(period), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StandardErrorBands{handle: ptr} + runtime.SetFinalizer(obj, (*StandardErrorBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *StandardErrorBands) Update(value float64) (StandardErrorBandsOutput, bool) { + var out C.struct_WickraStandardErrorBandsOutput + ok := bool(C.wickra_standard_error_bands_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return StandardErrorBandsOutput{}, false + } + return StandardErrorBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StandardErrorBands) Reset() { + C.wickra_standard_error_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StandardErrorBands) Close() { + if ind.handle != nil { + C.wickra_standard_error_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StarcBands wraps the StarcBands indicator over the Wickra C ABI. +type StarcBands struct { + handle *C.struct_StarcBands +} + +// NewStarcBands constructs a StarcBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStarcBands(smaPeriod int, atrPeriod int, multiplier float64) (*StarcBands, error) { + ptr := C.wickra_starc_bands_new(C.uintptr_t(smaPeriod), C.uintptr_t(atrPeriod), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StarcBands{handle: ptr} + runtime.SetFinalizer(obj, (*StarcBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *StarcBands) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (StarcBandsOutput, bool) { + var out C.struct_WickraStarcBandsOutput + ok := bool(C.wickra_starc_bands_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return StarcBandsOutput{}, false + } + return StarcBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StarcBands) Reset() { + C.wickra_starc_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StarcBands) Close() { + if ind.handle != nil { + C.wickra_starc_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Stc wraps the Stc indicator over the Wickra C ABI. +type Stc struct { + handle *C.struct_Stc +} + +// NewStc constructs a Stc. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStc(fast int, slow int, schaffPeriod int, factor float64) (*Stc, error) { + ptr := C.wickra_stc_new(C.uintptr_t(fast), C.uintptr_t(slow), C.uintptr_t(schaffPeriod), C.double(factor)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Stc{handle: ptr} + runtime.SetFinalizer(obj, (*Stc).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Stc) Update(value float64) float64 { + r := float64(C.wickra_stc_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Stc) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_stc_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Stc) Reset() { + C.wickra_stc_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Stc) Close() { + if ind.handle != nil { + C.wickra_stc_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StdDev wraps the StdDev indicator over the Wickra C ABI. +type StdDev struct { + handle *C.struct_StdDev +} + +// NewStdDev constructs a StdDev. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStdDev(period int) (*StdDev, error) { + ptr := C.wickra_std_dev_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StdDev{handle: ptr} + runtime.SetFinalizer(obj, (*StdDev).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *StdDev) Update(value float64) float64 { + r := float64(C.wickra_std_dev_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *StdDev) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_std_dev_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StdDev) Reset() { + C.wickra_std_dev_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StdDev) Close() { + if ind.handle != nil { + C.wickra_std_dev_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StepTrailingStop wraps the StepTrailingStop indicator over the Wickra C ABI. +type StepTrailingStop struct { + handle *C.struct_StepTrailingStop +} + +// NewStepTrailingStop constructs a StepTrailingStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStepTrailingStop(stepSize float64) (*StepTrailingStop, error) { + ptr := C.wickra_step_trailing_stop_new(C.double(stepSize)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StepTrailingStop{handle: ptr} + runtime.SetFinalizer(obj, (*StepTrailingStop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *StepTrailingStop) Update(value float64) float64 { + r := float64(C.wickra_step_trailing_stop_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *StepTrailingStop) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_step_trailing_stop_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StepTrailingStop) Reset() { + C.wickra_step_trailing_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StepTrailingStop) Close() { + if ind.handle != nil { + C.wickra_step_trailing_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SterlingRatio wraps the SterlingRatio indicator over the Wickra C ABI. +type SterlingRatio struct { + handle *C.struct_SterlingRatio +} + +// NewSterlingRatio constructs a SterlingRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSterlingRatio(period int) (*SterlingRatio, error) { + ptr := C.wickra_sterling_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SterlingRatio{handle: ptr} + runtime.SetFinalizer(obj, (*SterlingRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SterlingRatio) Update(value float64) float64 { + r := float64(C.wickra_sterling_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SterlingRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_sterling_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SterlingRatio) Reset() { + C.wickra_sterling_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SterlingRatio) Close() { + if ind.handle != nil { + C.wickra_sterling_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StickSandwich wraps the StickSandwich indicator over the Wickra C ABI. +type StickSandwich struct { + handle *C.struct_StickSandwich +} + +// NewStickSandwich constructs a StickSandwich. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStickSandwich() (*StickSandwich, error) { + ptr := C.wickra_stick_sandwich_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StickSandwich{handle: ptr} + runtime.SetFinalizer(obj, (*StickSandwich).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *StickSandwich) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_stick_sandwich_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *StickSandwich) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_stick_sandwich_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StickSandwich) Reset() { + C.wickra_stick_sandwich_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StickSandwich) Close() { + if ind.handle != nil { + C.wickra_stick_sandwich_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StochRsi wraps the StochRsi indicator over the Wickra C ABI. +type StochRsi struct { + handle *C.struct_StochRsi +} + +// NewStochRsi constructs a StochRsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStochRsi(rsiPeriod int, stochPeriod int) (*StochRsi, error) { + ptr := C.wickra_stoch_rsi_new(C.uintptr_t(rsiPeriod), C.uintptr_t(stochPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StochRsi{handle: ptr} + runtime.SetFinalizer(obj, (*StochRsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *StochRsi) Update(value float64) float64 { + r := float64(C.wickra_stoch_rsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *StochRsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_stoch_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StochRsi) Reset() { + C.wickra_stoch_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StochRsi) Close() { + if ind.handle != nil { + C.wickra_stoch_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Stochastic wraps the Stochastic indicator over the Wickra C ABI. +type Stochastic struct { + handle *C.struct_Stochastic +} + +// NewStochastic constructs a Stochastic. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStochastic(kPeriod int, dPeriod int) (*Stochastic, error) { + ptr := C.wickra_stochastic_new(C.uintptr_t(kPeriod), C.uintptr_t(dPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Stochastic{handle: ptr} + runtime.SetFinalizer(obj, (*Stochastic).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Stochastic) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (StochasticOutput, bool) { + var out C.struct_WickraStochasticOutput + ok := bool(C.wickra_stochastic_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return StochasticOutput{}, false + } + return StochasticOutput{float64(out.k), float64(out.d)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Stochastic) Reset() { + C.wickra_stochastic_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Stochastic) Close() { + if ind.handle != nil { + C.wickra_stochastic_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// StochasticCci wraps the StochasticCci indicator over the Wickra C ABI. +type StochasticCci struct { + handle *C.struct_StochasticCci +} + +// NewStochasticCci constructs a StochasticCci. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewStochasticCci(period int) (*StochasticCci, error) { + ptr := C.wickra_stochastic_cci_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &StochasticCci{handle: ptr} + runtime.SetFinalizer(obj, (*StochasticCci).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *StochasticCci) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_stochastic_cci_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *StochasticCci) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_stochastic_cci_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *StochasticCci) Reset() { + C.wickra_stochastic_cci_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *StochasticCci) Close() { + if ind.handle != nil { + C.wickra_stochastic_cci_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SuperSmoother wraps the SuperSmoother indicator over the Wickra C ABI. +type SuperSmoother struct { + handle *C.struct_SuperSmoother +} + +// NewSuperSmoother constructs a SuperSmoother. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSuperSmoother(period int) (*SuperSmoother, error) { + ptr := C.wickra_super_smoother_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SuperSmoother{handle: ptr} + runtime.SetFinalizer(obj, (*SuperSmoother).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *SuperSmoother) Update(value float64) float64 { + r := float64(C.wickra_super_smoother_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *SuperSmoother) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_super_smoother_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SuperSmoother) Reset() { + C.wickra_super_smoother_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SuperSmoother) Close() { + if ind.handle != nil { + C.wickra_super_smoother_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// SuperTrend wraps the SuperTrend indicator over the Wickra C ABI. +type SuperTrend struct { + handle *C.struct_SuperTrend +} + +// NewSuperTrend constructs a SuperTrend. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewSuperTrend(atrPeriod int, multiplier float64) (*SuperTrend, error) { + ptr := C.wickra_super_trend_new(C.uintptr_t(atrPeriod), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &SuperTrend{handle: ptr} + runtime.SetFinalizer(obj, (*SuperTrend).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *SuperTrend) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (SuperTrendOutput, bool) { + var out C.struct_WickraSuperTrendOutput + ok := bool(C.wickra_super_trend_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return SuperTrendOutput{}, false + } + return SuperTrendOutput{float64(out.value), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *SuperTrend) Reset() { + C.wickra_super_trend_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *SuperTrend) Close() { + if ind.handle != nil { + C.wickra_super_trend_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// T3 wraps the T3 indicator over the Wickra C ABI. +type T3 struct { + handle *C.struct_T3 +} + +// NewT3 constructs a T3. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewT3(period int, v float64) (*T3, error) { + ptr := C.wickra_t3_new(C.uintptr_t(period), C.double(v)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &T3{handle: ptr} + runtime.SetFinalizer(obj, (*T3).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *T3) Update(value float64) float64 { + r := float64(C.wickra_t3_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *T3) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_t3_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *T3) Reset() { + C.wickra_t3_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *T3) Close() { + if ind.handle != nil { + C.wickra_t3_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TailRatio wraps the TailRatio indicator over the Wickra C ABI. +type TailRatio struct { + handle *C.struct_TailRatio +} + +// NewTailRatio constructs a TailRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTailRatio(period int) (*TailRatio, error) { + ptr := C.wickra_tail_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TailRatio{handle: ptr} + runtime.SetFinalizer(obj, (*TailRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TailRatio) Update(value float64) float64 { + r := float64(C.wickra_tail_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TailRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tail_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TailRatio) Reset() { + C.wickra_tail_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TailRatio) Close() { + if ind.handle != nil { + C.wickra_tail_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TakerBuySellRatio wraps the TakerBuySellRatio indicator over the Wickra C ABI. +type TakerBuySellRatio struct { + handle *C.struct_TakerBuySellRatio +} + +// NewTakerBuySellRatio constructs a TakerBuySellRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTakerBuySellRatio() (*TakerBuySellRatio, error) { + ptr := C.wickra_taker_buy_sell_ratio_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TakerBuySellRatio{handle: ptr} + runtime.SetFinalizer(obj, (*TakerBuySellRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TakerBuySellRatio) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_taker_buy_sell_ratio_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TakerBuySellRatio) Reset() { + C.wickra_taker_buy_sell_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TakerBuySellRatio) Close() { + if ind.handle != nil { + C.wickra_taker_buy_sell_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Takuri wraps the Takuri indicator over the Wickra C ABI. +type Takuri struct { + handle *C.struct_Takuri +} + +// NewTakuri constructs a Takuri. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTakuri() (*Takuri, error) { + ptr := C.wickra_takuri_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Takuri{handle: ptr} + runtime.SetFinalizer(obj, (*Takuri).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Takuri) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_takuri_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Takuri) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_takuri_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Takuri) Reset() { + C.wickra_takuri_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Takuri) Close() { + if ind.handle != nil { + C.wickra_takuri_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TasukiGap wraps the TasukiGap indicator over the Wickra C ABI. +type TasukiGap struct { + handle *C.struct_TasukiGap +} + +// NewTasukiGap constructs a TasukiGap. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTasukiGap() (*TasukiGap, error) { + ptr := C.wickra_tasuki_gap_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TasukiGap{handle: ptr} + runtime.SetFinalizer(obj, (*TasukiGap).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TasukiGap) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_tasuki_gap_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TasukiGap) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tasuki_gap_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TasukiGap) Reset() { + C.wickra_tasuki_gap_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TasukiGap) Close() { + if ind.handle != nil { + C.wickra_tasuki_gap_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdCamouflage wraps the TdCamouflage indicator over the Wickra C ABI. +type TdCamouflage struct { + handle *C.struct_TdCamouflage +} + +// NewTdCamouflage constructs a TdCamouflage. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdCamouflage() (*TdCamouflage, error) { + ptr := C.wickra_td_camouflage_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdCamouflage{handle: ptr} + runtime.SetFinalizer(obj, (*TdCamouflage).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdCamouflage) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_camouflage_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdCamouflage) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_camouflage_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdCamouflage) Reset() { + C.wickra_td_camouflage_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdCamouflage) Close() { + if ind.handle != nil { + C.wickra_td_camouflage_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdClop wraps the TdClop indicator over the Wickra C ABI. +type TdClop struct { + handle *C.struct_TdClop +} + +// NewTdClop constructs a TdClop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdClop() (*TdClop, error) { + ptr := C.wickra_td_clop_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdClop{handle: ptr} + runtime.SetFinalizer(obj, (*TdClop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdClop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_clop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdClop) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_clop_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdClop) Reset() { + C.wickra_td_clop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdClop) Close() { + if ind.handle != nil { + C.wickra_td_clop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdClopwin wraps the TdClopwin indicator over the Wickra C ABI. +type TdClopwin struct { + handle *C.struct_TdClopwin +} + +// NewTdClopwin constructs a TdClopwin. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdClopwin() (*TdClopwin, error) { + ptr := C.wickra_td_clopwin_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdClopwin{handle: ptr} + runtime.SetFinalizer(obj, (*TdClopwin).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdClopwin) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_clopwin_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdClopwin) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_clopwin_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdClopwin) Reset() { + C.wickra_td_clopwin_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdClopwin) Close() { + if ind.handle != nil { + C.wickra_td_clopwin_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdCombo wraps the TdCombo indicator over the Wickra C ABI. +type TdCombo struct { + handle *C.struct_TdCombo +} + +// NewTdCombo constructs a TdCombo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdCombo(setupLookback int, setupTarget int, countdownLookback int, countdownTarget int) (*TdCombo, error) { + ptr := C.wickra_td_combo_new(C.uintptr_t(setupLookback), C.uintptr_t(setupTarget), C.uintptr_t(countdownLookback), C.uintptr_t(countdownTarget)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdCombo{handle: ptr} + runtime.SetFinalizer(obj, (*TdCombo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdCombo) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_combo_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdCombo) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_combo_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdCombo) Reset() { + C.wickra_td_combo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdCombo) Close() { + if ind.handle != nil { + C.wickra_td_combo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdCountdown wraps the TdCountdown indicator over the Wickra C ABI. +type TdCountdown struct { + handle *C.struct_TdCountdown +} + +// NewTdCountdown constructs a TdCountdown. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdCountdown(setupLookback int, setupTarget int, countdownLookback int, countdownTarget int) (*TdCountdown, error) { + ptr := C.wickra_td_countdown_new(C.uintptr_t(setupLookback), C.uintptr_t(setupTarget), C.uintptr_t(countdownLookback), C.uintptr_t(countdownTarget)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdCountdown{handle: ptr} + runtime.SetFinalizer(obj, (*TdCountdown).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdCountdown) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_countdown_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdCountdown) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_countdown_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdCountdown) Reset() { + C.wickra_td_countdown_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdCountdown) Close() { + if ind.handle != nil { + C.wickra_td_countdown_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdDWave wraps the TdDWave indicator over the Wickra C ABI. +type TdDWave struct { + handle *C.struct_TdDWave +} + +// NewTdDWave constructs a TdDWave. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdDWave(strength int) (*TdDWave, error) { + ptr := C.wickra_td_d_wave_new(C.uintptr_t(strength)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdDWave{handle: ptr} + runtime.SetFinalizer(obj, (*TdDWave).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdDWave) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_d_wave_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdDWave) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_d_wave_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdDWave) Reset() { + C.wickra_td_d_wave_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdDWave) Close() { + if ind.handle != nil { + C.wickra_td_d_wave_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdDeMarker wraps the TdDeMarker indicator over the Wickra C ABI. +type TdDeMarker struct { + handle *C.struct_TdDeMarker +} + +// NewTdDeMarker constructs a TdDeMarker. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdDeMarker(period int) (*TdDeMarker, error) { + ptr := C.wickra_td_de_marker_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdDeMarker{handle: ptr} + runtime.SetFinalizer(obj, (*TdDeMarker).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdDeMarker) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_de_marker_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdDeMarker) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_de_marker_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdDeMarker) Reset() { + C.wickra_td_de_marker_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdDeMarker) Close() { + if ind.handle != nil { + C.wickra_td_de_marker_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdDifferential wraps the TdDifferential indicator over the Wickra C ABI. +type TdDifferential struct { + handle *C.struct_TdDifferential +} + +// NewTdDifferential constructs a TdDifferential. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdDifferential() (*TdDifferential, error) { + ptr := C.wickra_td_differential_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdDifferential{handle: ptr} + runtime.SetFinalizer(obj, (*TdDifferential).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdDifferential) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_differential_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdDifferential) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_differential_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdDifferential) Reset() { + C.wickra_td_differential_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdDifferential) Close() { + if ind.handle != nil { + C.wickra_td_differential_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdLines wraps the TdLines indicator over the Wickra C ABI. +type TdLines struct { + handle *C.struct_TdLines +} + +// NewTdLines constructs a TdLines. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdLines(lookback int, target int) (*TdLines, error) { + ptr := C.wickra_td_lines_new(C.uintptr_t(lookback), C.uintptr_t(target)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdLines{handle: ptr} + runtime.SetFinalizer(obj, (*TdLines).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *TdLines) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (TdLinesOutput, bool) { + var out C.struct_WickraTdLinesOutput + ok := bool(C.wickra_td_lines_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return TdLinesOutput{}, false + } + return TdLinesOutput{float64(out.resistance), float64(out.support)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdLines) Reset() { + C.wickra_td_lines_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdLines) Close() { + if ind.handle != nil { + C.wickra_td_lines_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdMovingAverage wraps the TdMovingAverage indicator over the Wickra C ABI. +type TdMovingAverage struct { + handle *C.struct_TdMovingAverage +} + +// NewTdMovingAverage constructs a TdMovingAverage. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdMovingAverage(periodSt1 int, periodSt2 int) (*TdMovingAverage, error) { + ptr := C.wickra_td_moving_average_new(C.uintptr_t(periodSt1), C.uintptr_t(periodSt2)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdMovingAverage{handle: ptr} + runtime.SetFinalizer(obj, (*TdMovingAverage).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *TdMovingAverage) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (TdMovingAverageOutput, bool) { + var out C.struct_WickraTdMovingAverageOutput + ok := bool(C.wickra_td_moving_average_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return TdMovingAverageOutput{}, false + } + return TdMovingAverageOutput{float64(out.st1), float64(out.st2)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdMovingAverage) Reset() { + C.wickra_td_moving_average_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdMovingAverage) Close() { + if ind.handle != nil { + C.wickra_td_moving_average_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdOpen wraps the TdOpen indicator over the Wickra C ABI. +type TdOpen struct { + handle *C.struct_TdOpen +} + +// NewTdOpen constructs a TdOpen. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdOpen() (*TdOpen, error) { + ptr := C.wickra_td_open_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdOpen{handle: ptr} + runtime.SetFinalizer(obj, (*TdOpen).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdOpen) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_open_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdOpen) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_open_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdOpen) Reset() { + C.wickra_td_open_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdOpen) Close() { + if ind.handle != nil { + C.wickra_td_open_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdPressure wraps the TdPressure indicator over the Wickra C ABI. +type TdPressure struct { + handle *C.struct_TdPressure +} + +// NewTdPressure constructs a TdPressure. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdPressure(period int) (*TdPressure, error) { + ptr := C.wickra_td_pressure_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdPressure{handle: ptr} + runtime.SetFinalizer(obj, (*TdPressure).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdPressure) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_pressure_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdPressure) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_pressure_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdPressure) Reset() { + C.wickra_td_pressure_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdPressure) Close() { + if ind.handle != nil { + C.wickra_td_pressure_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdPropulsion wraps the TdPropulsion indicator over the Wickra C ABI. +type TdPropulsion struct { + handle *C.struct_TdPropulsion +} + +// NewTdPropulsion constructs a TdPropulsion. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdPropulsion() (*TdPropulsion, error) { + ptr := C.wickra_td_propulsion_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdPropulsion{handle: ptr} + runtime.SetFinalizer(obj, (*TdPropulsion).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdPropulsion) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_propulsion_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdPropulsion) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_propulsion_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdPropulsion) Reset() { + C.wickra_td_propulsion_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdPropulsion) Close() { + if ind.handle != nil { + C.wickra_td_propulsion_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdRangeProjection wraps the TdRangeProjection indicator over the Wickra C ABI. +type TdRangeProjection struct { + handle *C.struct_TdRangeProjection +} + +// NewTdRangeProjection constructs a TdRangeProjection. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdRangeProjection() (*TdRangeProjection, error) { + ptr := C.wickra_td_range_projection_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdRangeProjection{handle: ptr} + runtime.SetFinalizer(obj, (*TdRangeProjection).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *TdRangeProjection) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (TdRangeProjectionOutput, bool) { + var out C.struct_WickraTdRangeProjectionOutput + ok := bool(C.wickra_td_range_projection_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return TdRangeProjectionOutput{}, false + } + return TdRangeProjectionOutput{float64(out.high), float64(out.low)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdRangeProjection) Reset() { + C.wickra_td_range_projection_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdRangeProjection) Close() { + if ind.handle != nil { + C.wickra_td_range_projection_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdRei wraps the TdRei indicator over the Wickra C ABI. +type TdRei struct { + handle *C.struct_TdRei +} + +// NewTdRei constructs a TdRei. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdRei(period int) (*TdRei, error) { + ptr := C.wickra_td_rei_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdRei{handle: ptr} + runtime.SetFinalizer(obj, (*TdRei).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdRei) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_rei_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdRei) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_rei_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdRei) Reset() { + C.wickra_td_rei_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdRei) Close() { + if ind.handle != nil { + C.wickra_td_rei_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdRiskLevel wraps the TdRiskLevel indicator over the Wickra C ABI. +type TdRiskLevel struct { + handle *C.struct_TdRiskLevel +} + +// NewTdRiskLevel constructs a TdRiskLevel. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdRiskLevel(lookback int, target int) (*TdRiskLevel, error) { + ptr := C.wickra_td_risk_level_new(C.uintptr_t(lookback), C.uintptr_t(target)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdRiskLevel{handle: ptr} + runtime.SetFinalizer(obj, (*TdRiskLevel).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *TdRiskLevel) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (TdRiskLevelOutput, bool) { + var out C.struct_WickraTdRiskLevelOutput + ok := bool(C.wickra_td_risk_level_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return TdRiskLevelOutput{}, false + } + return TdRiskLevelOutput{float64(out.buy_risk), float64(out.sell_risk)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdRiskLevel) Reset() { + C.wickra_td_risk_level_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdRiskLevel) Close() { + if ind.handle != nil { + C.wickra_td_risk_level_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdSequential wraps the TdSequential indicator over the Wickra C ABI. +type TdSequential struct { + handle *C.struct_TdSequential +} + +// NewTdSequential constructs a TdSequential. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdSequential(setupLookback int, setupTarget int, countdownLookback int, countdownTarget int) (*TdSequential, error) { + ptr := C.wickra_td_sequential_new(C.uintptr_t(setupLookback), C.uintptr_t(setupTarget), C.uintptr_t(countdownLookback), C.uintptr_t(countdownTarget)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdSequential{handle: ptr} + runtime.SetFinalizer(obj, (*TdSequential).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *TdSequential) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (TdSequentialOutput, bool) { + var out C.struct_WickraTdSequentialOutput + ok := bool(C.wickra_td_sequential_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return TdSequentialOutput{}, false + } + return TdSequentialOutput{float64(out.setup), float64(out.countdown), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdSequential) Reset() { + C.wickra_td_sequential_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdSequential) Close() { + if ind.handle != nil { + C.wickra_td_sequential_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdSetup wraps the TdSetup indicator over the Wickra C ABI. +type TdSetup struct { + handle *C.struct_TdSetup +} + +// NewTdSetup constructs a TdSetup. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdSetup(lookback int, target int) (*TdSetup, error) { + ptr := C.wickra_td_setup_new(C.uintptr_t(lookback), C.uintptr_t(target)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdSetup{handle: ptr} + runtime.SetFinalizer(obj, (*TdSetup).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdSetup) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_setup_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdSetup) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_setup_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdSetup) Reset() { + C.wickra_td_setup_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdSetup) Close() { + if ind.handle != nil { + C.wickra_td_setup_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TdTrap wraps the TdTrap indicator over the Wickra C ABI. +type TdTrap struct { + handle *C.struct_TdTrap +} + +// NewTdTrap constructs a TdTrap. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTdTrap() (*TdTrap, error) { + ptr := C.wickra_td_trap_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TdTrap{handle: ptr} + runtime.SetFinalizer(obj, (*TdTrap).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TdTrap) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_td_trap_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TdTrap) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_td_trap_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TdTrap) Reset() { + C.wickra_td_trap_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TdTrap) Close() { + if ind.handle != nil { + C.wickra_td_trap_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Tema wraps the Tema indicator over the Wickra C ABI. +type Tema struct { + handle *C.struct_Tema +} + +// NewTema constructs a Tema. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTema(period int) (*Tema, error) { + ptr := C.wickra_tema_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Tema{handle: ptr} + runtime.SetFinalizer(obj, (*Tema).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Tema) Update(value float64) float64 { + r := float64(C.wickra_tema_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Tema) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tema_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Tema) Reset() { + C.wickra_tema_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Tema) Close() { + if ind.handle != nil { + C.wickra_tema_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TermStructureBasis wraps the TermStructureBasis indicator over the Wickra C ABI. +type TermStructureBasis struct { + handle *C.struct_TermStructureBasis +} + +// NewTermStructureBasis constructs a TermStructureBasis. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTermStructureBasis() (*TermStructureBasis, error) { + ptr := C.wickra_term_structure_basis_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TermStructureBasis{handle: ptr} + runtime.SetFinalizer(obj, (*TermStructureBasis).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TermStructureBasis) Update(fundingRate float64, markPrice float64, indexPrice float64, futuresPrice float64, openInterest float64, longSize float64, shortSize float64, takerBuyVolume float64, takerSellVolume float64, longLiquidation float64, shortLiquidation float64, timestamp int64) float64 { + r := float64(C.wickra_term_structure_basis_update(ind.handle, C.double(fundingRate), C.double(markPrice), C.double(indexPrice), C.double(futuresPrice), C.double(openInterest), C.double(longSize), C.double(shortSize), C.double(takerBuyVolume), C.double(takerSellVolume), C.double(longLiquidation), C.double(shortLiquidation), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TermStructureBasis) Reset() { + C.wickra_term_structure_basis_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TermStructureBasis) Close() { + if ind.handle != nil { + C.wickra_term_structure_basis_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeDrives wraps the ThreeDrives indicator over the Wickra C ABI. +type ThreeDrives struct { + handle *C.struct_ThreeDrives +} + +// NewThreeDrives constructs a ThreeDrives. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeDrives() (*ThreeDrives, error) { + ptr := C.wickra_three_drives_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeDrives{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeDrives).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ThreeDrives) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_three_drives_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ThreeDrives) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_three_drives_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeDrives) Reset() { + C.wickra_three_drives_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeDrives) Close() { + if ind.handle != nil { + C.wickra_three_drives_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeInside wraps the ThreeInside indicator over the Wickra C ABI. +type ThreeInside struct { + handle *C.struct_ThreeInside +} + +// NewThreeInside constructs a ThreeInside. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeInside() (*ThreeInside, error) { + ptr := C.wickra_three_inside_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeInside{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeInside).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ThreeInside) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_three_inside_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ThreeInside) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_three_inside_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeInside) Reset() { + C.wickra_three_inside_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeInside) Close() { + if ind.handle != nil { + C.wickra_three_inside_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeLineBreak wraps the ThreeLineBreak indicator over the Wickra C ABI. +type ThreeLineBreak struct { + handle *C.struct_ThreeLineBreak +} + +// NewThreeLineBreak constructs a ThreeLineBreak. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeLineBreak(lines int) (*ThreeLineBreak, error) { + ptr := C.wickra_three_line_break_new(C.uintptr_t(lines)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeLineBreak{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeLineBreak).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ThreeLineBreak) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_three_line_break_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ThreeLineBreak) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_three_line_break_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeLineBreak) Reset() { + C.wickra_three_line_break_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeLineBreak) Close() { + if ind.handle != nil { + C.wickra_three_line_break_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeLineBreakBars wraps the ThreeLineBreakBars indicator over the Wickra C ABI. +type ThreeLineBreakBars struct { + handle *C.struct_ThreeLineBreakBars +} + +// NewThreeLineBreakBars constructs a ThreeLineBreakBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeLineBreakBars(lines int) (*ThreeLineBreakBars, error) { + ptr := C.wickra_three_line_break_bars_new(C.uintptr_t(lines)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeLineBreakBars{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeLineBreakBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *ThreeLineBreakBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []LineBreakBar { + const capacity = 64 + var buf [capacity]C.struct_WickraLineBreakBar + n := int(C.wickra_three_line_break_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]LineBreakBar, n) + for i := 0; i < n; i++ { + out[i] = LineBreakBar{float64(buf[i].open), float64(buf[i].close), int8(buf[i].direction)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeLineBreakBars) Reset() { + C.wickra_three_line_break_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeLineBreakBars) Close() { + if ind.handle != nil { + C.wickra_three_line_break_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeLineStrike wraps the ThreeLineStrike indicator over the Wickra C ABI. +type ThreeLineStrike struct { + handle *C.struct_ThreeLineStrike +} + +// NewThreeLineStrike constructs a ThreeLineStrike. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeLineStrike() (*ThreeLineStrike, error) { + ptr := C.wickra_three_line_strike_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeLineStrike{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeLineStrike).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ThreeLineStrike) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_three_line_strike_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ThreeLineStrike) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_three_line_strike_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeLineStrike) Reset() { + C.wickra_three_line_strike_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeLineStrike) Close() { + if ind.handle != nil { + C.wickra_three_line_strike_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeOutside wraps the ThreeOutside indicator over the Wickra C ABI. +type ThreeOutside struct { + handle *C.struct_ThreeOutside +} + +// NewThreeOutside constructs a ThreeOutside. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeOutside() (*ThreeOutside, error) { + ptr := C.wickra_three_outside_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeOutside{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeOutside).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ThreeOutside) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_three_outside_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ThreeOutside) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_three_outside_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeOutside) Reset() { + C.wickra_three_outside_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeOutside) Close() { + if ind.handle != nil { + C.wickra_three_outside_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeSoldiersOrCrows wraps the ThreeSoldiersOrCrows indicator over the Wickra C ABI. +type ThreeSoldiersOrCrows struct { + handle *C.struct_ThreeSoldiersOrCrows +} + +// NewThreeSoldiersOrCrows constructs a ThreeSoldiersOrCrows. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeSoldiersOrCrows() (*ThreeSoldiersOrCrows, error) { + ptr := C.wickra_three_soldiers_or_crows_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeSoldiersOrCrows{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeSoldiersOrCrows).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ThreeSoldiersOrCrows) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_three_soldiers_or_crows_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ThreeSoldiersOrCrows) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_three_soldiers_or_crows_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeSoldiersOrCrows) Reset() { + C.wickra_three_soldiers_or_crows_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeSoldiersOrCrows) Close() { + if ind.handle != nil { + C.wickra_three_soldiers_or_crows_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ThreeStarsInSouth wraps the ThreeStarsInSouth indicator over the Wickra C ABI. +type ThreeStarsInSouth struct { + handle *C.struct_ThreeStarsInSouth +} + +// NewThreeStarsInSouth constructs a ThreeStarsInSouth. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThreeStarsInSouth() (*ThreeStarsInSouth, error) { + ptr := C.wickra_three_stars_in_south_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ThreeStarsInSouth{handle: ptr} + runtime.SetFinalizer(obj, (*ThreeStarsInSouth).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ThreeStarsInSouth) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_three_stars_in_south_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ThreeStarsInSouth) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_three_stars_in_south_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ThreeStarsInSouth) Reset() { + C.wickra_three_stars_in_south_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ThreeStarsInSouth) Close() { + if ind.handle != nil { + C.wickra_three_stars_in_south_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Thrusting wraps the Thrusting indicator over the Wickra C ABI. +type Thrusting struct { + handle *C.struct_Thrusting +} + +// NewThrusting constructs a Thrusting. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewThrusting() (*Thrusting, error) { + ptr := C.wickra_thrusting_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Thrusting{handle: ptr} + runtime.SetFinalizer(obj, (*Thrusting).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Thrusting) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_thrusting_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Thrusting) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_thrusting_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Thrusting) Reset() { + C.wickra_thrusting_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Thrusting) Close() { + if ind.handle != nil { + C.wickra_thrusting_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TickBars wraps the TickBars indicator over the Wickra C ABI. +type TickBars struct { + handle *C.struct_TickBars +} + +// NewTickBars constructs a TickBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTickBars(ticks int) (*TickBars, error) { + ptr := C.wickra_tick_bars_new(C.uintptr_t(ticks)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TickBars{handle: ptr} + runtime.SetFinalizer(obj, (*TickBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *TickBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []TickBar { + const capacity = 64 + var buf [capacity]C.struct_WickraTickBar + n := int(C.wickra_tick_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]TickBar, n) + for i := 0; i < n; i++ { + out[i] = TickBar{float64(buf[i].open), float64(buf[i].high), float64(buf[i].low), float64(buf[i].close), float64(buf[i].volume)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TickBars) Reset() { + C.wickra_tick_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TickBars) Close() { + if ind.handle != nil { + C.wickra_tick_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TickIndex wraps the TickIndex indicator over the Wickra C ABI. +type TickIndex struct { + handle *C.struct_TickIndex +} + +// NewTickIndex constructs a TickIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTickIndex() (*TickIndex, error) { + ptr := C.wickra_tick_index_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TickIndex{handle: ptr} + runtime.SetFinalizer(obj, (*TickIndex).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *TickIndex) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_tick_index_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TickIndex) Reset() { + C.wickra_tick_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TickIndex) Close() { + if ind.handle != nil { + C.wickra_tick_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Tii wraps the Tii indicator over the Wickra C ABI. +type Tii struct { + handle *C.struct_Tii +} + +// NewTii constructs a Tii. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTii(smaPeriod int, devPeriod int) (*Tii, error) { + ptr := C.wickra_tii_new(C.uintptr_t(smaPeriod), C.uintptr_t(devPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Tii{handle: ptr} + runtime.SetFinalizer(obj, (*Tii).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Tii) Update(value float64) float64 { + r := float64(C.wickra_tii_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Tii) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tii_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Tii) Reset() { + C.wickra_tii_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Tii) Close() { + if ind.handle != nil { + C.wickra_tii_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TimeBasedStop wraps the TimeBasedStop indicator over the Wickra C ABI. +type TimeBasedStop struct { + handle *C.struct_TimeBasedStop +} + +// NewTimeBasedStop constructs a TimeBasedStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTimeBasedStop(maxBars int) (*TimeBasedStop, error) { + ptr := C.wickra_time_based_stop_new(C.uintptr_t(maxBars)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TimeBasedStop{handle: ptr} + runtime.SetFinalizer(obj, (*TimeBasedStop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TimeBasedStop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_time_based_stop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TimeBasedStop) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_time_based_stop_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TimeBasedStop) Reset() { + C.wickra_time_based_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TimeBasedStop) Close() { + if ind.handle != nil { + C.wickra_time_based_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TimeOfDayReturnProfile wraps the TimeOfDayReturnProfile indicator over the Wickra C ABI. +type TimeOfDayReturnProfile struct { + handle *C.struct_TimeOfDayReturnProfile + valuesCap int +} + +// NewTimeOfDayReturnProfile constructs a TimeOfDayReturnProfile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTimeOfDayReturnProfile(buckets int, utcOffsetMinutes int32) (*TimeOfDayReturnProfile, error) { + ptr := C.wickra_time_of_day_return_profile_new(C.uintptr_t(buckets), C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TimeOfDayReturnProfile{handle: ptr} + obj.valuesCap = buckets + runtime.SetFinalizer(obj, (*TimeOfDayReturnProfile).Close) + return obj, nil +} + +// Update feeds one observation and returns the profile values +// (ok is false during warmup). +func (ind *TimeOfDayReturnProfile) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) ([]float64, bool) { + values := make([]float64, ind.valuesCap) + n := int(C.wickra_time_of_day_return_profile_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), (*C.double)(unsafe.Pointer(&values[0])), C.uintptr_t(len(values)))) + runtime.KeepAlive(ind) + if n < 0 { + return nil, false + } + return values[:n], true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TimeOfDayReturnProfile) Reset() { + C.wickra_time_of_day_return_profile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TimeOfDayReturnProfile) Close() { + if ind.handle != nil { + C.wickra_time_of_day_return_profile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TowerTopBottom wraps the TowerTopBottom indicator over the Wickra C ABI. +type TowerTopBottom struct { + handle *C.struct_TowerTopBottom +} + +// NewTowerTopBottom constructs a TowerTopBottom. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTowerTopBottom() (*TowerTopBottom, error) { + ptr := C.wickra_tower_top_bottom_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TowerTopBottom{handle: ptr} + runtime.SetFinalizer(obj, (*TowerTopBottom).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TowerTopBottom) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_tower_top_bottom_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TowerTopBottom) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tower_top_bottom_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TowerTopBottom) Reset() { + C.wickra_tower_top_bottom_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TowerTopBottom) Close() { + if ind.handle != nil { + C.wickra_tower_top_bottom_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TpoProfile wraps the TpoProfile indicator over the Wickra C ABI. +type TpoProfile struct { + handle *C.struct_TpoProfile + valuesCap int +} + +// NewTpoProfile constructs a TpoProfile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTpoProfile(period int, binCount int) (*TpoProfile, error) { + ptr := C.wickra_tpo_profile_new(C.uintptr_t(period), C.uintptr_t(binCount)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TpoProfile{handle: ptr} + obj.valuesCap = binCount + runtime.SetFinalizer(obj, (*TpoProfile).Close) + return obj, nil +} + +// Update feeds one observation and returns the profile snapshot +// (ok is false during warmup). +func (ind *TpoProfile) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (TpoProfileOutputScalars, bool) { + values := make([]float64, ind.valuesCap) + var sc C.struct_WickraTpoProfileOutputScalars + n := int(C.wickra_tpo_profile_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &sc, (*C.double)(unsafe.Pointer(&values[0])), C.uintptr_t(len(values)))) + runtime.KeepAlive(ind) + if n < 0 { + return TpoProfileOutputScalars{}, false + } + return TpoProfileOutputScalars{PriceLow: float64(sc.price_low), PriceHigh: float64(sc.price_high), Values: values[:n]}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TpoProfile) Reset() { + C.wickra_tpo_profile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TpoProfile) Close() { + if ind.handle != nil { + C.wickra_tpo_profile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TradeImbalance wraps the TradeImbalance indicator over the Wickra C ABI. +type TradeImbalance struct { + handle *C.struct_TradeImbalance +} + +// NewTradeImbalance constructs a TradeImbalance. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTradeImbalance(window int) (*TradeImbalance, error) { + ptr := C.wickra_trade_imbalance_new(C.uintptr_t(window)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TradeImbalance{handle: ptr} + runtime.SetFinalizer(obj, (*TradeImbalance).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TradeImbalance) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_trade_imbalance_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TradeImbalance) Reset() { + C.wickra_trade_imbalance_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TradeImbalance) Close() { + if ind.handle != nil { + C.wickra_trade_imbalance_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TradeSignAutocorrelation wraps the TradeSignAutocorrelation indicator over the Wickra C ABI. +type TradeSignAutocorrelation struct { + handle *C.struct_TradeSignAutocorrelation +} + +// NewTradeSignAutocorrelation constructs a TradeSignAutocorrelation. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTradeSignAutocorrelation(period int) (*TradeSignAutocorrelation, error) { + ptr := C.wickra_trade_sign_autocorrelation_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TradeSignAutocorrelation{handle: ptr} + runtime.SetFinalizer(obj, (*TradeSignAutocorrelation).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TradeSignAutocorrelation) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_trade_sign_autocorrelation_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TradeSignAutocorrelation) Reset() { + C.wickra_trade_sign_autocorrelation_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TradeSignAutocorrelation) Close() { + if ind.handle != nil { + C.wickra_trade_sign_autocorrelation_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TradeVolumeIndex wraps the TradeVolumeIndex indicator over the Wickra C ABI. +type TradeVolumeIndex struct { + handle *C.struct_TradeVolumeIndex +} + +// NewTradeVolumeIndex constructs a TradeVolumeIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTradeVolumeIndex(minTick float64) (*TradeVolumeIndex, error) { + ptr := C.wickra_trade_volume_index_new(C.double(minTick)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TradeVolumeIndex{handle: ptr} + runtime.SetFinalizer(obj, (*TradeVolumeIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TradeVolumeIndex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_trade_volume_index_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TradeVolumeIndex) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_trade_volume_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TradeVolumeIndex) Reset() { + C.wickra_trade_volume_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TradeVolumeIndex) Close() { + if ind.handle != nil { + C.wickra_trade_volume_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TrendLabel wraps the TrendLabel indicator over the Wickra C ABI. +type TrendLabel struct { + handle *C.struct_TrendLabel +} + +// NewTrendLabel constructs a TrendLabel. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTrendLabel(period int) (*TrendLabel, error) { + ptr := C.wickra_trend_label_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TrendLabel{handle: ptr} + runtime.SetFinalizer(obj, (*TrendLabel).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TrendLabel) Update(value float64) float64 { + r := float64(C.wickra_trend_label_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TrendLabel) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_trend_label_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TrendLabel) Reset() { + C.wickra_trend_label_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TrendLabel) Close() { + if ind.handle != nil { + C.wickra_trend_label_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TrendStrengthIndex wraps the TrendStrengthIndex indicator over the Wickra C ABI. +type TrendStrengthIndex struct { + handle *C.struct_TrendStrengthIndex +} + +// NewTrendStrengthIndex constructs a TrendStrengthIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTrendStrengthIndex(period int) (*TrendStrengthIndex, error) { + ptr := C.wickra_trend_strength_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TrendStrengthIndex{handle: ptr} + runtime.SetFinalizer(obj, (*TrendStrengthIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TrendStrengthIndex) Update(value float64) float64 { + r := float64(C.wickra_trend_strength_index_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TrendStrengthIndex) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_trend_strength_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TrendStrengthIndex) Reset() { + C.wickra_trend_strength_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TrendStrengthIndex) Close() { + if ind.handle != nil { + C.wickra_trend_strength_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Trendflex wraps the Trendflex indicator over the Wickra C ABI. +type Trendflex struct { + handle *C.struct_Trendflex +} + +// NewTrendflex constructs a Trendflex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTrendflex(period int) (*Trendflex, error) { + ptr := C.wickra_trendflex_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Trendflex{handle: ptr} + runtime.SetFinalizer(obj, (*Trendflex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Trendflex) Update(value float64) float64 { + r := float64(C.wickra_trendflex_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Trendflex) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_trendflex_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Trendflex) Reset() { + C.wickra_trendflex_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Trendflex) Close() { + if ind.handle != nil { + C.wickra_trendflex_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TreynorRatio wraps the TreynorRatio indicator over the Wickra C ABI. +type TreynorRatio struct { + handle *C.struct_TreynorRatio +} + +// NewTreynorRatio constructs a TreynorRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTreynorRatio(period int, riskFree float64) (*TreynorRatio, error) { + ptr := C.wickra_treynor_ratio_new(C.uintptr_t(period), C.double(riskFree)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TreynorRatio{handle: ptr} + runtime.SetFinalizer(obj, (*TreynorRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TreynorRatio) Update(x float64, y float64) float64 { + r := float64(C.wickra_treynor_ratio_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TreynorRatio) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_treynor_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TreynorRatio) Reset() { + C.wickra_treynor_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TreynorRatio) Close() { + if ind.handle != nil { + C.wickra_treynor_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Triangle wraps the Triangle indicator over the Wickra C ABI. +type Triangle struct { + handle *C.struct_Triangle +} + +// NewTriangle constructs a Triangle. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTriangle() (*Triangle, error) { + ptr := C.wickra_triangle_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Triangle{handle: ptr} + runtime.SetFinalizer(obj, (*Triangle).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Triangle) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_triangle_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Triangle) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_triangle_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Triangle) Reset() { + C.wickra_triangle_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Triangle) Close() { + if ind.handle != nil { + C.wickra_triangle_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Trima wraps the Trima indicator over the Wickra C ABI. +type Trima struct { + handle *C.struct_Trima +} + +// NewTrima constructs a Trima. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTrima(period int) (*Trima, error) { + ptr := C.wickra_trima_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Trima{handle: ptr} + runtime.SetFinalizer(obj, (*Trima).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Trima) Update(value float64) float64 { + r := float64(C.wickra_trima_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Trima) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_trima_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Trima) Reset() { + C.wickra_trima_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Trima) Close() { + if ind.handle != nil { + C.wickra_trima_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Trin wraps the Trin indicator over the Wickra C ABI. +type Trin struct { + handle *C.struct_Trin +} + +// NewTrin constructs a Trin. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTrin() (*Trin, error) { + ptr := C.wickra_trin_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Trin{handle: ptr} + runtime.SetFinalizer(obj, (*Trin).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *Trin) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_trin_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Trin) Reset() { + C.wickra_trin_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Trin) Close() { + if ind.handle != nil { + C.wickra_trin_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TripleTopBottom wraps the TripleTopBottom indicator over the Wickra C ABI. +type TripleTopBottom struct { + handle *C.struct_TripleTopBottom +} + +// NewTripleTopBottom constructs a TripleTopBottom. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTripleTopBottom() (*TripleTopBottom, error) { + ptr := C.wickra_triple_top_bottom_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TripleTopBottom{handle: ptr} + runtime.SetFinalizer(obj, (*TripleTopBottom).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TripleTopBottom) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_triple_top_bottom_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TripleTopBottom) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_triple_top_bottom_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TripleTopBottom) Reset() { + C.wickra_triple_top_bottom_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TripleTopBottom) Close() { + if ind.handle != nil { + C.wickra_triple_top_bottom_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Tristar wraps the Tristar indicator over the Wickra C ABI. +type Tristar struct { + handle *C.struct_Tristar +} + +// NewTristar constructs a Tristar. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTristar() (*Tristar, error) { + ptr := C.wickra_tristar_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Tristar{handle: ptr} + runtime.SetFinalizer(obj, (*Tristar).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Tristar) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_tristar_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Tristar) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tristar_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Tristar) Reset() { + C.wickra_tristar_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Tristar) Close() { + if ind.handle != nil { + C.wickra_tristar_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Trix wraps the Trix indicator over the Wickra C ABI. +type Trix struct { + handle *C.struct_Trix +} + +// NewTrix constructs a Trix. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTrix(period int) (*Trix, error) { + ptr := C.wickra_trix_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Trix{handle: ptr} + runtime.SetFinalizer(obj, (*Trix).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Trix) Update(value float64) float64 { + r := float64(C.wickra_trix_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Trix) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_trix_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Trix) Reset() { + C.wickra_trix_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Trix) Close() { + if ind.handle != nil { + C.wickra_trix_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TrueRange wraps the TrueRange indicator over the Wickra C ABI. +type TrueRange struct { + handle *C.struct_TrueRange +} + +// NewTrueRange constructs a TrueRange. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTrueRange() (*TrueRange, error) { + ptr := C.wickra_true_range_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TrueRange{handle: ptr} + runtime.SetFinalizer(obj, (*TrueRange).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TrueRange) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_true_range_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TrueRange) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_true_range_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TrueRange) Reset() { + C.wickra_true_range_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TrueRange) Close() { + if ind.handle != nil { + C.wickra_true_range_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Tsf wraps the Tsf indicator over the Wickra C ABI. +type Tsf struct { + handle *C.struct_Tsf +} + +// NewTsf constructs a Tsf. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTsf(period int) (*Tsf, error) { + ptr := C.wickra_tsf_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Tsf{handle: ptr} + runtime.SetFinalizer(obj, (*Tsf).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Tsf) Update(value float64) float64 { + r := float64(C.wickra_tsf_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Tsf) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tsf_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Tsf) Reset() { + C.wickra_tsf_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Tsf) Close() { + if ind.handle != nil { + C.wickra_tsf_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TsfOscillator wraps the TsfOscillator indicator over the Wickra C ABI. +type TsfOscillator struct { + handle *C.struct_TsfOscillator +} + +// NewTsfOscillator constructs a TsfOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTsfOscillator(period int) (*TsfOscillator, error) { + ptr := C.wickra_tsf_oscillator_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TsfOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*TsfOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TsfOscillator) Update(value float64) float64 { + r := float64(C.wickra_tsf_oscillator_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TsfOscillator) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tsf_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TsfOscillator) Reset() { + C.wickra_tsf_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TsfOscillator) Close() { + if ind.handle != nil { + C.wickra_tsf_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Tsi wraps the Tsi indicator over the Wickra C ABI. +type Tsi struct { + handle *C.struct_Tsi +} + +// NewTsi constructs a Tsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTsi(long int, short int) (*Tsi, error) { + ptr := C.wickra_tsi_new(C.uintptr_t(long), C.uintptr_t(short)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Tsi{handle: ptr} + runtime.SetFinalizer(obj, (*Tsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Tsi) Update(value float64) float64 { + r := float64(C.wickra_tsi_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Tsi) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Tsi) Reset() { + C.wickra_tsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Tsi) Close() { + if ind.handle != nil { + C.wickra_tsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Tsv wraps the Tsv indicator over the Wickra C ABI. +type Tsv struct { + handle *C.struct_Tsv +} + +// NewTsv constructs a Tsv. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTsv(period int) (*Tsv, error) { + ptr := C.wickra_tsv_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Tsv{handle: ptr} + runtime.SetFinalizer(obj, (*Tsv).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Tsv) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_tsv_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Tsv) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tsv_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Tsv) Reset() { + C.wickra_tsv_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Tsv) Close() { + if ind.handle != nil { + C.wickra_tsv_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TtmSqueeze wraps the TtmSqueeze indicator over the Wickra C ABI. +type TtmSqueeze struct { + handle *C.struct_TtmSqueeze +} + +// NewTtmSqueeze constructs a TtmSqueeze. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTtmSqueeze(period int, bbMult float64, kcMult float64) (*TtmSqueeze, error) { + ptr := C.wickra_ttm_squeeze_new(C.uintptr_t(period), C.double(bbMult), C.double(kcMult)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TtmSqueeze{handle: ptr} + runtime.SetFinalizer(obj, (*TtmSqueeze).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *TtmSqueeze) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (TtmSqueezeOutput, bool) { + var out C.struct_WickraTtmSqueezeOutput + ok := bool(C.wickra_ttm_squeeze_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return TtmSqueezeOutput{}, false + } + return TtmSqueezeOutput{float64(out.squeeze), float64(out.momentum)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TtmSqueeze) Reset() { + C.wickra_ttm_squeeze_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TtmSqueeze) Close() { + if ind.handle != nil { + C.wickra_ttm_squeeze_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TtmTrend wraps the TtmTrend indicator over the Wickra C ABI. +type TtmTrend struct { + handle *C.struct_TtmTrend +} + +// NewTtmTrend constructs a TtmTrend. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTtmTrend(period int) (*TtmTrend, error) { + ptr := C.wickra_ttm_trend_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TtmTrend{handle: ptr} + runtime.SetFinalizer(obj, (*TtmTrend).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TtmTrend) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_ttm_trend_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TtmTrend) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ttm_trend_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TtmTrend) Reset() { + C.wickra_ttm_trend_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TtmTrend) Close() { + if ind.handle != nil { + C.wickra_ttm_trend_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TurnOfMonth wraps the TurnOfMonth indicator over the Wickra C ABI. +type TurnOfMonth struct { + handle *C.struct_TurnOfMonth +} + +// NewTurnOfMonth constructs a TurnOfMonth. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTurnOfMonth(nFirst uint32, nLast uint32, utcOffsetMinutes int32) (*TurnOfMonth, error) { + ptr := C.wickra_turn_of_month_new(C.uint32_t(nFirst), C.uint32_t(nLast), C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TurnOfMonth{handle: ptr} + runtime.SetFinalizer(obj, (*TurnOfMonth).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TurnOfMonth) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_turn_of_month_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TurnOfMonth) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_turn_of_month_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TurnOfMonth) Reset() { + C.wickra_turn_of_month_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TurnOfMonth) Close() { + if ind.handle != nil { + C.wickra_turn_of_month_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Tweezer wraps the Tweezer indicator over the Wickra C ABI. +type Tweezer struct { + handle *C.struct_Tweezer +} + +// NewTweezer constructs a Tweezer. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTweezer() (*Tweezer, error) { + ptr := C.wickra_tweezer_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Tweezer{handle: ptr} + runtime.SetFinalizer(obj, (*Tweezer).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Tweezer) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_tweezer_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Tweezer) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_tweezer_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Tweezer) Reset() { + C.wickra_tweezer_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Tweezer) Close() { + if ind.handle != nil { + C.wickra_tweezer_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TwiggsMoneyFlow wraps the TwiggsMoneyFlow indicator over the Wickra C ABI. +type TwiggsMoneyFlow struct { + handle *C.struct_TwiggsMoneyFlow +} + +// NewTwiggsMoneyFlow constructs a TwiggsMoneyFlow. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTwiggsMoneyFlow(period int) (*TwiggsMoneyFlow, error) { + ptr := C.wickra_twiggs_money_flow_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TwiggsMoneyFlow{handle: ptr} + runtime.SetFinalizer(obj, (*TwiggsMoneyFlow).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TwiggsMoneyFlow) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_twiggs_money_flow_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TwiggsMoneyFlow) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_twiggs_money_flow_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TwiggsMoneyFlow) Reset() { + C.wickra_twiggs_money_flow_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TwiggsMoneyFlow) Close() { + if ind.handle != nil { + C.wickra_twiggs_money_flow_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TwoCrows wraps the TwoCrows indicator over the Wickra C ABI. +type TwoCrows struct { + handle *C.struct_TwoCrows +} + +// NewTwoCrows constructs a TwoCrows. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTwoCrows() (*TwoCrows, error) { + ptr := C.wickra_two_crows_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TwoCrows{handle: ptr} + runtime.SetFinalizer(obj, (*TwoCrows).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TwoCrows) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_two_crows_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TwoCrows) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_two_crows_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TwoCrows) Reset() { + C.wickra_two_crows_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TwoCrows) Close() { + if ind.handle != nil { + C.wickra_two_crows_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// TypicalPrice wraps the TypicalPrice indicator over the Wickra C ABI. +type TypicalPrice struct { + handle *C.struct_TypicalPrice +} + +// NewTypicalPrice constructs a TypicalPrice. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewTypicalPrice() (*TypicalPrice, error) { + ptr := C.wickra_typical_price_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &TypicalPrice{handle: ptr} + runtime.SetFinalizer(obj, (*TypicalPrice).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *TypicalPrice) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_typical_price_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *TypicalPrice) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_typical_price_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *TypicalPrice) Reset() { + C.wickra_typical_price_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *TypicalPrice) Close() { + if ind.handle != nil { + C.wickra_typical_price_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UlcerIndex wraps the UlcerIndex indicator over the Wickra C ABI. +type UlcerIndex struct { + handle *C.struct_UlcerIndex +} + +// NewUlcerIndex constructs a UlcerIndex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUlcerIndex(period int) (*UlcerIndex, error) { + ptr := C.wickra_ulcer_index_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UlcerIndex{handle: ptr} + runtime.SetFinalizer(obj, (*UlcerIndex).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *UlcerIndex) Update(value float64) float64 { + r := float64(C.wickra_ulcer_index_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *UlcerIndex) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ulcer_index_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UlcerIndex) Reset() { + C.wickra_ulcer_index_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UlcerIndex) Close() { + if ind.handle != nil { + C.wickra_ulcer_index_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UltimateOscillator wraps the UltimateOscillator indicator over the Wickra C ABI. +type UltimateOscillator struct { + handle *C.struct_UltimateOscillator +} + +// NewUltimateOscillator constructs a UltimateOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUltimateOscillator(short int, mid int, long int) (*UltimateOscillator, error) { + ptr := C.wickra_ultimate_oscillator_new(C.uintptr_t(short), C.uintptr_t(mid), C.uintptr_t(long)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UltimateOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*UltimateOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *UltimateOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_ultimate_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *UltimateOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_ultimate_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UltimateOscillator) Reset() { + C.wickra_ultimate_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UltimateOscillator) Close() { + if ind.handle != nil { + C.wickra_ultimate_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UniqueThreeRiver wraps the UniqueThreeRiver indicator over the Wickra C ABI. +type UniqueThreeRiver struct { + handle *C.struct_UniqueThreeRiver +} + +// NewUniqueThreeRiver constructs a UniqueThreeRiver. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUniqueThreeRiver() (*UniqueThreeRiver, error) { + ptr := C.wickra_unique_three_river_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UniqueThreeRiver{handle: ptr} + runtime.SetFinalizer(obj, (*UniqueThreeRiver).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *UniqueThreeRiver) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_unique_three_river_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *UniqueThreeRiver) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_unique_three_river_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UniqueThreeRiver) Reset() { + C.wickra_unique_three_river_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UniqueThreeRiver) Close() { + if ind.handle != nil { + C.wickra_unique_three_river_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UniversalOscillator wraps the UniversalOscillator indicator over the Wickra C ABI. +type UniversalOscillator struct { + handle *C.struct_UniversalOscillator +} + +// NewUniversalOscillator constructs a UniversalOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUniversalOscillator(period int) (*UniversalOscillator, error) { + ptr := C.wickra_universal_oscillator_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UniversalOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*UniversalOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *UniversalOscillator) Update(value float64) float64 { + r := float64(C.wickra_universal_oscillator_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *UniversalOscillator) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_universal_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UniversalOscillator) Reset() { + C.wickra_universal_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UniversalOscillator) Close() { + if ind.handle != nil { + C.wickra_universal_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UpDownVolumeRatio wraps the UpDownVolumeRatio indicator over the Wickra C ABI. +type UpDownVolumeRatio struct { + handle *C.struct_UpDownVolumeRatio +} + +// NewUpDownVolumeRatio constructs a UpDownVolumeRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUpDownVolumeRatio() (*UpDownVolumeRatio, error) { + ptr := C.wickra_up_down_volume_ratio_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UpDownVolumeRatio{handle: ptr} + runtime.SetFinalizer(obj, (*UpDownVolumeRatio).Close) + return obj, nil +} + +// Update feeds one cross-sectional snapshot and returns the indicator +// value (NaN until warmed up). Slices in a group must share a length. +func (ind *UpDownVolumeRatio) Update(change []float64, volume []float64, newHigh []bool, newLow []bool, aboveMa []bool, onBuySignal []bool, timestamp int64) float64 { + if len(volume) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newHigh) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(newLow) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(aboveMa) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + if len(onBuySignal) != len(change) { + panic("wickra: input slices in the same group must have equal length") + } + r := float64(C.wickra_up_down_volume_ratio_update(ind.handle, (*C.double)(unsafe.Pointer(&change[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.bool)(unsafe.Pointer(&newHigh[0])), (*C.bool)(unsafe.Pointer(&newLow[0])), (*C.bool)(unsafe.Pointer(&aboveMa[0])), (*C.bool)(unsafe.Pointer(&onBuySignal[0])), C.uintptr_t(len(change)), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + runtime.KeepAlive(change) + runtime.KeepAlive(volume) + runtime.KeepAlive(newHigh) + runtime.KeepAlive(newLow) + runtime.KeepAlive(aboveMa) + runtime.KeepAlive(onBuySignal) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UpDownVolumeRatio) Reset() { + C.wickra_up_down_volume_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UpDownVolumeRatio) Close() { + if ind.handle != nil { + C.wickra_up_down_volume_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UpsideGapThreeMethods wraps the UpsideGapThreeMethods indicator over the Wickra C ABI. +type UpsideGapThreeMethods struct { + handle *C.struct_UpsideGapThreeMethods +} + +// NewUpsideGapThreeMethods constructs a UpsideGapThreeMethods. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUpsideGapThreeMethods() (*UpsideGapThreeMethods, error) { + ptr := C.wickra_upside_gap_three_methods_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UpsideGapThreeMethods{handle: ptr} + runtime.SetFinalizer(obj, (*UpsideGapThreeMethods).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *UpsideGapThreeMethods) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_upside_gap_three_methods_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *UpsideGapThreeMethods) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_upside_gap_three_methods_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UpsideGapThreeMethods) Reset() { + C.wickra_upside_gap_three_methods_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UpsideGapThreeMethods) Close() { + if ind.handle != nil { + C.wickra_upside_gap_three_methods_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UpsideGapTwoCrows wraps the UpsideGapTwoCrows indicator over the Wickra C ABI. +type UpsideGapTwoCrows struct { + handle *C.struct_UpsideGapTwoCrows +} + +// NewUpsideGapTwoCrows constructs a UpsideGapTwoCrows. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUpsideGapTwoCrows() (*UpsideGapTwoCrows, error) { + ptr := C.wickra_upside_gap_two_crows_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UpsideGapTwoCrows{handle: ptr} + runtime.SetFinalizer(obj, (*UpsideGapTwoCrows).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *UpsideGapTwoCrows) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_upside_gap_two_crows_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *UpsideGapTwoCrows) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_upside_gap_two_crows_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UpsideGapTwoCrows) Reset() { + C.wickra_upside_gap_two_crows_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UpsideGapTwoCrows) Close() { + if ind.handle != nil { + C.wickra_upside_gap_two_crows_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// UpsidePotentialRatio wraps the UpsidePotentialRatio indicator over the Wickra C ABI. +type UpsidePotentialRatio struct { + handle *C.struct_UpsidePotentialRatio +} + +// NewUpsidePotentialRatio constructs a UpsidePotentialRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewUpsidePotentialRatio(period int, mar float64) (*UpsidePotentialRatio, error) { + ptr := C.wickra_upside_potential_ratio_new(C.uintptr_t(period), C.double(mar)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &UpsidePotentialRatio{handle: ptr} + runtime.SetFinalizer(obj, (*UpsidePotentialRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *UpsidePotentialRatio) Update(value float64) float64 { + r := float64(C.wickra_upside_potential_ratio_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *UpsidePotentialRatio) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_upside_potential_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *UpsidePotentialRatio) Reset() { + C.wickra_upside_potential_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *UpsidePotentialRatio) Close() { + if ind.handle != nil { + C.wickra_upside_potential_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ValueArea wraps the ValueArea indicator over the Wickra C ABI. +type ValueArea struct { + handle *C.struct_ValueArea +} + +// NewValueArea constructs a ValueArea. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewValueArea(period int, binCount int, valueAreaPct float64) (*ValueArea, error) { + ptr := C.wickra_value_area_new(C.uintptr_t(period), C.uintptr_t(binCount), C.double(valueAreaPct)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ValueArea{handle: ptr} + runtime.SetFinalizer(obj, (*ValueArea).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ValueArea) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ValueAreaOutput, bool) { + var out C.struct_WickraValueAreaOutput + ok := bool(C.wickra_value_area_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ValueAreaOutput{}, false + } + return ValueAreaOutput{float64(out.poc), float64(out.vah), float64(out.val)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ValueArea) Reset() { + C.wickra_value_area_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ValueArea) Close() { + if ind.handle != nil { + C.wickra_value_area_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ValueAtRisk wraps the ValueAtRisk indicator over the Wickra C ABI. +type ValueAtRisk struct { + handle *C.struct_ValueAtRisk +} + +// NewValueAtRisk constructs a ValueAtRisk. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewValueAtRisk(period int, confidence float64) (*ValueAtRisk, error) { + ptr := C.wickra_value_at_risk_new(C.uintptr_t(period), C.double(confidence)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ValueAtRisk{handle: ptr} + runtime.SetFinalizer(obj, (*ValueAtRisk).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ValueAtRisk) Update(value float64) float64 { + r := float64(C.wickra_value_at_risk_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ValueAtRisk) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_value_at_risk_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ValueAtRisk) Reset() { + C.wickra_value_at_risk_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ValueAtRisk) Close() { + if ind.handle != nil { + C.wickra_value_at_risk_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Variance wraps the Variance indicator over the Wickra C ABI. +type Variance struct { + handle *C.struct_Variance +} + +// NewVariance constructs a Variance. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVariance(period int) (*Variance, error) { + ptr := C.wickra_variance_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Variance{handle: ptr} + runtime.SetFinalizer(obj, (*Variance).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Variance) Update(value float64) float64 { + r := float64(C.wickra_variance_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Variance) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_variance_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Variance) Reset() { + C.wickra_variance_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Variance) Close() { + if ind.handle != nil { + C.wickra_variance_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VarianceRatio wraps the VarianceRatio indicator over the Wickra C ABI. +type VarianceRatio struct { + handle *C.struct_VarianceRatio +} + +// NewVarianceRatio constructs a VarianceRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVarianceRatio(period int, q int) (*VarianceRatio, error) { + ptr := C.wickra_variance_ratio_new(C.uintptr_t(period), C.uintptr_t(q)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VarianceRatio{handle: ptr} + runtime.SetFinalizer(obj, (*VarianceRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VarianceRatio) Update(x float64, y float64) float64 { + r := float64(C.wickra_variance_ratio_update(ind.handle, C.double(x), C.double(y))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VarianceRatio) Batch(x []float64, y []float64) []float64 { + n := len(x) + if len(y) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_variance_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&x[0])), (*C.double)(unsafe.Pointer(&y[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(x) + runtime.KeepAlive(y) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VarianceRatio) Reset() { + C.wickra_variance_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VarianceRatio) Close() { + if ind.handle != nil { + C.wickra_variance_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VerticalHorizontalFilter wraps the VerticalHorizontalFilter indicator over the Wickra C ABI. +type VerticalHorizontalFilter struct { + handle *C.struct_VerticalHorizontalFilter +} + +// NewVerticalHorizontalFilter constructs a VerticalHorizontalFilter. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVerticalHorizontalFilter(period int) (*VerticalHorizontalFilter, error) { + ptr := C.wickra_vertical_horizontal_filter_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VerticalHorizontalFilter{handle: ptr} + runtime.SetFinalizer(obj, (*VerticalHorizontalFilter).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VerticalHorizontalFilter) Update(value float64) float64 { + r := float64(C.wickra_vertical_horizontal_filter_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VerticalHorizontalFilter) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_vertical_horizontal_filter_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VerticalHorizontalFilter) Reset() { + C.wickra_vertical_horizontal_filter_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VerticalHorizontalFilter) Close() { + if ind.handle != nil { + C.wickra_vertical_horizontal_filter_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Vidya wraps the Vidya indicator over the Wickra C ABI. +type Vidya struct { + handle *C.struct_Vidya +} + +// NewVidya constructs a Vidya. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVidya(period int, cmoPeriod int) (*Vidya, error) { + ptr := C.wickra_vidya_new(C.uintptr_t(period), C.uintptr_t(cmoPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Vidya{handle: ptr} + runtime.SetFinalizer(obj, (*Vidya).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Vidya) Update(value float64) float64 { + r := float64(C.wickra_vidya_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Vidya) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_vidya_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Vidya) Reset() { + C.wickra_vidya_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Vidya) Close() { + if ind.handle != nil { + C.wickra_vidya_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolatilityCone wraps the VolatilityCone indicator over the Wickra C ABI. +type VolatilityCone struct { + handle *C.struct_VolatilityCone +} + +// NewVolatilityCone constructs a VolatilityCone. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolatilityCone(window int, lookback int) (*VolatilityCone, error) { + ptr := C.wickra_volatility_cone_new(C.uintptr_t(window), C.uintptr_t(lookback)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolatilityCone{handle: ptr} + runtime.SetFinalizer(obj, (*VolatilityCone).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *VolatilityCone) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (VolatilityConeOutput, bool) { + var out C.struct_WickraVolatilityConeOutput + ok := bool(C.wickra_volatility_cone_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return VolatilityConeOutput{}, false + } + return VolatilityConeOutput{float64(out.current), float64(out.min), float64(out.median), float64(out.max), float64(out.percentile)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolatilityCone) Reset() { + C.wickra_volatility_cone_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolatilityCone) Close() { + if ind.handle != nil { + C.wickra_volatility_cone_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolatilityOfVolatility wraps the VolatilityOfVolatility indicator over the Wickra C ABI. +type VolatilityOfVolatility struct { + handle *C.struct_VolatilityOfVolatility +} + +// NewVolatilityOfVolatility constructs a VolatilityOfVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolatilityOfVolatility(volWindow int, vovWindow int) (*VolatilityOfVolatility, error) { + ptr := C.wickra_volatility_of_volatility_new(C.uintptr_t(volWindow), C.uintptr_t(vovWindow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolatilityOfVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*VolatilityOfVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VolatilityOfVolatility) Update(value float64) float64 { + r := float64(C.wickra_volatility_of_volatility_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VolatilityOfVolatility) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_volatility_of_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolatilityOfVolatility) Reset() { + C.wickra_volatility_of_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolatilityOfVolatility) Close() { + if ind.handle != nil { + C.wickra_volatility_of_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolatilityRatio wraps the VolatilityRatio indicator over the Wickra C ABI. +type VolatilityRatio struct { + handle *C.struct_VolatilityRatio +} + +// NewVolatilityRatio constructs a VolatilityRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolatilityRatio(period int) (*VolatilityRatio, error) { + ptr := C.wickra_volatility_ratio_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolatilityRatio{handle: ptr} + runtime.SetFinalizer(obj, (*VolatilityRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VolatilityRatio) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_volatility_ratio_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VolatilityRatio) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_volatility_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolatilityRatio) Reset() { + C.wickra_volatility_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolatilityRatio) Close() { + if ind.handle != nil { + C.wickra_volatility_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VoltyStop wraps the VoltyStop indicator over the Wickra C ABI. +type VoltyStop struct { + handle *C.struct_VoltyStop +} + +// NewVoltyStop constructs a VoltyStop. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVoltyStop(atrPeriod int, multiplier float64) (*VoltyStop, error) { + ptr := C.wickra_volty_stop_new(C.uintptr_t(atrPeriod), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VoltyStop{handle: ptr} + runtime.SetFinalizer(obj, (*VoltyStop).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VoltyStop) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_volty_stop_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VoltyStop) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_volty_stop_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VoltyStop) Reset() { + C.wickra_volty_stop_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VoltyStop) Close() { + if ind.handle != nil { + C.wickra_volty_stop_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumeBars wraps the VolumeBars indicator over the Wickra C ABI. +type VolumeBars struct { + handle *C.struct_VolumeBars +} + +// NewVolumeBars constructs a VolumeBars. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumeBars(volumePerBar float64) (*VolumeBars, error) { + ptr := C.wickra_volume_bars_new(C.double(volumePerBar)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumeBars{handle: ptr} + runtime.SetFinalizer(obj, (*VolumeBars).Close) + return obj, nil +} + +// Update feeds one candle and returns any bars completed by it +// (a single candle may complete several). +func (ind *VolumeBars) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) []VolumeBar { + const capacity = 64 + var buf [capacity]C.struct_WickraVolumeBar + n := int(C.wickra_volume_bars_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &buf[0], C.uintptr_t(capacity))) + runtime.KeepAlive(ind) + if n <= 0 { + return nil + } + out := make([]VolumeBar, n) + for i := 0; i < n; i++ { + out[i] = VolumeBar{float64(buf[i].open), float64(buf[i].high), float64(buf[i].low), float64(buf[i].close), float64(buf[i].volume)} + } + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumeBars) Reset() { + C.wickra_volume_bars_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumeBars) Close() { + if ind.handle != nil { + C.wickra_volume_bars_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumeByTimeProfile wraps the VolumeByTimeProfile indicator over the Wickra C ABI. +type VolumeByTimeProfile struct { + handle *C.struct_VolumeByTimeProfile + valuesCap int +} + +// NewVolumeByTimeProfile constructs a VolumeByTimeProfile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumeByTimeProfile(buckets int, utcOffsetMinutes int32) (*VolumeByTimeProfile, error) { + ptr := C.wickra_volume_by_time_profile_new(C.uintptr_t(buckets), C.int32_t(utcOffsetMinutes)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumeByTimeProfile{handle: ptr} + obj.valuesCap = buckets + runtime.SetFinalizer(obj, (*VolumeByTimeProfile).Close) + return obj, nil +} + +// Update feeds one observation and returns the profile values +// (ok is false during warmup). +func (ind *VolumeByTimeProfile) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) ([]float64, bool) { + values := make([]float64, ind.valuesCap) + n := int(C.wickra_volume_by_time_profile_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), (*C.double)(unsafe.Pointer(&values[0])), C.uintptr_t(len(values)))) + runtime.KeepAlive(ind) + if n < 0 { + return nil, false + } + return values[:n], true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumeByTimeProfile) Reset() { + C.wickra_volume_by_time_profile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumeByTimeProfile) Close() { + if ind.handle != nil { + C.wickra_volume_by_time_profile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumeOscillator wraps the VolumeOscillator indicator over the Wickra C ABI. +type VolumeOscillator struct { + handle *C.struct_VolumeOscillator +} + +// NewVolumeOscillator constructs a VolumeOscillator. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumeOscillator(fast int, slow int) (*VolumeOscillator, error) { + ptr := C.wickra_volume_oscillator_new(C.uintptr_t(fast), C.uintptr_t(slow)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumeOscillator{handle: ptr} + runtime.SetFinalizer(obj, (*VolumeOscillator).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VolumeOscillator) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_volume_oscillator_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VolumeOscillator) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_volume_oscillator_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumeOscillator) Reset() { + C.wickra_volume_oscillator_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumeOscillator) Close() { + if ind.handle != nil { + C.wickra_volume_oscillator_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumePriceTrend wraps the VolumePriceTrend indicator over the Wickra C ABI. +type VolumePriceTrend struct { + handle *C.struct_VolumePriceTrend +} + +// NewVolumePriceTrend constructs a VolumePriceTrend. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumePriceTrend() (*VolumePriceTrend, error) { + ptr := C.wickra_volume_price_trend_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumePriceTrend{handle: ptr} + runtime.SetFinalizer(obj, (*VolumePriceTrend).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VolumePriceTrend) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_volume_price_trend_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VolumePriceTrend) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_volume_price_trend_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumePriceTrend) Reset() { + C.wickra_volume_price_trend_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumePriceTrend) Close() { + if ind.handle != nil { + C.wickra_volume_price_trend_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumeProfile wraps the VolumeProfile indicator over the Wickra C ABI. +type VolumeProfile struct { + handle *C.struct_VolumeProfile + valuesCap int +} + +// NewVolumeProfile constructs a VolumeProfile. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumeProfile(period int, binCount int) (*VolumeProfile, error) { + ptr := C.wickra_volume_profile_new(C.uintptr_t(period), C.uintptr_t(binCount)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumeProfile{handle: ptr} + obj.valuesCap = binCount + runtime.SetFinalizer(obj, (*VolumeProfile).Close) + return obj, nil +} + +// Update feeds one observation and returns the profile snapshot +// (ok is false during warmup). +func (ind *VolumeProfile) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (VolumeProfileOutputScalars, bool) { + values := make([]float64, ind.valuesCap) + var sc C.struct_WickraVolumeProfileOutputScalars + n := int(C.wickra_volume_profile_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &sc, (*C.double)(unsafe.Pointer(&values[0])), C.uintptr_t(len(values)))) + runtime.KeepAlive(ind) + if n < 0 { + return VolumeProfileOutputScalars{}, false + } + return VolumeProfileOutputScalars{PriceLow: float64(sc.price_low), PriceHigh: float64(sc.price_high), Values: values[:n]}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumeProfile) Reset() { + C.wickra_volume_profile_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumeProfile) Close() { + if ind.handle != nil { + C.wickra_volume_profile_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumeRsi wraps the VolumeRsi indicator over the Wickra C ABI. +type VolumeRsi struct { + handle *C.struct_VolumeRsi +} + +// NewVolumeRsi constructs a VolumeRsi. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumeRsi(period int) (*VolumeRsi, error) { + ptr := C.wickra_volume_rsi_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumeRsi{handle: ptr} + runtime.SetFinalizer(obj, (*VolumeRsi).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *VolumeRsi) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_volume_rsi_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *VolumeRsi) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_volume_rsi_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumeRsi) Reset() { + C.wickra_volume_rsi_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumeRsi) Close() { + if ind.handle != nil { + C.wickra_volume_rsi_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumeWeightedMacd wraps the VolumeWeightedMacd indicator over the Wickra C ABI. +type VolumeWeightedMacd struct { + handle *C.struct_VolumeWeightedMacd +} + +// NewVolumeWeightedMacd constructs a VolumeWeightedMacd. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumeWeightedMacd(fast int, slow int, signal int) (*VolumeWeightedMacd, error) { + ptr := C.wickra_volume_weighted_macd_new(C.uintptr_t(fast), C.uintptr_t(slow), C.uintptr_t(signal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumeWeightedMacd{handle: ptr} + runtime.SetFinalizer(obj, (*VolumeWeightedMacd).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *VolumeWeightedMacd) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (VolumeWeightedMacdOutput, bool) { + var out C.struct_WickraVolumeWeightedMacdOutput + ok := bool(C.wickra_volume_weighted_macd_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return VolumeWeightedMacdOutput{}, false + } + return VolumeWeightedMacdOutput{float64(out.macd), float64(out.signal), float64(out.histogram)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumeWeightedMacd) Reset() { + C.wickra_volume_weighted_macd_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumeWeightedMacd) Close() { + if ind.handle != nil { + C.wickra_volume_weighted_macd_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VolumeWeightedSr wraps the VolumeWeightedSr indicator over the Wickra C ABI. +type VolumeWeightedSr struct { + handle *C.struct_VolumeWeightedSr +} + +// NewVolumeWeightedSr constructs a VolumeWeightedSr. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVolumeWeightedSr(period int) (*VolumeWeightedSr, error) { + ptr := C.wickra_volume_weighted_sr_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VolumeWeightedSr{handle: ptr} + runtime.SetFinalizer(obj, (*VolumeWeightedSr).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *VolumeWeightedSr) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (VolumeWeightedSrOutput, bool) { + var out C.struct_WickraVolumeWeightedSrOutput + ok := bool(C.wickra_volume_weighted_sr_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return VolumeWeightedSrOutput{}, false + } + return VolumeWeightedSrOutput{float64(out.support), float64(out.resistance)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VolumeWeightedSr) Reset() { + C.wickra_volume_weighted_sr_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VolumeWeightedSr) Close() { + if ind.handle != nil { + C.wickra_volume_weighted_sr_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Vortex wraps the Vortex indicator over the Wickra C ABI. +type Vortex struct { + handle *C.struct_Vortex +} + +// NewVortex constructs a Vortex. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVortex(period int) (*Vortex, error) { + ptr := C.wickra_vortex_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Vortex{handle: ptr} + runtime.SetFinalizer(obj, (*Vortex).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *Vortex) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (VortexOutput, bool) { + var out C.struct_WickraVortexOutput + ok := bool(C.wickra_vortex_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return VortexOutput{}, false + } + return VortexOutput{float64(out.plus), float64(out.minus)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Vortex) Reset() { + C.wickra_vortex_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Vortex) Close() { + if ind.handle != nil { + C.wickra_vortex_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Vpin wraps the Vpin indicator over the Wickra C ABI. +type Vpin struct { + handle *C.struct_Vpin +} + +// NewVpin constructs a Vpin. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVpin(bucketVolume float64, numBuckets int) (*Vpin, error) { + ptr := C.wickra_vpin_new(C.double(bucketVolume), C.uintptr_t(numBuckets)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Vpin{handle: ptr} + runtime.SetFinalizer(obj, (*Vpin).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Vpin) Update(price float64, size float64, isBuy bool, timestamp int64) float64 { + r := float64(C.wickra_vpin_update(ind.handle, C.double(price), C.double(size), C.bool(isBuy), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Vpin) Reset() { + C.wickra_vpin_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Vpin) Close() { + if ind.handle != nil { + C.wickra_vpin_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Vwap wraps the Vwap indicator over the Wickra C ABI. +type Vwap struct { + handle *C.struct_Vwap +} + +// NewVwap constructs a Vwap. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVwap() (*Vwap, error) { + ptr := C.wickra_vwap_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Vwap{handle: ptr} + runtime.SetFinalizer(obj, (*Vwap).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Vwap) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_vwap_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Vwap) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_vwap_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Vwap) Reset() { + C.wickra_vwap_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Vwap) Close() { + if ind.handle != nil { + C.wickra_vwap_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// VwapStdDevBands wraps the VwapStdDevBands indicator over the Wickra C ABI. +type VwapStdDevBands struct { + handle *C.struct_VwapStdDevBands +} + +// NewVwapStdDevBands constructs a VwapStdDevBands. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVwapStdDevBands(multiplier float64) (*VwapStdDevBands, error) { + ptr := C.wickra_vwap_std_dev_bands_new(C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &VwapStdDevBands{handle: ptr} + runtime.SetFinalizer(obj, (*VwapStdDevBands).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *VwapStdDevBands) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (VwapStdDevBandsOutput, bool) { + var out C.struct_WickraVwapStdDevBandsOutput + ok := bool(C.wickra_vwap_std_dev_bands_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return VwapStdDevBandsOutput{}, false + } + return VwapStdDevBandsOutput{float64(out.upper), float64(out.middle), float64(out.lower), float64(out.stddev)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *VwapStdDevBands) Reset() { + C.wickra_vwap_std_dev_bands_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *VwapStdDevBands) Close() { + if ind.handle != nil { + C.wickra_vwap_std_dev_bands_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Vwma wraps the Vwma indicator over the Wickra C ABI. +type Vwma struct { + handle *C.struct_Vwma +} + +// NewVwma constructs a Vwma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVwma(period int) (*Vwma, error) { + ptr := C.wickra_vwma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Vwma{handle: ptr} + runtime.SetFinalizer(obj, (*Vwma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Vwma) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_vwma_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Vwma) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_vwma_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Vwma) Reset() { + C.wickra_vwma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Vwma) Close() { + if ind.handle != nil { + C.wickra_vwma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Vzo wraps the Vzo indicator over the Wickra C ABI. +type Vzo struct { + handle *C.struct_Vzo +} + +// NewVzo constructs a Vzo. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewVzo(period int) (*Vzo, error) { + ptr := C.wickra_vzo_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Vzo{handle: ptr} + runtime.SetFinalizer(obj, (*Vzo).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Vzo) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_vzo_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Vzo) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_vzo_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Vzo) Reset() { + C.wickra_vzo_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Vzo) Close() { + if ind.handle != nil { + C.wickra_vzo_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Wad wraps the Wad indicator over the Wickra C ABI. +type Wad struct { + handle *C.struct_Wad +} + +// NewWad constructs a Wad. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWad() (*Wad, error) { + ptr := C.wickra_wad_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Wad{handle: ptr} + runtime.SetFinalizer(obj, (*Wad).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Wad) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_wad_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Wad) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_wad_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Wad) Reset() { + C.wickra_wad_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Wad) Close() { + if ind.handle != nil { + C.wickra_wad_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WavePm wraps the WavePm indicator over the Wickra C ABI. +type WavePm struct { + handle *C.struct_WavePm +} + +// NewWavePm constructs a WavePm. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWavePm(length int, smoothing int) (*WavePm, error) { + ptr := C.wickra_wave_pm_new(C.uintptr_t(length), C.uintptr_t(smoothing)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WavePm{handle: ptr} + runtime.SetFinalizer(obj, (*WavePm).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *WavePm) Update(value float64) float64 { + r := float64(C.wickra_wave_pm_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *WavePm) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_wave_pm_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WavePm) Reset() { + C.wickra_wave_pm_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WavePm) Close() { + if ind.handle != nil { + C.wickra_wave_pm_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WaveTrend wraps the WaveTrend indicator over the Wickra C ABI. +type WaveTrend struct { + handle *C.struct_WaveTrend +} + +// NewWaveTrend constructs a WaveTrend. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWaveTrend(channelPeriod int, averagePeriod int, signalPeriod int) (*WaveTrend, error) { + ptr := C.wickra_wave_trend_new(C.uintptr_t(channelPeriod), C.uintptr_t(averagePeriod), C.uintptr_t(signalPeriod)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WaveTrend{handle: ptr} + runtime.SetFinalizer(obj, (*WaveTrend).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *WaveTrend) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (WaveTrendOutput, bool) { + var out C.struct_WickraWaveTrendOutput + ok := bool(C.wickra_wave_trend_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return WaveTrendOutput{}, false + } + return WaveTrendOutput{float64(out.wt1), float64(out.wt2)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WaveTrend) Reset() { + C.wickra_wave_trend_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WaveTrend) Close() { + if ind.handle != nil { + C.wickra_wave_trend_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Wedge wraps the Wedge indicator over the Wickra C ABI. +type Wedge struct { + handle *C.struct_Wedge +} + +// NewWedge constructs a Wedge. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWedge() (*Wedge, error) { + ptr := C.wickra_wedge_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Wedge{handle: ptr} + runtime.SetFinalizer(obj, (*Wedge).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Wedge) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_wedge_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Wedge) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_wedge_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Wedge) Reset() { + C.wickra_wedge_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Wedge) Close() { + if ind.handle != nil { + C.wickra_wedge_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WeightedClose wraps the WeightedClose indicator over the Wickra C ABI. +type WeightedClose struct { + handle *C.struct_WeightedClose +} + +// NewWeightedClose constructs a WeightedClose. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWeightedClose() (*WeightedClose, error) { + ptr := C.wickra_weighted_close_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WeightedClose{handle: ptr} + runtime.SetFinalizer(obj, (*WeightedClose).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *WeightedClose) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_weighted_close_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *WeightedClose) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_weighted_close_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WeightedClose) Reset() { + C.wickra_weighted_close_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WeightedClose) Close() { + if ind.handle != nil { + C.wickra_weighted_close_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WickRatio wraps the WickRatio indicator over the Wickra C ABI. +type WickRatio struct { + handle *C.struct_WickRatio +} + +// NewWickRatio constructs a WickRatio. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWickRatio() (*WickRatio, error) { + ptr := C.wickra_wick_ratio_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WickRatio{handle: ptr} + runtime.SetFinalizer(obj, (*WickRatio).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *WickRatio) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_wick_ratio_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *WickRatio) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_wick_ratio_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WickRatio) Reset() { + C.wickra_wick_ratio_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WickRatio) Close() { + if ind.handle != nil { + C.wickra_wick_ratio_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WilliamsFractals wraps the WilliamsFractals indicator over the Wickra C ABI. +type WilliamsFractals struct { + handle *C.struct_WilliamsFractals +} + +// NewWilliamsFractals constructs a WilliamsFractals. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWilliamsFractals() (*WilliamsFractals, error) { + ptr := C.wickra_williams_fractals_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WilliamsFractals{handle: ptr} + runtime.SetFinalizer(obj, (*WilliamsFractals).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *WilliamsFractals) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (WilliamsFractalsOutput, bool) { + var out C.struct_WickraWilliamsFractalsOutput + ok := bool(C.wickra_williams_fractals_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return WilliamsFractalsOutput{}, false + } + return WilliamsFractalsOutput{float64(out.up), float64(out.down)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WilliamsFractals) Reset() { + C.wickra_williams_fractals_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WilliamsFractals) Close() { + if ind.handle != nil { + C.wickra_williams_fractals_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WilliamsR wraps the WilliamsR indicator over the Wickra C ABI. +type WilliamsR struct { + handle *C.struct_WilliamsR +} + +// NewWilliamsR constructs a WilliamsR. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWilliamsR(period int) (*WilliamsR, error) { + ptr := C.wickra_williams_r_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WilliamsR{handle: ptr} + runtime.SetFinalizer(obj, (*WilliamsR).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *WilliamsR) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_williams_r_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *WilliamsR) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_williams_r_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WilliamsR) Reset() { + C.wickra_williams_r_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WilliamsR) Close() { + if ind.handle != nil { + C.wickra_williams_r_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WinRate wraps the WinRate indicator over the Wickra C ABI. +type WinRate struct { + handle *C.struct_WinRate +} + +// NewWinRate constructs a WinRate. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWinRate(period int) (*WinRate, error) { + ptr := C.wickra_win_rate_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WinRate{handle: ptr} + runtime.SetFinalizer(obj, (*WinRate).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *WinRate) Update(value float64) float64 { + r := float64(C.wickra_win_rate_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *WinRate) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_win_rate_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WinRate) Reset() { + C.wickra_win_rate_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WinRate) Close() { + if ind.handle != nil { + C.wickra_win_rate_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Wma wraps the Wma indicator over the Wickra C ABI. +type Wma struct { + handle *C.struct_Wma +} + +// NewWma constructs a Wma. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWma(period int) (*Wma, error) { + ptr := C.wickra_wma_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Wma{handle: ptr} + runtime.SetFinalizer(obj, (*Wma).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Wma) Update(value float64) float64 { + r := float64(C.wickra_wma_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Wma) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_wma_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Wma) Reset() { + C.wickra_wma_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Wma) Close() { + if ind.handle != nil { + C.wickra_wma_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// WoodiePivots wraps the WoodiePivots indicator over the Wickra C ABI. +type WoodiePivots struct { + handle *C.struct_WoodiePivots +} + +// NewWoodiePivots constructs a WoodiePivots. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewWoodiePivots() (*WoodiePivots, error) { + ptr := C.wickra_woodie_pivots_new() + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &WoodiePivots{handle: ptr} + runtime.SetFinalizer(obj, (*WoodiePivots).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *WoodiePivots) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (WoodiePivotsOutput, bool) { + var out C.struct_WickraWoodiePivotsOutput + ok := bool(C.wickra_woodie_pivots_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return WoodiePivotsOutput{}, false + } + return WoodiePivotsOutput{float64(out.pp), float64(out.r1), float64(out.r2), float64(out.s1), float64(out.s2)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *WoodiePivots) Reset() { + C.wickra_woodie_pivots_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *WoodiePivots) Close() { + if ind.handle != nil { + C.wickra_woodie_pivots_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// YangZhangVolatility wraps the YangZhangVolatility indicator over the Wickra C ABI. +type YangZhangVolatility struct { + handle *C.struct_YangZhangVolatility +} + +// NewYangZhangVolatility constructs a YangZhangVolatility. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewYangZhangVolatility(period int, tradingPeriods int) (*YangZhangVolatility, error) { + ptr := C.wickra_yang_zhang_volatility_new(C.uintptr_t(period), C.uintptr_t(tradingPeriods)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &YangZhangVolatility{handle: ptr} + runtime.SetFinalizer(obj, (*YangZhangVolatility).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *YangZhangVolatility) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_yang_zhang_volatility_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *YangZhangVolatility) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_yang_zhang_volatility_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *YangZhangVolatility) Reset() { + C.wickra_yang_zhang_volatility_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *YangZhangVolatility) Close() { + if ind.handle != nil { + C.wickra_yang_zhang_volatility_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// YoyoExit wraps the YoyoExit indicator over the Wickra C ABI. +type YoyoExit struct { + handle *C.struct_YoyoExit +} + +// NewYoyoExit constructs a YoyoExit. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewYoyoExit(atrPeriod int, multiplier float64) (*YoyoExit, error) { + ptr := C.wickra_yoyo_exit_new(C.uintptr_t(atrPeriod), C.double(multiplier)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &YoyoExit{handle: ptr} + runtime.SetFinalizer(obj, (*YoyoExit).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *YoyoExit) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) float64 { + r := float64(C.wickra_yoyo_exit_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *YoyoExit) Batch(open []float64, high []float64, low []float64, close []float64, volume []float64, timestamp []int64) []float64 { + n := len(open) + if len(high) != n { + panic("wickra: all input slices must have the same length") + } + if len(low) != n { + panic("wickra: all input slices must have the same length") + } + if len(close) != n { + panic("wickra: all input slices must have the same length") + } + if len(volume) != n { + panic("wickra: all input slices must have the same length") + } + if len(timestamp) != n { + panic("wickra: all input slices must have the same length") + } + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_yoyo_exit_batch(ind.handle, (*C.double)(unsafe.Pointer(&open[0])), (*C.double)(unsafe.Pointer(&high[0])), (*C.double)(unsafe.Pointer(&low[0])), (*C.double)(unsafe.Pointer(&close[0])), (*C.double)(unsafe.Pointer(&volume[0])), (*C.int64_t)(unsafe.Pointer(×tamp[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(open) + runtime.KeepAlive(high) + runtime.KeepAlive(low) + runtime.KeepAlive(close) + runtime.KeepAlive(volume) + runtime.KeepAlive(timestamp) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *YoyoExit) Reset() { + C.wickra_yoyo_exit_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *YoyoExit) Close() { + if ind.handle != nil { + C.wickra_yoyo_exit_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ZScore wraps the ZScore indicator over the Wickra C ABI. +type ZScore struct { + handle *C.struct_ZScore +} + +// NewZScore constructs a ZScore. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewZScore(period int) (*ZScore, error) { + ptr := C.wickra_z_score_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ZScore{handle: ptr} + runtime.SetFinalizer(obj, (*ZScore).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *ZScore) Update(value float64) float64 { + r := float64(C.wickra_z_score_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *ZScore) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_z_score_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ZScore) Reset() { + C.wickra_z_score_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ZScore) Close() { + if ind.handle != nil { + C.wickra_z_score_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ZeroLagMacd wraps the ZeroLagMacd indicator over the Wickra C ABI. +type ZeroLagMacd struct { + handle *C.struct_ZeroLagMacd +} + +// NewZeroLagMacd constructs a ZeroLagMacd. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewZeroLagMacd(fast int, slow int, signal int) (*ZeroLagMacd, error) { + ptr := C.wickra_zero_lag_macd_new(C.uintptr_t(fast), C.uintptr_t(slow), C.uintptr_t(signal)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ZeroLagMacd{handle: ptr} + runtime.SetFinalizer(obj, (*ZeroLagMacd).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ZeroLagMacd) Update(value float64) (ZeroLagMacdOutput, bool) { + var out C.struct_WickraZeroLagMacdOutput + ok := bool(C.wickra_zero_lag_macd_update(ind.handle, C.double(value), &out)) + runtime.KeepAlive(ind) + if !ok { + return ZeroLagMacdOutput{}, false + } + return ZeroLagMacdOutput{float64(out.macd), float64(out.signal), float64(out.histogram)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ZeroLagMacd) Reset() { + C.wickra_zero_lag_macd_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ZeroLagMacd) Close() { + if ind.handle != nil { + C.wickra_zero_lag_macd_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// ZigZag wraps the ZigZag indicator over the Wickra C ABI. +type ZigZag struct { + handle *C.struct_ZigZag +} + +// NewZigZag constructs a ZigZag. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewZigZag(threshold float64) (*ZigZag, error) { + ptr := C.wickra_zig_zag_new(C.double(threshold)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &ZigZag{handle: ptr} + runtime.SetFinalizer(obj, (*ZigZag).Close) + return obj, nil +} + +// Update feeds one observation. The bool reports whether a value is +// available yet (false during warmup). +func (ind *ZigZag) Update(open float64, high float64, low float64, close float64, volume float64, timestamp int64) (ZigZagOutput, bool) { + var out C.struct_WickraZigZagOutput + ok := bool(C.wickra_zig_zag_update(ind.handle, C.double(open), C.double(high), C.double(low), C.double(close), C.double(volume), C.int64_t(timestamp), &out)) + runtime.KeepAlive(ind) + if !ok { + return ZigZagOutput{}, false + } + return ZigZagOutput{float64(out.swing), float64(out.direction)}, true +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *ZigZag) Reset() { + C.wickra_zig_zag_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *ZigZag) Close() { + if ind.handle != nil { + C.wickra_zig_zag_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} + +// Zlema wraps the Zlema indicator over the Wickra C ABI. +type Zlema struct { + handle *C.struct_Zlema +} + +// NewZlema constructs a Zlema. It returns ErrInvalidParams when the +// native constructor rejects the arguments. +func NewZlema(period int) (*Zlema, error) { + ptr := C.wickra_zlema_new(C.uintptr_t(period)) + if ptr == nil { + return nil, ErrInvalidParams + } + obj := &Zlema{handle: ptr} + runtime.SetFinalizer(obj, (*Zlema).Close) + return obj, nil +} + +// Update feeds one observation and returns the indicator value +// (NaN until warmed up). +func (ind *Zlema) Update(value float64) float64 { + r := float64(C.wickra_zlema_update(ind.handle, C.double(value))) + runtime.KeepAlive(ind) + return r +} + +// Batch runs the indicator over a whole slice in one FFI call and +// returns the per-element output (NaN during warmup). +func (ind *Zlema) Batch(input []float64) []float64 { + n := len(input) + out := make([]float64, n) + if n == 0 { + return out + } + C.wickra_zlema_batch(ind.handle, (*C.double)(unsafe.Pointer(&input[0])), (*C.double)(unsafe.Pointer(&out[0])), C.uintptr_t(n)) + runtime.KeepAlive(ind) + runtime.KeepAlive(input) + return out +} + +// Reset clears all internal state, returning the indicator to warmup. +func (ind *Zlema) Reset() { + C.wickra_zlema_reset(ind.handle) + runtime.KeepAlive(ind) +} + +// Close frees the native handle. It is idempotent and safe to call +// alongside the finalizer. +func (ind *Zlema) Close() { + if ind.handle != nil { + C.wickra_zlema_free(ind.handle) + ind.handle = nil + runtime.SetFinalizer(ind, nil) + } +} diff --git a/bindings/go/lib/.gitignore b/bindings/go/lib/.gitignore new file mode 100644 index 00000000..bea6b417 --- /dev/null +++ b/bindings/go/lib/.gitignore @@ -0,0 +1,7 @@ +# Prebuilt Wickra C ABI libraries are provisioned locally / in CI, not committed. +*.so +*.dylib +*.dll +*.a +*.lib +*.exp diff --git a/bindings/go/wickra.go b/bindings/go/wickra.go new file mode 100644 index 00000000..625bfc40 --- /dev/null +++ b/bindings/go/wickra.go @@ -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 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 constructor when the native +// constructor rejects the supplied parameters (for example a zero period). +var ErrInvalidParams = errors.New("wickra: invalid indicator parameters") diff --git a/bindings/go/wickra_test.go b/bindings/go/wickra_test.go new file mode 100644 index 00000000..54f13855 --- /dev/null +++ b/bindings/go/wickra_test.go @@ -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 +} diff --git a/bindings/node/README.md b/bindings/node/README.md index 6a4c9bea..8a61bcd1 100644 --- a/bindings/node/README.md +++ b/bindings/node/README.md @@ -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++, C# and any +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 Node.js binding (napi-rs); diff --git a/bindings/python/README.md b/bindings/python/README.md index 51586e82..447a9c57 100644 --- a/bindings/python/README.md +++ b/bindings/python/README.md @@ -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++, C# and any +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 Python binding (PyO3); it diff --git a/bindings/wasm/README.md b/bindings/wasm/README.md index 75b3fadd..cdd1c484 100644 --- a/bindings/wasm/README.md +++ b/bindings/wasm/README.md @@ -9,7 +9,7 @@ wickra-wasm` — pure WebAssembly, runs anywhere a modern JS engine does.** 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# and any +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 dashboards and historical backtests share the exact same implementation. This package is the WebAssembly binding diff --git a/docs/README.md b/docs/README.md index 08e6d956..908368a6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,8 +8,9 @@ That includes: [Python](https://docs.wickra.org/Quickstart-Python), [Node](https://docs.wickra.org/Quickstart-Node), [WASM](https://docs.wickra.org/Quickstart-WASM), - [C](https://docs.wickra.org/Quickstart-C), and - [C#](https://docs.wickra.org/Quickstart-CSharp). + [C](https://docs.wickra.org/Quickstart-C), + [C#](https://docs.wickra.org/Quickstart-CSharp), and + [Go](https://docs.wickra.org/Quickstart-Go). - A per-indicator deep dive for every one of the **514 indicators** across the sixteen families (Moving Averages, Momentum Oscillators, Trend & Directional, Price Oscillators, Volatility & Bands, Bands & Channels, diff --git a/examples/README.md b/examples/README.md index bdffc81b..8f52547e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -69,6 +69,28 @@ The offline examples run on deterministic synthetic data (and under CI on all three OSes); `fetch_btcusdt` and `live_binance` reach the network and are built but not run in CI. +## Go — `examples/go/` + +Build the C ABI library first (`cargo build -p wickra-c --release`) and stage it +under `bindings/go/lib/` (see the [Go binding README](../bindings/go)), then run +any example from the `examples/go` module. + +| Example | What it does | Run | +| --- | --- | --- | +| `streaming` | Feed a synthetic price series through SMA / EMA / RSI / MACD tick by tick. | `go run ./streaming` | +| `backtest` | Basket of indicators over an OHLCV series (CSV arg or synthetic). | `go run ./backtest ` | +| `multi_timeframe` | Resample a 1-minute series to 5m / 15m and print an indicator per timeframe. | `go run ./multi_timeframe` | +| `parallel_assets` | SMA(20) batch over a panel, serial vs goroutine fan-out, with speedup. | `go run ./parallel_assets 200 5000` | +| `strategy_rsi_mean_reversion` | RSI(14) mean-reversion with PnL / Sharpe / max-DD summary. | `go run ./strategy_rsi_mean_reversion` | +| `strategy_macd_adx` | Trend-follower: MACD crossover entries gated by ADX(14) > 20. | `go run ./strategy_macd_adx` | +| `strategy_bollinger_squeeze` | Bollinger-squeeze breakout with an ATR(14) trailing stop. | `go run ./strategy_bollinger_squeeze` | +| `fetch_btcusdt` | Download real BTCUSDT klines from the Binance REST API into a CSV. | `go run ./fetch_btcusdt` | +| `live_binance` | Stream live Binance klines through EMA(20) over a WebSocket. | `go run ./live_binance` | + +The offline examples run on deterministic synthetic data (and under CI on all +three OSes); `fetch_btcusdt` and `live_binance` reach the network and are built +but not run in CI. + ## Python — `examples/python/` | Example | What it does | Run | diff --git a/examples/go/.gitignore b/examples/go/.gitignore new file mode 100644 index 00000000..f42884dd --- /dev/null +++ b/examples/go/.gitignore @@ -0,0 +1,14 @@ +# Data fetched at runtime by fetch_btcusdt +**/data/ + +# Compiled example binaries +/streaming/streaming +/backtest/backtest +/multi_timeframe/multi_timeframe +/parallel_assets/parallel_assets +/strategy_rsi_mean_reversion/strategy_rsi_mean_reversion +/strategy_macd_adx/strategy_macd_adx +/strategy_bollinger_squeeze/strategy_bollinger_squeeze +/fetch_btcusdt/fetch_btcusdt +/live_binance/live_binance +*.exe diff --git a/examples/go/README.md b/examples/go/README.md new file mode 100644 index 00000000..8afa0aa9 --- /dev/null +++ b/examples/go/README.md @@ -0,0 +1,38 @@ +# Wickra examples — Go + +Runnable Go examples for the [Wickra Go binding](../../bindings/go). Each example +is a small `main` program in its own directory; they share the deterministic +synthetic data, CSV loader, and equity summary in +[`internal/market`](internal/market). + +The binding links against the prebuilt Wickra C ABI library, so build and stage +it once before running anything: + +```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 put it on PATH) +``` + +Then run any example from the `examples/go` module: + +```bash +cd examples/go +go run ./streaming +``` + +| Example | What it does | Run | +| --- | --- | --- | +| `streaming` | Feed a synthetic price series through SMA / EMA / RSI / MACD tick by tick. | `go run ./streaming` | +| `backtest` | Compute a basket of indicators over an OHLCV series and print a summary. | `go run ./backtest ` | +| `multi_timeframe` | Resample a 1-minute series into 5m / 15m and print an indicator per timeframe. | `go run ./multi_timeframe` | +| `parallel_assets` | SMA(20) batch over a panel of assets, serial vs goroutine fan-out, with speedup. | `go run ./parallel_assets 200 5000` | +| `strategy_rsi_mean_reversion` | RSI(14) mean-reversion with a PnL / Sharpe / max-DD summary. | `go run ./strategy_rsi_mean_reversion` | +| `strategy_macd_adx` | MACD crossover entries gated by ADX(14) > 20. | `go run ./strategy_macd_adx` | +| `strategy_bollinger_squeeze` | Bollinger-squeeze breakout with an ATR(14) trailing stop. | `go run ./strategy_bollinger_squeeze` | +| `fetch_btcusdt` | Download real BTCUSDT klines from the Binance REST API into a CSV. | `go run ./fetch_btcusdt` | +| `live_binance` | Stream live Binance klines through EMA(20) over a WebSocket. | `go run ./live_binance` | + +`fetch_btcusdt` and `live_binance` require network access; the rest run offline +on deterministic synthetic data. diff --git a/examples/go/backtest/main.go b/examples/go/backtest/main.go new file mode 100644 index 00000000..dbf99212 --- /dev/null +++ b/examples/go/backtest/main.go @@ -0,0 +1,56 @@ +// Compute a basket of indicators over an OHLCV series and print a summary. +// Pass a CSV path (timestamp,open,high,low,close,volume) or run on synthetic data. +package main + +import ( + "fmt" + "log" + "math" + "os" + + wickra "github.com/wickra-lib/wickra/bindings/go" + "github.com/wickra-lib/wickra/examples/go/internal/market" +) + +func main() { + source := "synthetic" + var bars []market.Bar + if len(os.Args) > 1 { + source = os.Args[1] + loaded, err := market.LoadOhlcvCsv(os.Args[1]) + if err != nil { + log.Fatalf("load csv: %v", err) + } + bars = loaded + } else { + bars = market.SyntheticCandles(1000) + } + + fmt.Printf("Backtest over %d bars (%s):\n", len(bars), source) + + sma, _ := wickra.NewSma(20) + defer sma.Close() + ema, _ := wickra.NewEma(50) + defer ema.Close() + rsi, _ := wickra.NewRsi(14) + defer rsi.Close() + atr, _ := wickra.NewAtr(14) + defer atr.Close() + + var lastSma, lastEma, lastRsi, lastAtr float64 + oversold := 0 + for _, b := range bars { + lastSma = sma.Update(b.Close) + lastEma = ema.Update(b.Close) + lastRsi = rsi.Update(b.Close) + lastAtr = atr.Update(b.Open, b.High, b.Low, b.Close, b.Volume, b.Timestamp) + if !math.IsNaN(lastRsi) && lastRsi < 30.0 { + oversold++ + } + } + + fmt.Printf(" SMA(20) last = %.4f\n", lastSma) + fmt.Printf(" EMA(50) last = %.4f\n", lastEma) + fmt.Printf(" RSI(14) last = %.4f (%d oversold bars)\n", lastRsi, oversold) + fmt.Printf(" ATR(14) last = %.4f\n", lastAtr) +} diff --git a/examples/go/fetch_btcusdt/main.go b/examples/go/fetch_btcusdt/main.go new file mode 100644 index 00000000..8276be82 --- /dev/null +++ b/examples/go/fetch_btcusdt/main.go @@ -0,0 +1,58 @@ +// Download real BTCUSDT hourly klines from the Binance REST API into a CSV that the +// other examples can consume. Requires network access (build-only in CI). +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" +) + +func main() { + const url = "https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1h&limit=500" + fmt.Printf("Fetching %s\n", url) + + resp, err := http.Get(url) + if err != nil { + log.Fatalf("request: %v", err) + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Fatalf("read body: %v", err) + } + + // Binance kline array: [openTime, open, high, low, close, volume, ...]. + var klines [][]any + if err := json.Unmarshal(body, &klines); err != nil { + log.Fatalf("parse json: %v", err) + } + + dir := "data" + if err := os.MkdirAll(dir, 0o755); err != nil { + log.Fatalf("mkdir: %v", err) + } + path := filepath.Join(dir, "btcusdt_1h.csv") + file, err := os.Create(path) + if err != nil { + log.Fatalf("create: %v", err) + } + defer file.Close() + + writer := bufio.NewWriter(file) + defer writer.Flush() + fmt.Fprintln(writer, "timestamp,open,high,low,close,volume") + count := 0 + for _, k := range klines { + ts := int64(k[0].(float64)) + fmt.Fprintf(writer, "%d,%s,%s,%s,%s,%s\n", ts, k[1], k[2], k[3], k[4], k[5]) + count++ + } + + fmt.Printf("Wrote %d klines to %s\n", count, path) +} diff --git a/examples/go/go.mod b/examples/go/go.mod new file mode 100644 index 00000000..85d41ca1 --- /dev/null +++ b/examples/go/go.mod @@ -0,0 +1,9 @@ +module github.com/wickra-lib/wickra/examples/go + +go 1.23 + +require github.com/wickra-lib/wickra/bindings/go v0.0.0 + +require github.com/coder/websocket v1.8.14 + +replace github.com/wickra-lib/wickra/bindings/go => ../../bindings/go diff --git a/examples/go/go.sum b/examples/go/go.sum new file mode 100644 index 00000000..c80e2f07 --- /dev/null +++ b/examples/go/go.sum @@ -0,0 +1,2 @@ +github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= +github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= diff --git a/examples/go/internal/market/market.go b/examples/go/internal/market/market.go new file mode 100644 index 00000000..3bb66a5a --- /dev/null +++ b/examples/go/internal/market/market.go @@ -0,0 +1,156 @@ +// Package market provides deterministic synthetic market data, a small OHLCV +// CSV loader, and an equity-curve summary shared by the offline Go examples so +// they run without network access. It mirrors the helpers used by the Python, +// C, and C# example suites. +package market + +import ( + "bufio" + "fmt" + "math" + "os" + "strconv" + "strings" +) + +// Bar is one OHLCV bar with a millisecond timestamp. +type Bar struct { + Open float64 + High float64 + Low float64 + Close float64 + Volume float64 + Timestamp int64 +} + +// SyntheticPrices returns a reproducible price path (trend + two cycles), with +// no randomness, starting at 100. +func SyntheticPrices(count int) []float64 { + return SyntheticPricesFrom(count, 100.0) +} + +// SyntheticPricesFrom is SyntheticPrices with an explicit starting level. +func SyntheticPricesFrom(count int, start float64) []float64 { + prices := make([]float64, count) + for i := range prices { + fi := float64(i) + prices[i] = start + 12.0*math.Sin(fi*0.05) + 5.0*math.Sin(fi*0.013) + fi*0.01 + } + return prices +} + +// SyntheticCandles returns a reproducible OHLCV series derived from +// SyntheticPrices, one bar per hour. +func SyntheticCandles(count int) []Bar { + return SyntheticCandlesStep(count, 0, 3_600_000) +} + +// SyntheticCandlesStep is SyntheticCandles with an explicit start timestamp and +// per-bar step in milliseconds. +func SyntheticCandlesStep(count int, startTimestamp, stepMs int64) []Bar { + prices := SyntheticPrices(count + 1) + bars := make([]Bar, count) + for i := 0; i < count; i++ { + fi := float64(i) + op := prices[i] + cl := prices[i+1] + high := math.Max(op, cl) + 0.5 + math.Abs(math.Sin(fi*0.7)) + low := math.Min(op, cl) - 0.5 - math.Abs(math.Cos(fi*0.7)) + volume := 1000.0 + 500.0*(1.0+math.Sin(fi*0.1)) + bars[i] = Bar{op, high, low, cl, volume, startTimestamp + int64(i)*stepMs} + } + return bars +} + +// LoadOhlcvCsv loads an OHLCV CSV. It accepts rows of +// timestamp,open,high,low,close,volume or open,high,low,close,volume; a +// non-numeric first row is treated as a header and skipped. +func LoadOhlcvCsv(path string) ([]Bar, error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + + var bars []Bar + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" { + continue + } + cols := strings.Split(line, ",") + if _, err := strconv.ParseFloat(cols[0], 64); err != nil { + continue // header row + } + f := func(i int) float64 { + v, _ := strconv.ParseFloat(strings.TrimSpace(cols[i]), 64) + return v + } + if len(cols) >= 6 { + ts, _ := strconv.ParseInt(strings.TrimSpace(cols[0]), 10, 64) + bars = append(bars, Bar{f(1), f(2), f(3), f(4), f(5), ts}) + } else { + bars = append(bars, Bar{f(0), f(1), f(2), f(3), f(4), int64(len(bars))}) + } + } + return bars, scanner.Err() +} + +// EquityResult holds summary statistics for a long-only equity curve. +type EquityResult struct { + TotalReturnPct float64 + Sharpe float64 + MaxDrawdownPct float64 + Trades int + FinalEquity float64 +} + +// Summarize turns a stream of per-bar fractional returns (0.01 == +1%) into a +// PnL / Sharpe / max-drawdown summary, annualised by periodsPerYear. +func Summarize(periodReturns []float64, trades int, periodsPerYear float64) EquityResult { + equity, peak, maxDrawdown := 1.0, 1.0, 0.0 + for _, r := range periodReturns { + equity *= 1.0 + r + peak = math.Max(peak, equity) + if peak > 0 { + maxDrawdown = math.Max(maxDrawdown, (peak-equity)/peak) + } + } + + mean := 0.0 + if len(periodReturns) > 0 { + var sum float64 + for _, r := range periodReturns { + sum += r + } + mean = sum / float64(len(periodReturns)) + } + variance := 0.0 + if len(periodReturns) > 1 { + var ss float64 + for _, r := range periodReturns { + ss += (r - mean) * (r - mean) + } + variance = ss / float64(len(periodReturns)-1) + } + stdDev := math.Sqrt(variance) + sharpe := 0.0 + if stdDev > 1e-12 { + sharpe = mean / stdDev * math.Sqrt(periodsPerYear) + } + + return EquityResult{ + TotalReturnPct: (equity - 1.0) * 100.0, + Sharpe: sharpe, + MaxDrawdownPct: maxDrawdown * 100.0, + Trades: trades, + FinalEquity: equity, + } +} + +// Print writes a one-line summary of an equity result. +func Print(name string, r EquityResult) { + fmt.Printf("%-26s return=%8.2f%% sharpe=%6.2f maxDD=%6.2f%% trades=%d\n", + name, r.TotalReturnPct, r.Sharpe, r.MaxDrawdownPct, r.Trades) +} diff --git a/examples/go/live_binance/main.go b/examples/go/live_binance/main.go new file mode 100644 index 00000000..030cd589 --- /dev/null +++ b/examples/go/live_binance/main.go @@ -0,0 +1,54 @@ +// Stream live BTCUSDT 1-minute klines from Binance and feed each close through EMA(20). +// Requires network access (build-only in CI). Runs for up to 60 seconds. +package main + +import ( + "context" + "encoding/json" + "fmt" + "log" + "strconv" + "time" + + "github.com/coder/websocket" + wickra "github.com/wickra-lib/wickra/bindings/go" +) + +func main() { + const url = "wss://stream.binance.com:9443/ws/btcusdt@kline_1m" + fmt.Printf("Connecting to %s (up to 60s)...\n", url) + + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + conn, _, err := websocket.Dial(ctx, url, nil) + if err != nil { + log.Fatalf("dial: %v", err) + } + defer conn.CloseNow() + + ema, _ := wickra.NewEma(20) + defer ema.Close() + + for { + _, data, err := conn.Read(ctx) + if err != nil { + fmt.Println("Done (time limit reached).") + return + } + + var msg struct { + K struct { + Close string `json:"c"` + } `json:"k"` + } + if err := json.Unmarshal(data, &msg); err != nil || msg.K.Close == "" { + continue + } + closePx, err := strconv.ParseFloat(msg.K.Close, 64) + if err != nil { + continue + } + fmt.Printf("close=%.2f EMA(20)=%.2f\n", closePx, ema.Update(closePx)) + } +} diff --git a/examples/go/multi_timeframe/main.go b/examples/go/multi_timeframe/main.go new file mode 100644 index 00000000..e2413075 --- /dev/null +++ b/examples/go/multi_timeframe/main.go @@ -0,0 +1,54 @@ +// Resample a 1-minute series into higher timeframes and run an indicator per timeframe. +package main + +import ( + "fmt" + "math" + + wickra "github.com/wickra-lib/wickra/bindings/go" + "github.com/wickra-lib/wickra/examples/go/internal/market" +) + +func main() { + oneMinute := market.SyntheticCandlesStep(1200, 0, 60_000) + + fmt.Println("EMA(20) of close across timeframes (resampled from 1-minute bars):") + for _, factor := range []int{1, 5, 15} { + bars := resample(oneMinute, factor) + ema, _ := wickra.NewEma(20) + var last float64 + for _, b := range bars { + last = ema.Update(b.Close) + } + ema.Close() + fmt.Printf(" %2dm: %5d bars EMA(20) last = %.4f\n", factor, len(bars), last) + } +} + +func resample(source []market.Bar, factor int) []market.Bar { + if factor <= 1 { + return source + } + var out []market.Bar + for i := 0; i < len(source); i += factor { + end := i + factor + if end > len(source) { + end = len(source) + } + high, low, volume := math.Inf(-1), math.Inf(1), 0.0 + for j := i; j < end; j++ { + high = math.Max(high, source[j].High) + low = math.Min(low, source[j].Low) + volume += source[j].Volume + } + out = append(out, market.Bar{ + Open: source[i].Open, + High: high, + Low: low, + Close: source[end-1].Close, + Volume: volume, + Timestamp: source[i].Timestamp, + }) + } + return out +} diff --git a/examples/go/parallel_assets/main.go b/examples/go/parallel_assets/main.go new file mode 100644 index 00000000..3fd4f907 --- /dev/null +++ b/examples/go/parallel_assets/main.go @@ -0,0 +1,80 @@ +// Run SMA(20) batch over a panel of assets, serial vs goroutine fan-out, and +// report the speedup. +package main + +import ( + "fmt" + "os" + "runtime" + "strconv" + "sync" + "time" + + wickra "github.com/wickra-lib/wickra/bindings/go" + "github.com/wickra-lib/wickra/examples/go/internal/market" +) + +func main() { + assets := argInt(1, 500) + bars := argInt(2, 20_000) + + panel := make([][]float64, assets) + for a := 0; a < assets; a++ { + panel[a] = market.SyntheticPricesFrom(bars, 50.0+float64(a)*0.1) + } + + // Warm up so the comparison is fair. + if warm, err := wickra.NewSma(20); err == nil { + warm.Batch(panel[0]) + warm.Close() + } + + sink := 0.0 + start := time.Now() + for a := 0; a < assets; a++ { + sma, _ := wickra.NewSma(20) + result := sma.Batch(panel[a]) + sma.Close() + sink += result[len(result)-1] + } + serial := time.Since(start) + + lasts := make([]float64, assets) + start = time.Now() + var wg sync.WaitGroup + work := make(chan int, assets) + for w := 0; w < runtime.GOMAXPROCS(0); w++ { + wg.Add(1) + go func() { + defer wg.Done() + for a := range work { + sma, _ := wickra.NewSma(20) + result := sma.Batch(panel[a]) + sma.Close() + lasts[a] = result[len(result)-1] + } + }() + } + for a := 0; a < assets; a++ { + work <- a + } + close(work) + wg.Wait() + parallel := time.Since(start) + + serialMs := float64(serial.Microseconds()) / 1000.0 + parallelMs := float64(parallel.Microseconds()) / 1000.0 + fmt.Printf("%d assets x %d bars, SMA(20) batch:\n", assets, bars) + fmt.Printf(" serial %8.1f ms\n", serialMs) + fmt.Printf(" parallel %8.1f ms (%.1fx speedup)\n", parallelMs, serialMs/max(parallelMs, 1e-9)) + _ = sink +} + +func argInt(i, def int) int { + if len(os.Args) > i { + if v, err := strconv.Atoi(os.Args[i]); err == nil { + return v + } + } + return def +} diff --git a/examples/go/strategy_bollinger_squeeze/main.go b/examples/go/strategy_bollinger_squeeze/main.go new file mode 100644 index 00000000..f5b82990 --- /dev/null +++ b/examples/go/strategy_bollinger_squeeze/main.go @@ -0,0 +1,66 @@ +// Breakout: when Bollinger bandwidth is tight (a "squeeze") and price closes above +// the upper band, go long with an ATR(14) trailing stop. +package main + +import ( + "log" + "math" + "os" + + wickra "github.com/wickra-lib/wickra/bindings/go" + "github.com/wickra-lib/wickra/examples/go/internal/market" +) + +func main() { + bars := loadBars() + + bollinger, _ := wickra.NewBollingerBands(20, 2.0) + defer bollinger.Close() + atr, _ := wickra.NewAtr(14) + defer atr.Close() + + var returns []float64 + trades := 0 + inPosition := false + entry := 0.0 + stop := 0.0 + + for _, b := range bars { + band, okBand := bollinger.Update(b.Close) + atrValue := atr.Update(b.Open, b.High, b.Low, b.Close, b.Volume, b.Timestamp) + if !okBand || math.IsNaN(atrValue) { + continue + } + + bandwidth := math.MaxFloat64 + if band.Middle != 0.0 { + bandwidth = (band.Upper - band.Lower) / band.Middle + } + + if !inPosition && bandwidth < 0.06 && b.Close > band.Upper { + inPosition = true + entry = b.Close + stop = b.Close - 2.0*atrValue + trades++ + } else if inPosition { + stop = math.Max(stop, b.Close-2.0*atrValue) // trail the stop up + if b.Close < stop { + returns = append(returns, (b.Close-entry)/entry) + inPosition = false + } + } + } + + market.Print("Bollinger squeeze", market.Summarize(returns, trades, 252.0)) +} + +func loadBars() []market.Bar { + if len(os.Args) > 1 { + bars, err := market.LoadOhlcvCsv(os.Args[1]) + if err != nil { + log.Fatalf("load csv: %v", err) + } + return bars + } + return market.SyntheticCandles(2000) +} diff --git a/examples/go/strategy_macd_adx/main.go b/examples/go/strategy_macd_adx/main.go new file mode 100644 index 00000000..a98cd418 --- /dev/null +++ b/examples/go/strategy_macd_adx/main.go @@ -0,0 +1,59 @@ +// Trend follower: enter long on a MACD histogram cross up, but only when ADX(14) > 20 +// confirms a trend; exit when the histogram crosses back below zero. +package main + +import ( + "log" + "math" + "os" + + wickra "github.com/wickra-lib/wickra/bindings/go" + "github.com/wickra-lib/wickra/examples/go/internal/market" +) + +func main() { + bars := loadBars() + + macd, _ := wickra.NewMacdIndicator(12, 26, 9) + defer macd.Close() + adx, _ := wickra.NewAdx(14) + defer adx.Close() + + var returns []float64 + trades := 0 + inPosition := false + entry := 0.0 + prevHistogram := math.NaN() + + for _, b := range bars { + m, okMacd := macd.Update(b.Close) + a, okAdx := adx.Update(b.Open, b.High, b.Low, b.Close, b.Volume, b.Timestamp) + if !okMacd || !okAdx { + continue + } + + trending := a.Adx > 20.0 + if !inPosition && trending && !math.IsNaN(prevHistogram) && prevHistogram <= 0.0 && m.Histogram > 0.0 { + inPosition = true + entry = b.Close + trades++ + } else if inPosition && m.Histogram < 0.0 { + returns = append(returns, (b.Close-entry)/entry) + inPosition = false + } + prevHistogram = m.Histogram + } + + market.Print("MACD + ADX trend", market.Summarize(returns, trades, 252.0)) +} + +func loadBars() []market.Bar { + if len(os.Args) > 1 { + bars, err := market.LoadOhlcvCsv(os.Args[1]) + if err != nil { + log.Fatalf("load csv: %v", err) + } + return bars + } + return market.SyntheticCandles(2000) +} diff --git a/examples/go/strategy_rsi_mean_reversion/main.go b/examples/go/strategy_rsi_mean_reversion/main.go new file mode 100644 index 00000000..3a02943a --- /dev/null +++ b/examples/go/strategy_rsi_mean_reversion/main.go @@ -0,0 +1,51 @@ +// Mean reversion: go long when RSI(14) drops below 30, exit when it recovers above 50. +package main + +import ( + "log" + "math" + "os" + + wickra "github.com/wickra-lib/wickra/bindings/go" + "github.com/wickra-lib/wickra/examples/go/internal/market" +) + +func main() { + bars := loadBars() + + rsi, _ := wickra.NewRsi(14) + defer rsi.Close() + + var returns []float64 + trades := 0 + inPosition := false + entry := 0.0 + + for _, b := range bars { + value := rsi.Update(b.Close) + if math.IsNaN(value) { + continue + } + if !inPosition && value < 30.0 { + inPosition = true + entry = b.Close + trades++ + } else if inPosition && value > 50.0 { + returns = append(returns, (b.Close-entry)/entry) + inPosition = false + } + } + + market.Print("RSI mean-reversion", market.Summarize(returns, trades, 252.0)) +} + +func loadBars() []market.Bar { + if len(os.Args) > 1 { + bars, err := market.LoadOhlcvCsv(os.Args[1]) + if err != nil { + log.Fatalf("load csv: %v", err) + } + return bars + } + return market.SyntheticCandles(2000) +} diff --git a/examples/go/streaming/main.go b/examples/go/streaming/main.go new file mode 100644 index 00000000..a14fda32 --- /dev/null +++ b/examples/go/streaming/main.go @@ -0,0 +1,40 @@ +// Feed a synthetic price series through several indicators tick by tick (O(1) each). +package main + +import ( + "fmt" + + wickra "github.com/wickra-lib/wickra/bindings/go" + "github.com/wickra-lib/wickra/examples/go/internal/market" +) + +func main() { + prices := market.SyntheticPrices(500) + + sma, _ := wickra.NewSma(20) + defer sma.Close() + ema, _ := wickra.NewEma(20) + defer ema.Close() + rsi, _ := wickra.NewRsi(14) + defer rsi.Close() + macd, _ := wickra.NewMacdIndicator(12, 26, 9) + defer macd.Close() + + var lastSma, lastEma, lastRsi float64 + var lastMacd wickra.MacdOutput + var haveMacd bool + for _, price := range prices { + lastSma = sma.Update(price) + lastEma = ema.Update(price) + lastRsi = rsi.Update(price) + lastMacd, haveMacd = macd.Update(price) + } + + fmt.Printf("Streamed %d prices through SMA(20), EMA(20), RSI(14), MACD(12,26,9):\n", len(prices)) + fmt.Printf(" SMA = %.4f\n", lastSma) + fmt.Printf(" EMA = %.4f\n", lastEma) + fmt.Printf(" RSI = %.4f\n", lastRsi) + if haveMacd { + fmt.Printf(" MACD = %.4f signal=%.4f hist=%.4f\n", lastMacd.Macd, lastMacd.Signal, lastMacd.Histogram) + } +}