wickra-wasm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,270 @@
1
+ # Wickra
2
+
3
+ [![CI](https://github.com/kingchenc/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/kingchenc/wickra/actions/workflows/ci.yml)
4
+ [![crates.io](https://img.shields.io/crates/v/wickra.svg?logo=rust&color=orange)](https://crates.io/crates/wickra)
5
+ [![PyPI](https://img.shields.io/pypi/v/wickra.svg?logo=pypi&color=blue)](https://pypi.org/project/wickra/)
6
+ [![npm](https://img.shields.io/npm/v/wickra.svg?logo=npm&color=red)](https://www.npmjs.com/package/wickra)
7
+ [![License: PolyForm-NC](https://img.shields.io/badge/license-PolyForm--NC--1.0.0-purple)](LICENSE)
8
+
9
+ **Streaming-first technical indicators. Install with `pip install wickra` — no system dependencies.**
10
+
11
+ Wickra is a multi-language technical-analysis library with a Rust core and
12
+ bindings for Python, Node.js, and WebAssembly. Every indicator is a state
13
+ machine that updates in O(1) per new data point, so live trading bots and
14
+ historical backtests share the exact same implementation.
15
+
16
+ ```python
17
+ import numpy as np
18
+ import wickra as ta
19
+
20
+ # Batch: classic TA-Lib-style usage
21
+ prices = np.linspace(100, 200, 1000)
22
+ rsi = ta.RSI(14)
23
+ values = rsi.batch(prices) # numpy array, NaN during warmup
24
+
25
+ # Streaming: same indicator, fed tick by tick
26
+ rsi = ta.RSI(14)
27
+ for price in live_feed:
28
+ value = rsi.update(price) # O(1) — no recomputation over history
29
+ if value is not None and value > 70:
30
+ print("overbought")
31
+ ```
32
+
33
+ ## Why Wickra exists
34
+
35
+ The Python TA ecosystem has plenty of libraries — TA-Lib, pandas-ta, finta,
36
+ talipp, tulipy — and every one of them shares the same blind spot:
37
+
38
+ | Library | Install pain | Streaming | Multi-language | Active |
39
+ |--------------------|-----------------|-----------|----------------|--------|
40
+ | TA-Lib (Python) | yes (C deps) | no | no | barely |
41
+ | pandas-ta | clean | no | no | slow |
42
+ | finta | clean | no | no | stale |
43
+ | ta-lib-python | yes (C deps) | no | no | barely |
44
+ | talipp | clean | yes | no | yes |
45
+ | Tulip Indicators | yes (C deps) | no | partial | stale |
46
+ | ooples (C#) | clean | no | C# only | yes |
47
+ | **Wickra** | **clean** | **yes** | **Python+Node+WASM+Rust** | **yes** |
48
+
49
+ Wickra is the only library that combines all of: clean install, streaming,
50
+ multi-language reach, and active maintenance.
51
+
52
+ ## Benchmark: how much faster is "streaming-first"?
53
+
54
+ Reproduced on this machine with `python -m benchmarks.compare_libraries`.
55
+ Lower µs/op = faster. Wickra wins every batch category outright, and the
56
+ streaming gap widens linearly with how much history a batch-only library has
57
+ to recompute on every tick.
58
+
59
+ ### Batch — single full pass over a 5 000-bar series
60
+
61
+ Reading the table: each cell shows that library's runtime, plus how many times
62
+ slower it is than Wickra in parentheses. **★** marks the winner per row.
63
+
64
+ | Indicator | Wickra | finta | talipp |
65
+ |---------------------|---------------------|------------------------|------------------------------|
66
+ | SMA(20) | **26.0 µs ★** | 295.3 µs (11.4× slower) | 1 812.8 µs (69.7× slower) |
67
+ | EMA(20) | **16.8 µs ★** | 205.5 µs (12.2× slower) | 2 534.4 µs (150.9× slower) |
68
+ | RSI(14) | **31.2 µs ★** | 714.1 µs (22.9× slower) | 3 751.7 µs (120.2× slower) |
69
+ | MACD(12, 26, 9) | **30.8 µs ★** | 359.5 µs (11.7× slower) | 11 642.2 µs (378.0× slower) |
70
+ | Bollinger(20, 2.0) | **26.7 µs ★** | 690.6 µs (25.9× slower) | 27 482.4 µs (1 030.1× slower) |
71
+ | ATR(14) | **40.6 µs ★** | 1 120.3 µs (27.6× slower) | 3 760.2 µs (92.7× slower) |
72
+
73
+ ### Streaming — per-tick latency after seeding with 2 000 historical bars
74
+
75
+ A batch-only library has to re-run its full indicator over the entire history on
76
+ every new tick; Wickra updates state in O(1).
77
+
78
+ | Indicator | Wickra (per tick) | talipp (per tick) |
79
+ |-----------|---------------------|---------------------------|
80
+ | RSI(14) | **0.07 µs ★** | 1.16 µs (17.5× slower) |
81
+
82
+ > TA-Lib and pandas-ta are not included here because both fail to install
83
+ > cleanly on Windows without C build tooling — which is precisely the install
84
+ > pain Wickra was built to remove. The benchmark script auto-detects every
85
+ > peer library it can find and runs them on the same inputs as Wickra; install
86
+ > them in your environment to see those rows light up too.
87
+
88
+ Run the suite yourself:
89
+
90
+ ```bash
91
+ pip install -e bindings/python[bench]
92
+ python -m benchmarks.compare_libraries
93
+ ```
94
+
95
+ ## Indicators in 0.1.0
96
+
97
+ 25 streaming-first indicators across four families. Every one passes the
98
+ `batch == streaming` equivalence test, reference-value tests, and reset
99
+ semantics tests.
100
+
101
+ | Family | Indicators |
102
+ |-------------|-----------|
103
+ | Trend | SMA, EMA, WMA, DEMA, TEMA, HMA, KAMA |
104
+ | Momentum | RSI (Wilder), MACD, Stochastic, CCI, ROC, Williams %R, ADX (+DI/-DI), MFI, TRIX, Awesome Oscillator, Aroon |
105
+ | Volatility | Bollinger Bands, ATR, Keltner Channels, Donchian Channels, Parabolic SAR |
106
+ | Volume | OBV, VWAP (cumulative + rolling) |
107
+
108
+ Adding a new indicator means implementing one trait in Rust; all four bindings
109
+ inherit it automatically.
110
+
111
+ ## Languages
112
+
113
+ | Binding | Install | Example |
114
+ |-------------------|-----------------------------------------------|---------|
115
+ | Python (PyO3) | `pip install wickra` | `examples/python/backtest.py` |
116
+ | Node.js (napi-rs) | `npm install wickra` | `bindings/node/__tests__/smoke.test.js` |
117
+ | Browser / WASM | `npm install wickra-wasm` | `bindings/wasm/examples/index.html` |
118
+ | Rust | `cargo add wickra` | `crates/wickra/examples/backtest.rs` |
119
+
120
+ The wickra-core crate is `unsafe`-forbidden, so every binding inherits a
121
+ memory-safe implementation.
122
+
123
+ ## Rust API
124
+
125
+ ```rust
126
+ use wickra::{Indicator, BatchExt, Chain, Ema, Rsi, Sma};
127
+
128
+ // Streaming or batch — same trait, same code.
129
+ let mut sma = Sma::new(14)?;
130
+ let out: Vec<Option<f64>> = sma.batch(&[1.0, 2.0, 3.0, 4.0, 5.0]);
131
+
132
+ let mut rsi = Rsi::new(14)?;
133
+ for price in live_feed {
134
+ if let Some(v) = rsi.update(price) {
135
+ println!("RSI = {v}");
136
+ }
137
+ }
138
+
139
+ // Compose indicators: RSI(7) on top of EMA(14).
140
+ let mut chain = Chain::new(Ema::new(14)?, Rsi::new(7)?);
141
+ chain.update(price);
142
+ ```
143
+
144
+ ## Live data sources
145
+
146
+ `wickra-data` (separate crate, opt-in) ships:
147
+
148
+ - A streaming OHLCV **CSV reader**.
149
+ - A **tick-to-candle aggregator** with arbitrary timeframes.
150
+ - A **candle resampler** for multi-timeframe analysis (1m → 5m → 1h on the fly).
151
+ - A **Binance Spot WebSocket** kline adapter (feature `live-binance`).
152
+
153
+ ```rust
154
+ use wickra::{Indicator, Rsi};
155
+ use wickra_data::live::binance::{BinanceKlineStream, Interval};
156
+
157
+ let mut stream = BinanceKlineStream::connect(&["BTCUSDT".into()], Interval::OneMinute).await?;
158
+ let mut rsi = Rsi::new(14)?;
159
+ while let Some(event) = stream.next_event().await? {
160
+ if event.is_closed {
161
+ if let Some(v) = rsi.update(event.candle.close) {
162
+ println!("RSI = {v:.2}");
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ A Python live-trading example using the public `websockets` package lives at
169
+ `examples/python/live_trading.py`.
170
+
171
+ ## Project layout
172
+
173
+ ```
174
+ wickra/
175
+ ├── crates/
176
+ │ ├── wickra-core/ core engine + all 25 indicators
177
+ │ ├── wickra/ top-level facade crate (publishes on crates.io)
178
+ │ └── wickra-data/ CSV reader, tick aggregator, live exchange feeds
179
+ ├── bindings/
180
+ │ ├── python/ PyO3 + maturin (publishes on PyPI)
181
+ │ ├── node/ napi-rs (publishes on npm)
182
+ │ └── wasm/ wasm-bindgen (browsers, bundlers, Node)
183
+ ├── examples/
184
+ │ └── python/ backtest, live trading, parallel assets, multi-tf
185
+ │ (Rust examples live inside their crate at crates/<name>/examples/)
186
+ ├── benches/ cargo bench targets
187
+ └── .github/workflows/ CI and release pipelines
188
+ ```
189
+
190
+ ## Building everything from source
191
+
192
+ ```bash
193
+ # Rust core + tests
194
+ cargo test --workspace
195
+ cargo clippy --workspace --all-targets -- -D warnings
196
+ cargo bench -p wickra
197
+
198
+ # Python binding (requires Rust toolchain + maturin)
199
+ cd bindings/python
200
+ maturin develop --release
201
+ pytest
202
+
203
+ # WASM binding (requires wasm-pack + wasm32-unknown-unknown target)
204
+ wasm-pack build bindings/wasm --target web --release --features panic-hook
205
+
206
+ # Node binding (requires @napi-rs/cli)
207
+ cd bindings/node && npm install && npm run build && npm test
208
+ ```
209
+
210
+ ## Test counts
211
+
212
+ - `wickra-core`: 171 unit tests + 2 doctests, including textbook-value tests
213
+ for Wilder RSI, Bollinger Bands, MACD, ATR, and Stochastic.
214
+ - `wickra-data`: 11 unit tests + 1 doctest, covers CSV decoding, the tick
215
+ aggregator, the resampler, and the Binance payload parser.
216
+ - `bindings/python`: 56 pytest tests covering smoke checks, streaming==batch
217
+ equivalence, reference values, lifecycle, and dict/tuple candle inputs.
218
+ - `bindings/node`: 7 Node test-runner cases via `node --test`.
219
+
220
+ ## Contributing
221
+
222
+ Contributions are very welcome — issues, bug reports, ideas, and pull requests
223
+ all land in the same place: <https://github.com/kingchenc/wickra>.
224
+
225
+ A short orientation for first-time contributors:
226
+
227
+ - **Adding an indicator.** Implement the `Indicator` trait in
228
+ `crates/wickra-core/src/indicators/<name>.rs`, wire it into
229
+ `indicators/mod.rs` and the crate root, and add reference-value tests,
230
+ a `batch == streaming` equivalence test, and (where it makes sense) a
231
+ proptest. The four bindings inherit your indicator automatically once
232
+ you expose it in the language wrappers.
233
+ - **Fixing a numeric bug.** Add a failing test that pins the textbook value
234
+ first, then fix the math. Property tests in `crates/wickra-core` catch
235
+ most regressions; please don't disable them.
236
+ - **Improving a binding.** Each binding lives under `bindings/<lang>` with
237
+ its own tests; please keep the `batch == streaming` invariant.
238
+ - **Style.** `cargo fmt --all` + `cargo clippy --workspace --all-targets -- -D warnings`
239
+ are CI gates; running them locally before pushing keeps reviews short.
240
+
241
+ For larger architectural changes, open an issue first so we can sketch the
242
+ shape together before you invest the time.
243
+
244
+ ## License
245
+
246
+ Licensed under the **PolyForm Noncommercial License 1.0.0**. See [LICENSE](LICENSE).
247
+
248
+ In plain English: use it, fork it, modify it, redistribute it, file issues, send
249
+ pull requests — all welcome. Personal projects, research, education, non-profits,
250
+ government, hobby trading bots: all fine. The one thing that's not allowed is
251
+ commercial sale of the software or of services built around it. If you want to
252
+ use Wickra commercially, get in touch about a license.
253
+
254
+ ---
255
+
256
+ <p align="center">
257
+ <a href="https://github.com/kingchenc/wickra/stargazers">
258
+ <img alt="GitHub stars" src="https://img.shields.io/github/stars/kingchenc/wickra?style=for-the-badge&logo=github&logoColor=white&color=ffd866">
259
+ </a>
260
+ <a href="https://github.com/kingchenc/wickra/network/members">
261
+ <img alt="GitHub forks" src="https://img.shields.io/github/forks/kingchenc/wickra?style=for-the-badge&logo=github&logoColor=white&color=78dce8">
262
+ </a>
263
+ <a href="https://github.com/kingchenc/wickra/issues">
264
+ <img alt="GitHub issues" src="https://img.shields.io/github/issues/kingchenc/wickra?style=for-the-badge&logo=github&logoColor=white&color=ff6188">
265
+ </a>
266
+ </p>
267
+
268
+ <p align="center">
269
+ If Wickra saved you time, the cheapest way to say thanks is to ⭐ the repo.
270
+ </p>
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "wickra-wasm",
3
+ "type": "module",
4
+ "collaborators": [
5
+ "Wickra Contributors"
6
+ ],
7
+ "description": "WASM bindings for the Wickra streaming-first technical indicators library.",
8
+ "version": "0.1.0",
9
+ "license": "SEE LICENSE IN LICENSE",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/kingchenc/wickra"
13
+ },
14
+ "files": [
15
+ "wickra_wasm_bg.wasm",
16
+ "wickra_wasm.js",
17
+ "wickra_wasm_bg.js",
18
+ "wickra_wasm.d.ts"
19
+ ],
20
+ "main": "wickra_wasm.js",
21
+ "homepage": "https://github.com/kingchenc/wickra",
22
+ "types": "wickra_wasm.d.ts",
23
+ "sideEffects": [
24
+ "./wickra_wasm.js",
25
+ "./snippets/*"
26
+ ],
27
+ "keywords": [
28
+ "finance",
29
+ "trading",
30
+ "indicators",
31
+ "technical-analysis",
32
+ "ta"
33
+ ],
34
+ "author": "kingchenc <kingchencp@gmail.com>",
35
+ "bugs": {
36
+ "url": "https://github.com/kingchenc/wickra/issues"
37
+ }
38
+ }
@@ -0,0 +1,251 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ export class ADX {
5
+ free(): void;
6
+ [Symbol.dispose](): void;
7
+ /**
8
+ * Returns `[plusDi, minusDi, adx]` × n, length `3n`.
9
+ */
10
+ batch(high: Float64Array, low: Float64Array, close: Float64Array): Float64Array;
11
+ constructor(period: number);
12
+ }
13
+
14
+ export class ATR {
15
+ free(): void;
16
+ [Symbol.dispose](): void;
17
+ batch(high: Float64Array, low: Float64Array, close: Float64Array): Float64Array;
18
+ constructor(period: number);
19
+ reset(): void;
20
+ update(high: number, low: number, close: number): number | undefined;
21
+ }
22
+
23
+ export class Aroon {
24
+ free(): void;
25
+ [Symbol.dispose](): void;
26
+ /**
27
+ * Returns `[up0, down0, up1, down1, ...]`, length `2n`.
28
+ */
29
+ batch(high: Float64Array, low: Float64Array): Float64Array;
30
+ constructor(period: number);
31
+ }
32
+
33
+ export class AwesomeOscillator {
34
+ free(): void;
35
+ [Symbol.dispose](): void;
36
+ batch(high: Float64Array, low: Float64Array): Float64Array;
37
+ constructor(fast: number, slow: number);
38
+ }
39
+
40
+ export class BollingerBands {
41
+ free(): void;
42
+ [Symbol.dispose](): void;
43
+ /**
44
+ * Returns `[u0, m0, l0, sd0, u1, m1, l1, sd1, ...]`, length `4 * n`.
45
+ */
46
+ batch(prices: Float64Array): Float64Array;
47
+ constructor(period: number, multiplier: number);
48
+ reset(): void;
49
+ update(value: number): any;
50
+ }
51
+
52
+ export class CCI {
53
+ free(): void;
54
+ [Symbol.dispose](): void;
55
+ batch(high: Float64Array, low: Float64Array, close: Float64Array): Float64Array;
56
+ constructor(period: number);
57
+ }
58
+
59
+ export class DEMA {
60
+ free(): void;
61
+ [Symbol.dispose](): void;
62
+ batch(prices: Float64Array): Float64Array;
63
+ isReady(): boolean;
64
+ constructor(period: number);
65
+ reset(): void;
66
+ update(value: number): number | undefined;
67
+ warmupPeriod(): number;
68
+ }
69
+
70
+ export class Donchian {
71
+ free(): void;
72
+ [Symbol.dispose](): void;
73
+ batch(high: Float64Array, low: Float64Array): Float64Array;
74
+ constructor(period: number);
75
+ }
76
+
77
+ export class EMA {
78
+ free(): void;
79
+ [Symbol.dispose](): void;
80
+ batch(prices: Float64Array): Float64Array;
81
+ isReady(): boolean;
82
+ constructor(period: number);
83
+ reset(): void;
84
+ update(value: number): number | undefined;
85
+ warmupPeriod(): number;
86
+ }
87
+
88
+ export class HMA {
89
+ free(): void;
90
+ [Symbol.dispose](): void;
91
+ batch(prices: Float64Array): Float64Array;
92
+ isReady(): boolean;
93
+ constructor(period: number);
94
+ reset(): void;
95
+ update(value: number): number | undefined;
96
+ warmupPeriod(): number;
97
+ }
98
+
99
+ export class KAMA {
100
+ free(): void;
101
+ [Symbol.dispose](): void;
102
+ batch(prices: Float64Array): Float64Array;
103
+ isReady(): boolean;
104
+ constructor(er_period: number, fast: number, slow: number);
105
+ reset(): void;
106
+ update(value: number): number | undefined;
107
+ }
108
+
109
+ export class Keltner {
110
+ free(): void;
111
+ [Symbol.dispose](): void;
112
+ batch(high: Float64Array, low: Float64Array, close: Float64Array): Float64Array;
113
+ constructor(ema_period: number, atr_period: number, multiplier: number);
114
+ }
115
+
116
+ export class MACD {
117
+ free(): void;
118
+ [Symbol.dispose](): void;
119
+ /**
120
+ * Returns a flat `Float64Array` of length `3 * n`: `[macd0, sig0, hist0, macd1, sig1, hist1, ...]`.
121
+ * Use `result[3*i + 0/1/2]` to read each column. Warmup positions are NaN.
122
+ */
123
+ batch(prices: Float64Array): Float64Array;
124
+ isReady(): boolean;
125
+ constructor(fast: number, slow: number, signal: number);
126
+ reset(): void;
127
+ update(value: number): any;
128
+ }
129
+
130
+ export class MFI {
131
+ free(): void;
132
+ [Symbol.dispose](): void;
133
+ batch(high: Float64Array, low: Float64Array, close: Float64Array, volume: Float64Array): Float64Array;
134
+ constructor(period: number);
135
+ }
136
+
137
+ export class OBV {
138
+ free(): void;
139
+ [Symbol.dispose](): void;
140
+ batch(close: Float64Array, volume: Float64Array): Float64Array;
141
+ constructor();
142
+ reset(): void;
143
+ }
144
+
145
+ export class PSAR {
146
+ free(): void;
147
+ [Symbol.dispose](): void;
148
+ batch(high: Float64Array, low: Float64Array, close: Float64Array): Float64Array;
149
+ constructor(af_start: number, af_step: number, af_max: number);
150
+ }
151
+
152
+ export class ROC {
153
+ free(): void;
154
+ [Symbol.dispose](): void;
155
+ batch(prices: Float64Array): Float64Array;
156
+ isReady(): boolean;
157
+ constructor(period: number);
158
+ reset(): void;
159
+ update(value: number): number | undefined;
160
+ warmupPeriod(): number;
161
+ }
162
+
163
+ export class RSI {
164
+ free(): void;
165
+ [Symbol.dispose](): void;
166
+ batch(prices: Float64Array): Float64Array;
167
+ isReady(): boolean;
168
+ constructor(period: number);
169
+ reset(): void;
170
+ update(value: number): number | undefined;
171
+ warmupPeriod(): number;
172
+ }
173
+
174
+ export class SMA {
175
+ free(): void;
176
+ [Symbol.dispose](): void;
177
+ batch(prices: Float64Array): Float64Array;
178
+ isReady(): boolean;
179
+ constructor(period: number);
180
+ reset(): void;
181
+ update(value: number): number | undefined;
182
+ warmupPeriod(): number;
183
+ }
184
+
185
+ export class Stochastic {
186
+ free(): void;
187
+ [Symbol.dispose](): void;
188
+ /**
189
+ * Returns `[k0, d0, k1, d1, ...]`, length `2 * n`.
190
+ */
191
+ batch(high: Float64Array, low: Float64Array, close: Float64Array): Float64Array;
192
+ constructor(k_period: number, d_period: number);
193
+ reset(): void;
194
+ }
195
+
196
+ export class TEMA {
197
+ free(): void;
198
+ [Symbol.dispose](): void;
199
+ batch(prices: Float64Array): Float64Array;
200
+ isReady(): boolean;
201
+ constructor(period: number);
202
+ reset(): void;
203
+ update(value: number): number | undefined;
204
+ warmupPeriod(): number;
205
+ }
206
+
207
+ export class TRIX {
208
+ free(): void;
209
+ [Symbol.dispose](): void;
210
+ batch(prices: Float64Array): Float64Array;
211
+ isReady(): boolean;
212
+ constructor(period: number);
213
+ reset(): void;
214
+ update(value: number): number | undefined;
215
+ warmupPeriod(): number;
216
+ }
217
+
218
+ export class VWAP {
219
+ free(): void;
220
+ [Symbol.dispose](): void;
221
+ batch(high: Float64Array, low: Float64Array, close: Float64Array, volume: Float64Array): Float64Array;
222
+ constructor();
223
+ }
224
+
225
+ export class WMA {
226
+ free(): void;
227
+ [Symbol.dispose](): void;
228
+ batch(prices: Float64Array): Float64Array;
229
+ isReady(): boolean;
230
+ constructor(period: number);
231
+ reset(): void;
232
+ update(value: number): number | undefined;
233
+ warmupPeriod(): number;
234
+ }
235
+
236
+ export class WilliamsR {
237
+ free(): void;
238
+ [Symbol.dispose](): void;
239
+ batch(high: Float64Array, low: Float64Array, close: Float64Array): Float64Array;
240
+ constructor(period: number);
241
+ }
242
+
243
+ /**
244
+ * Optional helper: install `console.error` panic hook in the browser.
245
+ */
246
+ export function installPanicHook(): void;
247
+
248
+ /**
249
+ * Library version (matches the Cargo package version).
250
+ */
251
+ export function version(): string;
package/wickra_wasm.js ADDED
@@ -0,0 +1,9 @@
1
+ /* @ts-self-types="./wickra_wasm.d.ts" */
2
+ import * as wasm from "./wickra_wasm_bg.wasm";
3
+ import { __wbg_set_wasm } from "./wickra_wasm_bg.js";
4
+
5
+ __wbg_set_wasm(wasm);
6
+
7
+ export {
8
+ ADX, ATR, Aroon, AwesomeOscillator, BollingerBands, CCI, DEMA, Donchian, EMA, HMA, KAMA, Keltner, MACD, MFI, OBV, PSAR, ROC, RSI, SMA, Stochastic, TEMA, TRIX, VWAP, WMA, WilliamsR, installPanicHook, version
9
+ } from "./wickra_wasm_bg.js";