feat(data): expose CandleReader (CSV) natively in all 10 languages (#311)

Add the data-layer CSV candle reader to every binding so loading OHLCV
candles from a CSV no longer needs a per-language CSV/dataframe dependency.

- C ABI: wickra_candle_reader_new(bytes, len) / _count / _read / _free over
  an opaque CandleReader handle (parse the whole buffer up front, then drain).
- Native: Node/WASM CandleReader.read() -> Candle[], Python read() -> list[tuple].
- C-ABI languages: Go Read() []Candle, C# Candle[] Read(), Java Candle[] read(),
  R read() S3 generic (n x 6 matrix); C / C++ call the C ABI directly.
- Cross-language golden testdata/golden/data_csv*.csv pins the parsed candles
  bit-for-bit across every binding.

Verified locally across Rust (test+clippy+fmt), Node, WASM, Python, C#, Go,
Java, R, and the C/C++ cmake parity suite.
This commit is contained in:
kingchenc
2026-06-16 00:10:58 +02:00
committed by GitHub
parent cb6da4d737
commit d362ae26a3
31 changed files with 867 additions and 6 deletions
+10
View File
@@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- **CSV candle reading in all 10 languages (data layer).** The `CandleReader`
parses a `timestamp,open,high,low,close,volume` CSV buffer (a leading UTF-8 BOM
and field whitespace are tolerated) into candles: construct it from a CSV string
and call `read()` for every candle in file order. Exposed natively (Node.js /
WASM `read(): Candle[]`, Python `read() -> list[tuple]`) and over the C ABI as Go
`Read() []Candle`, C# `Candle[] Read()`, Java `Candle[] read()`, and the R
`read()` S3 generic (an `n×6` matrix); C / C++ call `wickra_candle_reader_new` /
`_count` / `_read` directly. A cross-language golden
(`testdata/golden/data_csv*.csv`) pins the parsed candles identically across
every binding. This makes CSV backtest loading dependency-free in every binding.
- **Candle resampling in all 10 languages (data layer).** The `Resampler`
aggregates candles into a higher timeframe (e.g. 1m → 5m): `update(open, high,
low, close, volume, timestamp)` returns the completed higher-timeframe candle on