* feat(bindings): expose name() on every indicator in Node, WASM, and Python Surface the core Indicator::name() / BarBuilder::name() accessor through the three native bindings so every indicator reports its canonical name at runtime, matching the existing reset/isReady/warmupPeriod surface. - Node (napi): name(): string on all 514 classes (regenerated index.d.ts) - WASM (wasm-bindgen): name(): string on all 514 classes - Python (pyo3): name() -> str on all classes * feat(bindings): expose name() across the C ABI and C/C++/Go/C#/Java/R Regenerate the C ABI and the four generated language bindings from the updated ScriptHelpers generators so every indicator and bar builder reports its canonical name at runtime, completing name() coverage across all 10 languages. - C ABI (bindings/c): wickra_<ind>_name() -> *const c_char for all 514, cached in a per-function OnceLock<CString> with ind.name() as the source of truth; cbindgen header regenerated and vendored into bindings/go/include. - Go: Name() string; C#: string Name(); Java: String name(); R: name() S3 generic over the wk_<ind>_name C glue (methods.R + NAMESPACE). The Java regeneration also restores two fixes that had drifted out of the generator (bool* arrays via boolSegment; uint8_t ctor args cast to byte) and C# re-emits '#nullable enable'; these are no-op vs the previous committed output apart from the new name() accessors. * test(golden): pin canonical name() across all 10 language bindings Add a cross-language name() consistency check: every indicator must report the exact core Indicator::name() (which can differ from the registered class name, e.g. ChaikinMoneyFlow -> "CMF", Donchian -> "DonchianChannels"). The 514 core names are committed as testdata/golden/names.json (keyed by Rust canonical) and asserted by each binding's golden replay, which already reconstructs the whole catalogue: - node / wasm: assert against names.json in the existing golden test - python: new test_golden_names.py over the shared node manifest - go / csharp / java / c+c++ / r: the golden-test generators load names.json and emit a name assertion per indicator (regenerated test artifacts committed) All 10 bindings return identical names by construction (each delegates to core), so this pins that contract and guards against a future binding breaking the passthrough. * docs(changelog): record name() across all 10 bindings under Unreleased * fix(r): restore bool* flag marshalling in the regenerated C glue The name() regeneration had reverted the cross-section bool fix: the R glue emitted (bool *)REAL(x) for const bool* inputs, reinterpreting 8-byte doubles as 1-byte bools so every flag read as false (PercentAboveMa, NewHighsNewLows, HighLowIndex, BullishPercentIndex returned 0 instead of the breadth value). The wk_bool_vec() helper is restored in the generator and the glue routes bool arrays through it again.
Wickra — C / C++ examples
The Wickra C ABI is a single shared/static library plus a generated header
(bindings/c/include/wickra.h). Any
C-capable language links against the same artifact; these examples show the
plain-C path.
Build the library
From the workspace root:
cargo build -p wickra-c --release
This produces, in target/release/:
| Platform | Shared library | Link target |
|---|---|---|
| Linux | libwickra.so |
-lwickra |
| macOS | libwickra.dylib |
-lwickra |
| Windows (MSVC) | wickra.dll |
wickra.dll.lib (import lib) |
A static library (libwickra.a / wickra.lib) is emitted alongside.
Build and run the smoke example
With CMake (portable, used by CI)
cmake -S examples/c -B examples/c/build -DWICKRA_LIB_DIR="$PWD/target/release"
cmake --build examples/c/build
ctest --test-dir examples/c/build --output-on-failure
Directly with a compiler
# Linux / macOS
cc examples/c/smoke.c -I bindings/c/include -L target/release -lwickra -lm -o smoke
LD_LIBRARY_PATH=target/release ./smoke # macOS: DYLD_LIBRARY_PATH
# Windows (MinGW gcc, linking the DLL directly)
gcc examples/c/smoke.c -I bindings/c/include target/release/wickra.dll -lm -o smoke.exe
Expected output:
OK: wickra C ABI smoke passed (SMA streaming + batch + reset + NULL-safety + free)
The examples
| Example | What it does |
|---|---|
smoke.c |
Links the boundary and asserts SMA streaming / batch / reset / NULL-safety values. |
streaming.c |
Feeds a synthetic price series through SMA / EMA / RSI / MACD tick by tick. |
backtest.c |
Runs an indicator basket over an OHLCV CSV (defaults to the bundled daily dataset). |
multi_timeframe.c |
Resamples the bundled 1-minute CSV to 5m / 15m / 1h / 4h / 1d and prints indicators per timeframe. |
parallel_assets.c |
Serial vs OpenMP fan-out over a synthetic panel (one handle per asset), with speedup. |
strategy_rsi_mean_reversion.c |
Hourly RSI(14) mean-reversion with a PnL / Sharpe / max-drawdown summary. |
strategy_macd_adx.c |
Hourly MACD crossover gated by ADX(14) > 20. |
strategy_bollinger_squeeze.c |
Daily Bollinger-squeeze breakout with an ATR(14) stop. |
fetch_btcusdt.c |
Downloads BTCUSDT klines from the Binance REST API into examples/data/ (shells out to curl). |
live_binance.c |
Polls the Binance REST klines endpoint via curl and streams closed candles through RSI(14). |
smoke.cpp |
C++ RAII via wickra::Handle from wickra.hpp. |
ctest builds and runs every example except fetch_btcusdt and live_binance,
which reach the network and are built only — run those two by hand. The C ABI
exposes only the indicators, not the wickra-data IO layer, so the examples read
CSV (wickra_csv.h) and resample themselves; the network ones
shell out to the system curl rather than adding an HTTP/TLS dependency.
Usage shape
Every indicator follows the same five-function pattern over an opaque handle:
#include "wickra.h"
struct Sma *sma = wickra_sma_new(14); /* NULL on invalid params */
double v = wickra_sma_update(sma, 42.0); /* NaN during warmup */
wickra_sma_reset(sma); /* back to fresh state */
wickra_sma_free(sma); /* exactly once per _new */
There is no RAII across the C boundary: every wickra_<ind>_new must be paired
with exactly one wickra_<ind>_free. All functions are NULL-safe (a NULL handle
yields NaN / a no-op, never a crash).