278b6afaa4
The 33 Markdown files under docs/wiki/ were never tracked. Commit them
into the repository so the documentation is versioned alongside the
code: 8 top-level pages plus 25 per-indicator deep dives under
indicators/{momentum,trend,volatility,volume}/.
The pages are kept in-repo (not pushed to a flat GitHub Wiki), so the
relative indicators/<family>/... links in Home.md resolve correctly
when rendered on GitHub.
174 lines
5.9 KiB
Markdown
174 lines
5.9 KiB
Markdown
# Quickstart: Node
|
||
|
||
A five-minute tour of the Wickra Node.js binding. The binding is generated by
|
||
[napi-rs](https://napi.rs/), so it's a native addon — no WebAssembly, no
|
||
slow JS reimplementation.
|
||
|
||
## Install
|
||
|
||
```bash
|
||
npm install wickra
|
||
```
|
||
|
||
> **Windows install caveat (current, 0.1.4).** The platform-specific
|
||
> sub-package `wickra-win32-x64-msvc@0.1.4` is presently held back by npm's
|
||
> automated spam filter. On a Windows x64 machine `npm install wickra`
|
||
> succeeds, but `require('wickra')` then throws
|
||
> `Error: Cannot find module 'wickra-win32-x64-msvc'` because the loader
|
||
> falls through to `require('wickra-win32-x64-msvc')` when no local `.node`
|
||
> binary is found. Linux x64 and macOS (x64 + arm64) wheels are unaffected.
|
||
> If you are on Windows today, build the binding from source (see "Building
|
||
> from source" below) until the npm side is resolved.
|
||
|
||
## A first run
|
||
|
||
```javascript
|
||
const wickra = require('wickra');
|
||
|
||
console.log('wickra', wickra.version());
|
||
|
||
// Simple moving average over a fixed window.
|
||
const sma = new wickra.SMA(3);
|
||
console.log(sma.batch([2, 4, 6, 8, 10]));
|
||
// -> [ NaN, NaN, 4, 6, 8 ]
|
||
```
|
||
|
||
Two things to notice:
|
||
|
||
1. The `batch` return type is a regular JavaScript `Array<number>`. Warmup
|
||
slots are `NaN`, not `null` or `undefined`, so the array is
|
||
`Number.isFinite`-checkable in one pass.
|
||
2. `new wickra.SMA(0)` does **not** throw. Constructors in the Node binding
|
||
currently cannot raise errors from JS (a napi-rs 2.16 limitation), so
|
||
pathological values like `period = 0` are clamped to the smallest valid
|
||
window. This is exactly the behaviour pinned by
|
||
`bindings/node/__tests__/smoke.test.js` ("zero period is clamped to a
|
||
valid window").
|
||
|
||
## Streaming
|
||
|
||
```javascript
|
||
const wickra = require('wickra');
|
||
|
||
const sma = new wickra.SMA(3);
|
||
for (const price of [2, 4, 6, 8, 10]) {
|
||
const value = sma.update(price);
|
||
console.log('update', price, '->', value);
|
||
}
|
||
```
|
||
|
||
Output:
|
||
|
||
```
|
||
update 2 -> null
|
||
update 4 -> null
|
||
update 6 -> 4
|
||
update 8 -> 6
|
||
update 10 -> 8
|
||
```
|
||
|
||
`update` returns either a JavaScript `number` or `null` while the indicator
|
||
is still warming up. (Compare with `batch`, where warmup slots are `NaN`.
|
||
The asymmetry exists because the streaming API surfaces "no value yet"
|
||
through the JS type system, whereas the batch result is shaped as a numeric
|
||
array for downstream numeric code.)
|
||
|
||
## MACD: streaming and batch
|
||
|
||
`MACD` is the canonical multi-output indicator. The Node API surfaces this in
|
||
two shapes:
|
||
|
||
- `update(price)` returns either `null` (during warmup) or
|
||
`{ macd, signal, histogram }`.
|
||
- `batch(prices)` returns a **flat** `Array<number>` of length `prices.length * 3`,
|
||
laid out as `[macd_0, signal_0, hist_0, macd_1, signal_1, hist_1, ...]`,
|
||
with each warmup row written as three `NaN`s.
|
||
|
||
Streaming form:
|
||
|
||
```javascript
|
||
const wickra = require('wickra');
|
||
|
||
const macd = new wickra.MACD(12, 26, 9);
|
||
let last = null;
|
||
for (let i = 0; i < 40; i++) {
|
||
last = macd.update(100 + i * 0.5);
|
||
}
|
||
console.log(last);
|
||
// -> { macd: 3.5, signal: 3.500000000000001, histogram: -8.881784197001252e-16 }
|
||
```
|
||
|
||
Batch form (note the flat layout):
|
||
|
||
```javascript
|
||
const wickra = require('wickra');
|
||
|
||
const prices = Array.from({ length: 40 }, (_, i) => 100 + i * 0.5);
|
||
const macd = new wickra.MACD(12, 26, 9);
|
||
const flat = macd.batch(prices);
|
||
|
||
console.log('total values:', flat.length); // -> 120 (= 40 * 3)
|
||
console.log('row 33 :', flat.slice(99, 102)); // -> [ 3.5, 3.5, 0 ]
|
||
console.log('row 39 :', flat.slice(117, 120)); // -> [ 3.5, 3.5000000..., -8.88e-16 ]
|
||
|
||
// Reshape into 3-tuples if you want:
|
||
const rows = [];
|
||
for (let i = 0; i < flat.length; i += 3) {
|
||
rows.push({ macd: flat[i], signal: flat[i + 1], histogram: flat[i + 2] });
|
||
}
|
||
```
|
||
|
||
`MACD(12, 26, 9)` emits its first non-NaN row at index 33 because the
|
||
underlying Rust `warmup_period()` is `slow + signal − 1 = 34` (the first
|
||
ready row is `warmup_period - 1` in 0-indexed terms).
|
||
|
||
## API surface
|
||
|
||
The complete TypeScript definitions live at
|
||
`bindings/node/index.d.ts`. Every indicator class exposes some subset of:
|
||
|
||
| Member | Notes |
|
||
|---------------------------|------------------------------------------------------------------------|
|
||
| `constructor(...)` | Pathological values are clamped, not thrown. |
|
||
| `update(...)` | Returns the indicator output or `null` during warmup. |
|
||
| `batch(...)` | Single-output: flat `Array<number>` with `NaN` warmup.<br>Multi-output: flat interleaved `Array<number>`. |
|
||
| `reset()` | Returns to a freshly-constructed state. |
|
||
| `isReady()` | `true` once the first value has been emitted. |
|
||
| `warmupPeriod()` | Present on single-output indicators (SMA, EMA, WMA, RSI, ...). Not exposed on every multi-output class — check `index.d.ts`. |
|
||
|
||
A complete reference run lives in `bindings/node/__tests__/smoke.test.js`:
|
||
|
||
```bash
|
||
cd bindings/node
|
||
npm install
|
||
npm run build # only needed if you cloned the repo (Windows: see above)
|
||
npm test
|
||
```
|
||
|
||
## Building from source (Windows workaround)
|
||
|
||
If you are on Windows x64 and want to use Wickra today, build the binding
|
||
locally from the repository:
|
||
|
||
```bash
|
||
git clone https://github.com/kingchenc/wickra
|
||
cd wickra/bindings/node
|
||
npm install
|
||
npm run build # requires a Rust toolchain (rustup) on PATH
|
||
npm test
|
||
```
|
||
|
||
`npm run build` produces `wickra.win32-x64-msvc.node` in the binding
|
||
directory; the platform loader in `index.js` then picks it up before falling
|
||
through to the npm sub-package and the install just works.
|
||
|
||
## See also
|
||
|
||
- [Quickstart: Python](Quickstart-Python.md) — sibling binding with NumPy
|
||
shapes.
|
||
- [Streaming vs Batch](Streaming-vs-Batch.md) — why `update` is the primary
|
||
entry point, not `batch`.
|
||
- [Warmup Periods](Warmup-Periods.md) — exact `warmup_period()` for every
|
||
indicator.
|
||
- Source: <https://github.com/kingchenc/wickra>
|