Commit Graph

31 Commits

Author SHA1 Message Date
kingchenc fae60e0d54 release: bump 0.4.2 -> 0.4.3 (#125) 2026-06-01 20:49:11 +02:00
kingchenc b5d9e47a2e release: bump 0.4.1 -> 0.4.2 (#121) 2026-06-01 18:29:32 +02:00
kingchenc 498b74a5ae chore(license): point package metadata at the modified license file
The LICENSE now carries an Additional Permissions section on top of
PolyForm Noncommercial 1.0.0, so the bare SPDX id no longer describes
it exactly. Update the package manifests to reference the actual file
instead of claiming the unmodified standard:

- Cargo (workspace + all crates): license -> license-file = "LICENSE"
- npm (main + 6 platform packages): LicenseRef-Wickra-Noncommercial-1.0.0
- PyPI: license text notes the additional personal-account permissions
2026-06-01 15:28:18 +02:00
kingchenc 4631519885 release: bump 0.4.0 -> 0.4.1 (#110)
Releases the cross-asset / pairwise indicator family (PR #109):
PairwiseBeta, PairSpreadZScore, LeadLagCrossCorrelation, Cointegration,
RelativeStrengthAB. Indicator count 214 -> 219.

Bumps workspace + binding versions and the CHANGELOG ([Unreleased] ->
[0.4.1]) with the new compare URL.
2026-06-01 13:58:50 +02:00
kingchenc eab2649f1c release: bump 0.3.1 -> 0.4.0 (#89)
Minor release. The headline user-facing change is the Node binding now
rejecting invalid indicator periods instead of silently clamping period 0
to 1 (matches Python/WASM/core); plus per-ecosystem binding READMEs and a
corrected MSRV statement in CONTRIBUTING. See CHANGELOG [0.4.0].

- Cargo.toml (workspace.package + wickra-core dep) + Cargo.lock (6 members)
- bindings/python/pyproject.toml
- bindings/node/package.json (version + 6 optionalDependencies) + package-lock.json
- bindings/node/npm/*/package.json (6 platform subpackages)
- examples/node/package-lock.json (wickra-* platform pins)
- CHANGELOG: [Unreleased] -> [0.4.0] - 2026-05-31 + compare URL

No tag pushed (release publish is a separate, user-confirmed step).
2026-06-01 01:28:53 +02:00
kingchenc 9309bf9d60 docs(P6.4): repoint all doc links from the GitHub wiki to docs.wickra.org (#86)
The documentation now lives in the wickra-lib/wickra-docs VitePress repo and
will deploy to docs.wickra.org. Rewrite every tracked, user-facing wiki link
in the main repo to the new canonical site:

- docs/README.md, CONTRIBUTING.md, PULL_REQUEST_TEMPLATE.md
- bindings/{node,python,wasm}/README.md, examples/wasm/README.md
- repo-metadata.toml: wiki_url/wiki_git -> docs_url/docs_git

Page paths map 1:1 to VitePress clean URLs (e.g. /wiki/Quickstart-Rust.md ->
docs.wickra.org/Quickstart-Rust). The sync-about.yml wiki-sync step is left
untouched on purpose: it stays until the docs site is live (tracked as P8.3).
The GitHub wiki itself is not deleted yet for the same reason.
2026-05-31 21:48:24 +02:00
kingchenc 21c86f348f examples + bindings: Node/WASM strategy parity + test/benchmark parity (P2 + P3) (#81)
* examples(node): add RSI mean-reversion strategy

Node counterpart of strategy_rsi_mean_reversion.{py,rs}: RSI(14) < 30 long,
> 70 exit, 0.1% fees, hourly BTCUSDT. Output verified byte-identical to the
Rust reference (37 trades W24/L13, -17.84% return, 46.89% max drawdown).

* examples(node): add MACD + ADX trend-filter strategy

Node counterpart of strategy_macd_adx.{py,rs}: MACD(12,26,9) histogram
crossover entries gated by ADX(14) > 20, hourly BTCUSDT, 0.1% fees. Output
verified byte-identical to the Rust reference (246 trades W90/L156, -47.19%
return, 53.75% max drawdown).

* examples(node): add Bollinger-squeeze breakout strategy

Node counterpart of strategy_bollinger_squeeze.{py,rs}: enter on a fresh
180-bar Bollinger-bandwidth low + close above the upper band, exit on a
2*ATR(14) stop or upper-band collapse, daily BTCUSDT, 0.1% fees. Output
verified byte-identical to the Rust reference (1 trade, -7.82% return,
13.01% max drawdown).

* examples(wasm): add RSI mean-reversion strategy demo

Browser counterpart of strategy_rsi_mean_reversion.{py,js,rs}: RSI(14) < 30
long, > 70 exit, 0.1% fees, summary table. Same signal/fill/PnL/equity loop as
the runtime-verified Node example; loads via the established wickra_wasm.js
init + fetch-CSV pattern. (wasm32 build runs in CI.)

* examples(wasm): add MACD + ADX trend-filter strategy demo

Browser counterpart of strategy_macd_adx.{py,js,rs}: MACD(12,26,9) histogram
crossover gated by ADX(14) > 20, hourly BTCUSDT, 0.1% fees. Logic identical to
the runtime-verified Node example; standard wickra_wasm.js init + fetch-CSV
loader. (wasm32 build runs in CI.)

* examples(wasm): add Bollinger-squeeze breakout strategy demo

Browser counterpart of strategy_bollinger_squeeze.{py,js,rs}: fresh 180-bar
Bollinger-bandwidth low + upper-band breakout, 2*ATR(14) stop, daily BTCUSDT,
0.1% fees. Logic identical to the runtime-verified Node example; standard
wickra_wasm.js init + fetch-CSV loader. (wasm32 build runs in CI.)

* ci: add examples syntax-smoke job (P2.3)

The Rust examples are built by 'cargo build -p wickra-examples --bins'; the
Node, browser-WASM and Python examples had no build gate. New job parse-checks
every examples/{node,wasm}/*.js, extracts and node --checks each WASM .html
module script, and python -m py_compile's every examples/python/*.py — so a
broken example edit fails CI instead of landing silently.

* docs(examples): list the new Node + WASM strategy examples

Add the three Node strategy scripts and three WASM strategy demos to the
examples README tables, bringing Node and WASM to parity with the existing
Rust and Python strategy rows.

* chore(examples): refresh examples/node lockfile for the linked wickra binding

npm install rewrote the file: dependency snapshot of the local wickra binding
that the examples link against (version 0.1.4 -> 0.3.1, license + engines
fields), which had gone stale in the committed lockfile.

* test(node): add input-validation suite

Node counterpart of bindings/python/tests/test_input_validation.py: invalid
constructor parameters (ATR zero period, MACD non-increasing fast/slow,
BollingerBands negative multiplier, PSAR step > max, ValueArea period/pct,
InitialBalance/OpeningRange zero period, Ichimoku non-increasing periods,
Ehlers-family ordering) and unequal-length candle/ValueArea batch inputs all
throw a JS Error. Validated against the built binding.

* test(node): add indicator completeness contract

Introspects every exported indicator class and asserts the full interface
(update / batch / reset / isReady / warmupPeriod) plus the pre-warmup contract
for zero-arg indicators, and guards that the full catalogue (>= 200 classes)
is exported. Catches a new indicator wired without the standard methods, or a
stale/partial native build dropping exports, with no per-indicator boilerplate.

* test(wasm): broaden scalar streaming-vs-batch coverage

Extend the inline wasm-bindgen-test suite with a streaming==batch check across
~70 scalar indicators spanning moving averages, momentum, volatility,
statistics/regression, Ehlers/cycle and risk/performance families (previously
only EMA + the candle-input group were covered per-indicator), plus four more
invalid-constructor assertions. Constructor args mirror the CI-passing Node
factories. Host-compiles (cargo test -p wickra-wasm --no-run); executed in CI
via wasm-pack test --node.

* bench(node): add indicator throughput benchmark

Node counterpart of the Rust criterion benches / Python compare_libraries:
measures streaming (per-tick update) and batch throughput in Mupd/s across a
representative indicator set over a synthetic OHLCV series (--bars, default
200k). Dependency-free; wired as 'npm run bench'.

* docs(wasm): list strategy demos + document the benchmark story

Add the three new strategy demos to the WASM examples table and a Performance
section: parallel_assets.html is the in-browser benchmark, with raw throughput
covered by the Rust criterion / Python / Node benchmarks (the WASM engine is the
same core compiled to wasm32).
2026-05-31 05:09:26 +02:00
kingchenc 01aeb965d1 release: bump 0.3.0 -> 0.3.1 (#80)
* chore: remove ROADMAP.md from the public repo

ROADMAP is kept as a local-only draft (ghost-ignored via
.git/info/exclude); it is not part of the published package surface.

* release: bump 0.3.0 -> 0.3.1

CI-only patch: fixes the release.yml CycloneDX SBOM step (cargo-cyclonedx
has no -p flag, see #79) that skipped the GitHub Release attach-assets job
on 0.3.0. No library changes — republishes the same code with a working
release pipeline.

- Cargo.toml (workspace.package + wickra-core dep) + Cargo.lock
- bindings/python/pyproject.toml
- bindings/node/package.json (version + 6 optionalDependencies) + package-lock.json
- bindings/node/npm/*/package.json (6 platform subpackages)
- CHANGELOG: finalize [0.3.0] (was still under [Unreleased]), add [0.3.1]

* chore: track examples/node/package-lock.json

Since the global package-lock ignore rule was dropped (#68) this file was
left untracked. Commit it for reproducible example installs, consistent
with bindings/node (findings P4.1).
2026-05-30 19:50:45 +02:00
kingchenc c212f91256 docs(examples): add 3 end-to-end strategy examples (Rust + Python) (#65)
Wires real indicators into complete signal -> fill -> PnL -> equity
loops over the checked-in BTCUSDT datasets, with per-trade Sharpe and
max-drawdown reported on stdout. Closes the gap where existing
examples showed only the mechanics of calling `update`/`batch` but not
how Wickra plugs into a trading-system shape.

Three strategies, each in Rust + Python (six files total):

- strategy_rsi_mean_reversion — RSI(14) thresholds (30/70) on 1h
  BTCUSDT. Binary position, 0.1% per-trade fee.
- strategy_macd_adx — MACD crossover entries gated by ADX(14) > 20 on
  1h BTCUSDT. Trend-follower demo of multi-indicator gating.
- strategy_bollinger_squeeze — Bollinger-bandwidth 180-day-low squeeze
  + upper-band breakout entry, ATR(14) * 2 stop. On 1d BTCUSDT for
  interpretable lookback.

Each file is self-contained — print_summary is inlined per script so
the example stays a single-file read. Every script prints a
NOT-financial-advice notice next to its results.

examples/README.md updated to list the new bins/scripts.
2026-05-30 18:23:03 +02:00
kingchenc 62ab84c472 chore(migration): switch org to wickra-lib and maintainer email to wickra.lib@gmail.com (#59)
Introduce repo-metadata.toml as single source of truth for repo identity
(org slug, maintainer email, canonical URLs) and add sync-metadata.yml
workflow with a Python audit script that fails CI if any tracked file
drifts back to pre-migration values.

Bulk-replace across 24 tracked files:
- kingchenc/wickra -> wickra-lib/wickra (URL segment)
- kingchencp@gmail.com -> wickra.lib@gmail.com (maintainer email)
- @kingchenc -> @wickra-lib (CODEOWNERS mention only)

Person-name credits are preserved: LICENSE copyright holder, Cargo.toml
authors handle, and CHANGELOG historical @kingchenc reference all remain
unchanged. Crate / PyPI / npm package names also untouched.

Merge this PR only after the kingchenc/wickra -> wickra-lib/wickra org
transfer has happened on the GitHub side, otherwise all badges and
repository links 404 until the transfer is performed.
2026-05-30 12:18:10 +02:00
kingchenc 4aec5d544c docs(wiki): migrate documentation out of repo into GitHub Wiki
The 84 markdown files under docs/wiki/ are now published to the
project's GitHub Wiki at https://github.com/kingchenc/wickra/wiki —
a separate git repository (https://github.com/kingchenc/wickra.wiki.git)
that GitHub hosts natively with its own UI, search and history. The
flat layout that the GitHub Wiki requires has been generated, all
internal cross-links rewritten, and a _Sidebar.md groups the 71
indicators by their canonical 8 families.

Effects:
- docs/wiki/ is removed from the main repo (-84 files). docs/README.md
  now just points readers at the Wiki.
- PR template + CONTRIBUTING text updated to point at the Wiki instead
  of the in-repo path. The Wiki repo is separately cloneable and
  editable via the GitHub web UI.
- examples/wasm/README.md cross-link fixed to use the Wiki URL.
- The (still in-repo) CHANGELOG keeps its historical references to
  docs/wiki/ paths — those describe what the tree looked like at past
  releases and stay accurate as history.
- README.md, license, all source unaffected.

The Wiki itself ships with _Sidebar.md / _Footer.md generated from the
8-families taxonomy and 503/503 cross-links resolved.
2026-05-23 22:48:48 +02:00
kingchenc 2bc6cc5505 docs: round out the docs for Z7's example additions
* examples/README.md — replace the single-row WASM section with a build
  block (one-time `wasm-pack` build), a serve note, and the full
  five-row table (`index`, `backtest`, `live_trading`, `multi_timeframe`,
  `parallel_assets`).
* examples/wasm/README.md — new dedicated index for the WASM demos
  with the build and serve commands and a description of every file
  including the module worker companion.
* CHANGELOG.md `[Unreleased]` gains three bullets: the Python and Node
  `fetch_btcusdt` siblings; the four new WASM browser demos; and the
  three new wiki pages from Z6 (TA-Lib-Migration, Cookbook, FAQ).
2026-05-23 00:45:51 +02:00
kingchenc 6e3190a44a examples(wasm): add a browser parallel-assets demo via Web Workers
Close the final "parallel assets" cell of the cross-language matrix for
WASM.

* examples/wasm/parallel_assets.html — generates a synthetic
  `(assets, bars)` panel deterministically (the LCG matches the Node
  and Rust siblings so timings are directly comparable), runs the
  serial baseline on the main thread, then dispatches the same workload
  to a pool of module Workers and reports the speedup. The render is
  three cards (serial / parallel / speedup) plus a sanity-check line
  asserting per-asset agreement between the two paths.
* examples/wasm/parallel_worker.js — companion module worker that
  loads its own copy of the WebAssembly module via `init()` and
  processes whichever slice of the panel its parent dispatches.

Modern browsers ship module-worker support (`new Worker(url, {
type: "module" })`) which lets every worker do `import init, { SMA, RSI
} from "../../bindings/wasm/pkg/wickra_wasm.js"` without bundler
glue. The inline page module and the worker module both syntax-check
cleanly under `node --check`.
2026-05-23 00:45:01 +02:00
kingchenc 04c3a83fdb examples(wasm): add a browser multi-timeframe demo
Close the "multi-timeframe" cell of the cross-language matrix for WASM.

* examples/wasm/multi_timeframe.html — fetches the bundled 1-minute
  BTCUSDT CSV (or any 1-minute OHLCV CSV), rolls it up in-page to 5m,
  15m, 1h, 4h and 1d buckets, and prints RSI(14), MACD(12,26,9)
  histogram and ADX(14) per timeframe via the WebAssembly bindings.
  Same inline-bucket aggregation as the Node sibling, same indicator
  set as the Python and Rust siblings — the Rust version uses
  `wickra-data::Resampler` directly which is currently a Rust-only API.

The render is a single table (one row per timeframe) so the cross-
language outputs sit side-by-side cleanly. The inline module script
syntax-checks cleanly under `node --check`.
2026-05-23 00:43:54 +02:00
kingchenc c87a16953b examples(wasm): add a browser live-trading demo
Close the "live trading" cell of the cross-language matrix for WASM.

* examples/wasm/live_trading.html — opens a native browser `WebSocket`
  to Binance's public kline stream, feeds every close through RSI(14),
  MACD(12,26,9) and Bollinger(20, 2.0) via the WebAssembly bindings, and
  flags BUY/SELL candidates when all three indicators agree. Mirrors
  the Node and Python live-trading examples in indicator set, signal
  logic and symbol/interval validation — the symbol is checked against
  `^[A-Za-z0-9]+$` before being spliced into the stream URL, the
  interval against the public-API allow-list.

The UI shows live close / RSI / MACD-histogram / Bollinger-band cards,
plus a scrolling log of the last 200 ticks with signal rows highlighted.
Browser-native `WebSocket` means no library dependency. Build the WASM
module once (`wasm-pack build bindings/wasm --target web --release
--features panic-hook`), serve the repository root and open
`examples/wasm/live_trading.html`.
2026-05-23 00:43:05 +02:00
kingchenc 5ea36a6064 examples(wasm): add a browser backtest demo
The WASM example set had only `index.html` (the streaming canvas demo);
the "backtest" cell of the cross-language matrix was empty. Close it.

* examples/wasm/backtest.html — loads the wasm-pack `--target web`
  bundle, fetches an OHLCV CSV from the same `examples/data/` directory
  the other languages use (default: `btcusdt-1d.csv`), parses it
  in-page and streams every candle through SMA, EMA, RSI, MACD,
  Bollinger, ATR, ADX and OBV via the WebAssembly bindings. Renders a
  summary table with mean / min / max / last per series — mirrors the
  Rust, Python and Node backtest examples both in indicator set and in
  output shape.

Build the WASM module once (`wasm-pack build bindings/wasm --target web
--release --features panic-hook`), then serve the repository root and
open `examples/wasm/backtest.html`. The inline module script
syntax-checks cleanly under `node --check` on the extracted body.
2026-05-23 00:42:14 +02:00
kingchenc 303ff0a163 examples(node): add a fetch_btcusdt script using built-in fetch
Node had no sibling for the Rust and Python `fetch_btcusdt`
data-generators — adding it closes the "fetch (data-gen)" cell for the
last remaining row of the cross-language example matrix where the
pattern makes sense.

* examples/node/fetch_btcusdt.js — uses Node 18+'s built-in global
  `fetch` (no npm dependencies); same pagination logic as the Rust and
  Python siblings (paginate backwards via `endTime`, drop the
  in-progress bucket, sort and trim to the configured target). Applies
  the same OHLC validity check the Rust `Candle::new` constructor
  enforces so a malformed kline is skipped rather than written.
* JavaScript's `String(v)` already gives the shortest round-trip
  representation and strips the `.0` suffix for whole-number floats, so
  the CSV output is byte-for-byte identical to what the Rust and
  Python fetchers produce on the same Binance snapshot. Verified by
  running it and `git diff`-ing against the checked-in dataset: every
  row older than the run is unchanged; only the most recent ~24 hours
  drift because the market kept moving.

examples/README.md gains the new row.
2026-05-23 00:40:27 +02:00
kingchenc b948b0b9cf examples(python): add a stdlib-only fetch_btcusdt script
Python had no sibling for the Rust `fetch_btcusdt` data-generator —
adding it closes the "fetch (data-gen)" cell for Python and lets users
without a Rust toolchain regenerate the bundled BTCUSDT datasets.

* examples/python/fetch_btcusdt.py — uses only the standard library
  (urllib.request + json + csv); same pagination strategy as the Rust
  version (paginate backwards via `endTime`, drop the in-progress
  bucket, sort and trim to the configured target). Applies the same
  OHLC validity check the Rust `Candle::new` constructor enforces
  (finite fields, high >= low/open/close, low <= open/close,
  volume >= 0) so a malformed kline is skipped rather than written.
* Number formatting matches Rust's `f64` Display: shortest round-trip,
  no trailing `.0` for whole-number floats. Verified by running the
  script and `git diff`-ing against the checked-in dataset: every row
  older than the run is byte-identical to Rust's output; the diff only
  shows the most recent ~24 hours where Binance has produced fresh
  candles since the original snapshot.

examples/README.md gains the new row.
2026-05-23 00:38:38 +02:00
kingchenc 43b0b26736 examples: add parallel-assets demos for Rust and Node
Python's parallel_assets.py demoed GIL-release multi-core throughput;
Rust and Node both lacked a sibling that shows their own native
parallelism. Close the gap with two real, runnable examples.

* examples/rust/src/bin/parallel_assets.rs — synthesises an (assets,
  bars) panel with a deterministic per-asset LCG, runs a serial baseline,
  then `Sma::batch_parallel` / `Rsi::batch_parallel` via rayon, asserts
  the two outputs are element-wise identical and prints the speedup.
  Toggle indicator with `--indicator sma|rsi`.
* examples/node/parallel_assets.js — same shape, but the parallel run is
  a `worker_threads` pool that re-loads the native binding in each
  worker. Each worker computes the last non-null indicator value for its
  slice; the main thread aggregates and verifies serial == parallel
  per asset.

Both examples report timings and the serial-vs-parallel sanity check
passes. Defaults (200 × 5000) keep the example fast on dev hardware;
larger `--assets`/`--bars` is where the speedup numbers move (Node's
worker spawn cost dominates the smallest sizes, which is honest and
educational).

examples/README.md gains the two new rows.
2026-05-23 00:18:46 +02:00
kingchenc 962ced0712 examples: add multi-timeframe demos for Rust and Node
Python's examples/python/multi_timeframe.py had no Rust or Node sibling.
Add both — the Rust version uses wickra-data's `Resampler` /
`resample_all` (the canonical path; no manual roll-up), the Node version
mirrors the Python one's inline aggregation because wickra-data's
resampler is currently Rust-only.

* examples/rust/src/bin/multi_timeframe.rs — reads the bundled 1m CSV via
  `CandleReader`, resamples to 5m / 15m / 1h / 4h / 1d via `resample_all`,
  prints last RSI(14), MACD(12,26,9) histogram and ADX(14) per timeframe.
* examples/node/multi_timeframe.js — same outputs from a hand-rolled
  bucket aggregator; reuses the new examples/data/ default path.
* examples/README.md gains the new rows.

Run side by side: the Rust and Node summaries are bit-identical at every
timeframe (50000 / 10000 / 3334 / 834 / 209 / 35 bars; same RSI, MACD
histogram and ADX to two decimals) — confirming both the Rust resampler
and the inline Node aggregator produce the same OHLC buckets.
2026-05-23 00:16:08 +02:00
kingchenc 5a4cf66022 examples: add streaming demos for Python and Rust
Python and Rust both lacked a standalone "streaming indicators" example
that mirrors examples/node/streaming.js — the quickstart docs cover the
pattern, but a runnable file makes the parity visible across all four
languages.

* examples/python/streaming.py — argparse-driven synthetic streaming demo
  feeding SMA(20) / EMA(20) / RSI(14) / MACD(12,26,9), tagging BUY?/SELL?
  candidates when RSI extremes and MACD-histogram direction agree.
* examples/rust/src/bin/streaming.rs — same demo as a wickra-examples
  binary, reusing the seeded LCG so its first 40 rows are bit-identical
  to the Python (and Node) sibling — a strong cross-language consistency
  signal verified by running both side by side.
* examples/README.md gains a `streaming` row in the Rust and Python tables.
2026-05-23 00:13:38 +02:00
kingchenc d87005577e examples: move the WASM browser demo into a top-level examples/wasm/
Finish the per-language `examples/<lang>/` restructure by relocating the
WASM browser demo from bindings/wasm/examples/ to examples/wasm/.

* `examples/wasm/index.html` is the moved file; its WASM module import
  becomes `../../bindings/wasm/pkg/wickra_wasm.js` so the demo still loads
  the wasm-pack output without copying it.
* bindings/wasm/README.md, Quickstart-WASM.md, examples/README.md and the
  root README "Languages" + project-layout block all point at the new
  path. The serve command in the docs now says "serve the repository root
  and open examples/wasm/index.html".

`bindings/wasm/examples/` is empty after the move; the now-empty
directory is removed.
2026-05-23 00:11:07 +02:00
kingchenc 8b9e8e30b9 examples: move Node examples into a top-level examples/node/
Continue the per-language `examples/<lang>/` restructure: move the three
Node example files (streaming.js, backtest.js, live_trading.js) out of
bindings/node/examples/ and into a top-level examples/node/ directory.

* `examples/node/package.json` is a `private` package that pulls the
  native binding via `file:../../bindings/node` and lists `ws` as a
  dev-dependency for the live-trading example. `require('..')` in each
  file becomes `require('wickra')` — exactly what a downstream user would
  write — and the file-header run instructions are updated to the new
  two-step workflow (`npm install` in bindings/node, then in
  examples/node).
* `backtest.js`'s default-CSV path becomes the much shorter
  `__dirname/../data/btcusdt-1d.csv` from the new location.
* `bindings/node/package.json` drops the now-unused `ws` devDependency.
* `.gitignore` is broadened from `bindings/node/node_modules/` to
  `**/node_modules/` so the new `examples/node/node_modules/` directory is
  not tracked.
* The README "Languages" table, project-layout block and
  `examples/README.md` Node section are updated for the new paths and run
  commands.

Verified by running `node backtest.js` (3200 BTCUSDT daily bars, matching
output), `node streaming.js`, and `node --check live_trading.js` from the
new location.
2026-05-23 00:10:06 +02:00
kingchenc 747d1a5b1b examples: move Rust examples into a top-level examples/rust/ crate
The three Rust examples (backtest, fetch_btcusdt, live_binance) used to
live each in their own crate's examples/ dir, splitting the example set
across crates and burying it inside the source tree. Move them into a new
workspace member crate at `examples/rust/` (package `wickra-examples`,
`publish = false`) so all language examples sit under one top-level
`examples/<lang>/` tree.

* `examples/rust/Cargo.toml` declares the per-binary deps (wickra,
  wickra-data with the `live-binance` feature always on, serde_json, tokio
  for the macro and current-thread runtime).
* `examples/rust/src/bin/{backtest,fetch_btcusdt,live_binance}.rs` are the
  three migrated binaries; their doc-comments and the fetch_btcusdt output
  path are updated for the new location and run command
  (`cargo run -p wickra-examples --bin <name>`).
* Workspace `Cargo.toml` lists the new member; the now-empty
  `[dev-dependencies]` extras (`wickra`, `tokio` in wickra-data and
  `serde_json` in wickra) that existed only for these examples are dropped.
* The `[[example]] live_binance` table is removed from wickra-data's
  manifest since the file moved out.
* README "Languages" + project-layout, examples/README.md, Quickstart-Rust
  and Data-Layer are pointed at the new paths and commands.

`cargo build -p wickra-examples` and `cargo run --release -p wickra-examples
--bin backtest -- examples/data/btcusdt-1d.csv` both succeed; the rest of
the workspace (core, data, wickra) builds, clippies (`--all-targets -D
warnings`) and tests (508 core + 28 data + 1 integration + 74+3+1
doctests) all stay green.
2026-05-23 00:07:07 +02:00
kingchenc a1c646ae7c examples: move the bundled BTCUSDT datasets to a top-level examples/data/
The seven BTCUSDT OHLCV datasets used to live under
crates/wickra/examples/data/, which buried them inside a Rust crate even
though the Node backtest example and the upcoming Rust/Node/WASM example
restructure need to reach them too. Move them to the workspace-level
examples/data/ so every language's examples can resolve the same path.

The bench (crates/wickra/benches/indicators.rs), the example_data
integration test, fetch_btcusdt.rs and the Node backtest example all take
the new ../../examples/data/ path; Data-Layer.md, examples/README.md and
the CHANGELOG entry are updated to match. No data file content changes.
2026-05-23 00:01:52 +02:00
kingchenc ba10898801 docs: add a cross-language examples index
The top-level examples/ directory held only python/, which made the
examples look Python-only even though Rust, Node and WASM all ship their
own. Add examples/README.md: a single index of every runnable example
across Rust, Python, Node and WASM, each with its run command, plus a note
on the bundled BTCUSDT datasets.

Point the README "Languages" table at the Node backtest example and link
the new index from both the table and the project-layout section.
2026-05-22 22:47:13 +02:00
kingchenc 79d705a746 C13: report clear CSV errors in the offline examples
backtest.py and multi_timeframe.py read OHLCV CSVs with csv.DictReader
and crashed opaquely on malformed input: a missing column raised a bare
KeyError, a non-numeric cell surfaced NumPy's column-less ValueError,
and an empty or all-NaN series hit IndexError deep in summarize.

Validate the header against the required columns up front, catch
non-numeric cells and report the offending row/column, reject a
header-only file distinctly from a headerless one, and guard resample
and summarize against empty input. Every failure mode now raises a
ValueError naming the file, row and column.
2026-05-22 12:29:40 +02:00
kingchenc a8fb0b8181 C12: fix falsy-value display and validate symbol/interval
Two issues in the live_trading example:

- The status line rendered indicator values with `... if snap.rsi
  else "--"`. A genuine reading of 0.0 is falsy, so an RSI / MACD
  histogram / Bollinger value of exactly zero was misreported as "--".
  Switch to explicit `is not None` checks.

- --symbol and --interval were interpolated straight into the stream
  name and WebSocket URL with no checks. Add validate_args: the symbol
  must be strictly alphanumeric and the interval must be one Binance
  recognises. main() validates before connecting and exits with a clear
  error and code 2 otherwise; the strict values keep the URL well-formed
  without escaping.
2026-05-22 12:27:13 +02:00
kingchenc 783e40069d C8: skip non-kline frames in the live_trading example
The combined Binance stream interleaves the kline payloads with
subscription acks, heartbeats and error objects. The example pulled
k = payload.get("k", {}) and immediately did float(k.get("c")) — for
any non-kline frame k is {}, k.get("c") is None, and float(None) raises
TypeError, crashing the script the moment it connects.

Skip frames without a kline payload (no "k" object, or no "c" close
field) with a debug log line, matching the C2 fix on the Rust adapter.
2026-05-22 12:20:19 +02:00
kingchenc 06f67c8c0e Move Rust examples into their crates so cargo publish picks them up
The previous `[[example]] path = "../../examples/rust/..."` entries
pointed at files outside the crate root. cargo only packages files
inside the crate directory, so the examples would have been silently
dropped on publish. Moving them to crates/wickra/examples/ and
crates/wickra-data/examples/ keeps them as part of the published
package and lets cargo discover them automatically (no [[example]]
override needed). README and project-layout section updated.
2026-05-21 20:36:57 +02:00
kingchenc 3be267cb03 Wickra 0.1.0: streaming-first technical indicators
A multi-language technical analysis library: 25 indicators across trend,
momentum, volatility, and volume families, every one a state machine with
O(1) per-tick updates. Batch evaluation is provided by a blanket extension
trait over the streaming primitive, so live trading bots and historical
backtests run the same code path.

What ships in this initial drop:

  crates/wickra-core   - 25 indicators, Indicator/BatchExt/Chain traits,
                          OHLCV types with validation; 171 unit tests,
                          property tests, Wilder/Bollinger textbook tests.
  crates/wickra        - top-level facade + criterion benches for every
                          indicator at 1K/10K/100K series sizes.
  crates/wickra-data   - streaming CSV reader, tick-to-candle aggregator,
                          multi-timeframe resampler, Binance Spot kline
                          WebSocket adapter behind feature live-binance;
                          11 unit + 1 doctest.
  bindings/python      - PyO3 + maturin, NumPy I/O, type stubs (.pyi),
                          56 pytest tests including streaming==batch
                          equivalence, Wilder reference values, lifecycle.
  bindings/node        - napi-rs native module, TypeScript .d.ts
                          auto-generated, 7 node --test cases.
  bindings/wasm        - wasm-bindgen ES module for browser/bundler/Node;
                          interactive HTML demo at examples/index.html.
  examples/            - Python and Rust scripts: backtest, live trading,
                          parallel multi-asset, multi-timeframe, Binance.
  benchmarks/          - cross-library comparison against TA-Lib,
                          pandas-ta, finta, talipp; Wickra wins every
                          category by 11-1030x (batch) and 17x+ streaming.
  .github/workflows/   - CI matrix (Rust + Python + Node + WASM on
                          Linux/macOS/Windows), release pipeline for
                          PyPI wheels and npm.

Indicators (25):
  Trend       SMA EMA WMA DEMA TEMA HMA KAMA
  Momentum    RSI MACD Stochastic CCI ROC WilliamsR ADX MFI TRIX
              AwesomeOscillator Aroon
  Volatility  BollingerBands ATR Keltner Donchian PSAR
  Volume      OBV VWAP (cumulative + rolling)

cargo clippy --workspace --all-targets -D warnings is clean. License: Apache-2.0.
2026-05-21 17:50:45 +02:00