* feat(data-layer): TickAggregator in Node, WASM, Python + C ABI hub
First data-layer feature (F2): roll trade ticks up into fixed-timeframe OHLCV
candles, exposed natively and over the C ABI.
- wickra-data wired as a binding dependency (workspace dep; its wickra-core dep
is default-features=false so it never forces rayon into the rayon-free WASM
build — native bindings re-enable parallel through their own dependency).
- Node `TickAggregator(bucket, gapFill?)` -> `push(price, size, ts): Candle[]`;
WASM the same (array of objects); Python `push(...) -> list[tuple]`.
- C ABI: `WickraCandle` struct + `wickra_tick_aggregator_new/push/free` (push
writes candles into a caller buffer and returns the count), generated via the
capi generator's new DATA_LAYER section; cbindgen now parses wickra-data so
`TickAggregator` is a forward-declared opaque; header vendored to bindings/go.
Verified bit-identical across Node/WASM/Python/C/C++ (o=100 h=101 l=100 c=101
v=3 ts=0 for the shared 3-tick probe). WIP: Go/C#/Java/R generated bindings and
the cross-language golden are still pending.
* feat(data-layer): TickAggregator in Go, C#, Java, R (lossless push/drain)
Complete F2 across all 10 languages: the C-ABI tick aggregator now uses a
two-step push/drain so gap-fill candles are never lost, and the four generated
bindings expose it idiomatically.
- C ABI redesigned: opaque TickAggregator handle (inner aggregator + pending
buffer); push consumes a tick and returns the closed-candle count, drain copies
them into a count-sized caller buffer.
- Go: NewTickAggregator + Push(price,size,ts) []Candle; C#: TickAggregator +
Candle[] Push(...); Java: TickAggregator + Candle[] push(...); R: TickAggregator
constructor + push() S3 generic returning an (n x 6) numeric matrix.
- Candle output record generated per language from WickraCandle.
Verified bit-identical to the native bindings (o=100 h=101 l=100 c=101 v=3 ts=0)
in Go, C#, Java, and R at runtime; R passes R CMD check (pre-existing doc
warnings only). WIP: cross-language data-layer golden + CHANGELOG still pending.
* test(data-layer): cross-language golden for the tick aggregator + CHANGELOG
gen_golden emits a deterministic tick stream (testdata/golden/data_ticks.csv) and
the reference candle streams with and without gap filling (data_candles.csv,
data_candles_gap.csv). Every binding replays the shared ticks through its
TickAggregator and checks the candles bit-for-bit (fp tolerance) against the Rust
reference:
- Node / WASM / Python / Go / C# / Java / R: a dedicated parity test each.
- C / C++: data_layer_test.c (compiled as both, run as ctest).
The gap-fill fixture closes several candles from a single push, exercising the
lossless push/drain path. Records the feature under CHANGELOG [Unreleased].
* fix(examples): rename the CSV-loader candle to WickraBar
The example CSV helper (wickra_csv.h) defined its own struct WickraCandle, which
now collides with the public C ABI WickraCandle (the tick aggregator output) in
any example that includes both headers (backtest, multi_timeframe, the strategy
examples). The public type owns the name; rename the example loader's bar to
WickraBar. The generated golden_test.c is untouched (its only match was the
unrelated WickraCandleVolumeOutput).
Stacked on #222 (base `feat/c-abi-hub`), so the diff is just the additions on top of the hub foundation — no merge of #222 required.
## What this adds
**Examples — full parity with rust/python/node (`examples/c/`)**
- `streaming.c` upgraded to the multi-indicator (SMA/EMA/RSI/MACD + signals) demo
- `backtest.c`, `multi_timeframe.c` (manual time-bucket resampling), `parallel_assets.c` (serial vs OpenMP fan-out, one handle per asset)
- three educational strategies: `strategy_rsi_mean_reversion.c`, `strategy_macd_adx.c`, `strategy_bollinger_squeeze.c`
- two network examples shelling out to `curl`: `fetch_btcusdt.c`, `live_binance.c` (REST poll)
- two header-only helpers (`wickra_csv.h`, `wickra_strategy.h`) since the C ABI ships no IO layer
- CMake builds all 11; the 9 offline ones run under `ctest` on 3 OS; the network two are built-only
**Docs & metadata — surface the C ABI everywhere it was missing**
- ARCHITECTURE diagram + crate table, SECURITY + THREAT_MODEL (the C ABI as the sole `unsafe` FFI surface), the three binding package READMEs, issue/PR templates, CHANGELOG, and the GitHub About template (live About + org description updated too)
**Cleanup**
- removed all references to the private generator tooling from public files (`bindings/c/src/lib.rs` header, `CONTRIBUTING.md`, `sync-about.yml`)
Verified locally: `cargo build -p wickra-c --release`, `cmake + ctest` (9/9 pass), and `-Wall -Wextra -Wpedantic` clean on gcc 13.