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.
This commit is contained in:
Generated
+10
-2
@@ -1974,7 +1974,6 @@ dependencies = [
|
|||||||
"approx",
|
"approx",
|
||||||
"criterion",
|
"criterion",
|
||||||
"proptest",
|
"proptest",
|
||||||
"serde_json",
|
|
||||||
"wickra-core",
|
"wickra-core",
|
||||||
"wickra-data",
|
"wickra-data",
|
||||||
]
|
]
|
||||||
@@ -2003,10 +2002,19 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
"url",
|
"url",
|
||||||
"wickra",
|
|
||||||
"wickra-core",
|
"wickra-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wickra-examples"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
|
"wickra",
|
||||||
|
"wickra-data",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wickra-node"
|
name = "wickra-node"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ members = [
|
|||||||
"bindings/python",
|
"bindings/python",
|
||||||
"bindings/wasm",
|
"bindings/wasm",
|
||||||
"bindings/node",
|
"bindings/node",
|
||||||
|
"examples/rust",
|
||||||
]
|
]
|
||||||
exclude = ["fuzz"]
|
exclude = ["fuzz"]
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ inherit it automatically.
|
|||||||
| Python (PyO3) | `pip install wickra` | `examples/python/backtest.py` |
|
| Python (PyO3) | `pip install wickra` | `examples/python/backtest.py` |
|
||||||
| Node.js (napi-rs) | `npm install wickra` | `bindings/node/examples/backtest.js` |
|
| Node.js (napi-rs) | `npm install wickra` | `bindings/node/examples/backtest.js` |
|
||||||
| Browser / WASM | `npm install wickra-wasm` | `bindings/wasm/examples/index.html` |
|
| Browser / WASM | `npm install wickra-wasm` | `bindings/wasm/examples/index.html` |
|
||||||
| Rust | `cargo add wickra` | `crates/wickra/examples/backtest.rs` |
|
| Rust | `cargo add wickra` | `examples/rust/src/bin/backtest.rs` |
|
||||||
|
|
||||||
Each binding ships several runnable examples (streaming, backtest, live feed);
|
Each binding ships several runnable examples (streaming, backtest, live feed);
|
||||||
[`examples/README.md`](examples/README.md) is the full cross-language index.
|
[`examples/README.md`](examples/README.md) is the full cross-language index.
|
||||||
@@ -182,23 +182,22 @@ A Python live-trading example using the public `websockets` package lives at
|
|||||||
wickra/
|
wickra/
|
||||||
├── crates/
|
├── crates/
|
||||||
│ ├── wickra-core/ core engine + all 71 indicators
|
│ ├── wickra-core/ core engine + all 71 indicators
|
||||||
│ ├── wickra/ top-level facade crate (publishes on crates.io)
|
│ ├── wickra/ top-level facade crate (publishes on crates.io) + benches/
|
||||||
│ │ + benches/, examples/ (backtest, fetch_btcusdt)
|
|
||||||
│ │ and examples/data/ real BTCUSDT datasets
|
|
||||||
│ └── wickra-data/ CSV reader, tick aggregator, live exchange feeds
|
│ └── wickra-data/ CSV reader, tick aggregator, live exchange feeds
|
||||||
│ + examples/live_binance.rs
|
|
||||||
├── bindings/
|
├── bindings/
|
||||||
│ ├── python/ PyO3 + maturin (publishes on PyPI)
|
│ ├── python/ PyO3 + maturin (publishes on PyPI)
|
||||||
│ ├── node/ napi-rs (publishes on npm) + examples/
|
│ ├── node/ napi-rs (publishes on npm) + examples/
|
||||||
│ └── wasm/ wasm-bindgen (browsers, bundlers, Node) + examples/
|
│ └── wasm/ wasm-bindgen (browsers, bundlers, Node) + examples/
|
||||||
├── examples/ examples/README.md indexes every language
|
├── examples/ examples/README.md indexes every language
|
||||||
|
│ ├── data/ real BTCUSDT OHLCV datasets, one per timeframe
|
||||||
|
│ ├── rust/ Rust workspace member (`wickra-examples`)
|
||||||
│ └── python/ backtest, live trading, parallel assets, multi-tf
|
│ └── python/ backtest, live trading, parallel assets, multi-tf
|
||||||
└── .github/workflows/ CI and release pipelines
|
└── .github/workflows/ CI and release pipelines
|
||||||
```
|
```
|
||||||
|
|
||||||
Rust benchmarks and examples live inside their crate
|
Rust benchmarks live in `crates/wickra/benches/`; runnable Rust examples live
|
||||||
(`crates/wickra/benches/`, `crates/<name>/examples/`); there is no
|
in the workspace member crate at `examples/rust/`. There is no top-level
|
||||||
top-level `benches/` directory.
|
`benches/` directory.
|
||||||
|
|
||||||
## Building everything from source
|
## Building everything from source
|
||||||
|
|
||||||
|
|||||||
@@ -42,9 +42,3 @@ live-binance = ["dep:tokio", "dep:tokio-tungstenite", "dep:futures-util", "dep:u
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
approx = { workspace = true }
|
approx = { workspace = true }
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
wickra = { path = "../wickra" }
|
|
||||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
|
||||||
|
|
||||||
[[example]]
|
|
||||||
name = "live_binance"
|
|
||||||
required-features = ["live-binance"]
|
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ approx = { workspace = true }
|
|||||||
criterion = { workspace = true }
|
criterion = { workspace = true }
|
||||||
proptest = { workspace = true }
|
proptest = { workspace = true }
|
||||||
wickra-data = { path = "../wickra-data" }
|
wickra-data = { path = "../wickra-data" }
|
||||||
# Only the `fetch_btcusdt` example parses Binance REST JSON; a dev-dependency
|
|
||||||
# never reaches a downstream consumer's dependency tree.
|
|
||||||
serde_json = "1"
|
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "indicators"
|
name = "indicators"
|
||||||
|
|||||||
@@ -150,10 +150,10 @@ dropped connection, skips non-kline frames (subscription acks, heartbeats),
|
|||||||
applies a read timeout and message-size limits, and tracks a closed flag so a
|
applies a read timeout and message-size limits, and tracks a closed flag so a
|
||||||
deliberately closed stream is not reused.
|
deliberately closed stream is not reused.
|
||||||
|
|
||||||
A runnable example lives at `crates/wickra-data/examples/live_binance.rs`:
|
A runnable example lives at `examples/rust/src/bin/live_binance.rs`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo run -p wickra-data --example live_binance --features live-binance
|
cargo run -p wickra-examples --bin live_binance
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example datasets
|
## Example datasets
|
||||||
@@ -183,7 +183,7 @@ Binance REST API and needs the system `curl` (shipped with Windows 10+, macOS
|
|||||||
and Linux):
|
and Linux):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo run -p wickra --example fetch_btcusdt
|
cargo run -p wickra-examples --bin fetch_btcusdt
|
||||||
```
|
```
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|||||||
@@ -119,17 +119,17 @@ exact contract.
|
|||||||
|
|
||||||
## A deeper example
|
## A deeper example
|
||||||
|
|
||||||
`crates/wickra/examples/backtest.rs` shipped with the workspace computes a
|
`examples/rust/src/bin/backtest.rs` (in the `wickra-examples` workspace
|
||||||
panel of indicators (RSI, EMA, Bollinger, MACD, ATR, ADX, OBV) over an OHLCV
|
crate) computes a panel of indicators (RSI, EMA, Bollinger, MACD, ATR, ADX,
|
||||||
CSV by way of `wickra-data`:
|
OBV) over an OHLCV CSV by way of `wickra-data`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo run --release --example backtest -- path/to/ohlcv.csv
|
cargo run --release -p wickra-examples --bin backtest -- path/to/ohlcv.csv
|
||||||
```
|
```
|
||||||
|
|
||||||
For live-data work, `wickra-data` ships a streaming CSV reader, a
|
For live-data work, `wickra-data` ships a streaming CSV reader, a
|
||||||
tick-to-candle aggregator, a candle resampler, and a Binance kline WebSocket
|
tick-to-candle aggregator, a candle resampler, and a Binance kline WebSocket
|
||||||
adapter under the `live-binance` feature. `crates/wickra-data/examples/live_binance.rs`
|
adapter under the `live-binance` feature. `examples/rust/src/bin/live_binance.rs`
|
||||||
is the canonical example for the latter.
|
is the canonical example for the latter.
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|||||||
+7
-5
@@ -5,13 +5,15 @@ to the code they exercise so the language tooling (`cargo run --example`,
|
|||||||
`node`) can find them; the Python examples have no crate of their own and
|
`node`) can find them; the Python examples have no crate of their own and
|
||||||
live here under [`python/`](python/).
|
live here under [`python/`](python/).
|
||||||
|
|
||||||
## Rust — `crates/*/examples/`
|
## Rust — `examples/rust/`
|
||||||
|
|
||||||
|
The Rust examples live in the `wickra-examples` workspace member crate.
|
||||||
|
|
||||||
| Example | What it does | Run |
|
| Example | What it does | Run |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `backtest.rs` | Compute a basket of indicators over an OHLCV CSV and print a summary. | `cargo run -p wickra --example backtest -- <ohlcv.csv>` |
|
| `backtest.rs` | Compute a basket of indicators over an OHLCV CSV and print a summary. | `cargo run -p wickra-examples --bin backtest -- <ohlcv.csv>` |
|
||||||
| `fetch_btcusdt.rs` | Download real BTCUSDT klines from the Binance REST API into `examples/data/`. | `cargo run -p wickra --example fetch_btcusdt` |
|
| `fetch_btcusdt.rs` | Download real BTCUSDT klines from the Binance REST API into `examples/data/`. | `cargo run -p wickra-examples --bin fetch_btcusdt` |
|
||||||
| `live_binance.rs` | Stream live Binance klines through an indicator over a resilient WebSocket. | `cargo run -p wickra-data --example live_binance --features live-binance` |
|
| `live_binance.rs` | Stream live Binance klines through an indicator over a resilient WebSocket. | `cargo run -p wickra-examples --bin live_binance` |
|
||||||
|
|
||||||
## Python — `examples/python/`
|
## Python — `examples/python/`
|
||||||
|
|
||||||
@@ -46,4 +48,4 @@ Build the native module first: `cd bindings/node && npm install && npx napi buil
|
|||||||
per timeframe (1m, 5m, 15m, 1h, 12h, 1d, 1month), in the standard
|
per timeframe (1m, 5m, 15m, 1h, 12h, 1d, 1month), in the standard
|
||||||
`timestamp,open,high,low,close,volume` layout. The Rust and Node backtest
|
`timestamp,open,high,low,close,volume` layout. The Rust and Node backtest
|
||||||
examples and the indicator benchmarks run against them. Regenerate them with
|
examples and the indicator benchmarks run against them. Regenerate them with
|
||||||
the latest market history via `cargo run -p wickra --example fetch_btcusdt`.
|
the latest market history via `cargo run -p wickra-examples --bin fetch_btcusdt`.
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
[package]
|
||||||
|
name = "wickra-examples"
|
||||||
|
version = "0.0.0"
|
||||||
|
publish = false
|
||||||
|
description = "Runnable Rust examples for the Wickra technical-analysis library."
|
||||||
|
authors.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
rust-version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# All examples sit on top of the indicator engine.
|
||||||
|
wickra = { path = "../../crates/wickra" }
|
||||||
|
# The data layer is needed by every example except streaming/parallel: CSV
|
||||||
|
# reading, the Binance live feed and the resampler all live here. The
|
||||||
|
# `live-binance` feature is always on for this crate so the live_binance
|
||||||
|
# binary just compiles.
|
||||||
|
wickra-data = { path = "../../crates/wickra-data", features = ["live-binance"] }
|
||||||
|
# fetch_btcusdt parses the Binance REST kline response.
|
||||||
|
serde_json = "1"
|
||||||
|
# live_binance uses #[tokio::main]; the current-thread runtime is enough.
|
||||||
|
tokio = { version = "1", features = ["rt", "macros"] }
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Build with:
|
//! Build with:
|
||||||
//! ```text
|
//! ```text
|
||||||
//! cargo run --release --example backtest -- path/to/ohlcv.csv
|
//! cargo run --release -p wickra-examples --bin backtest -- path/to/ohlcv.csv
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
//! Rust example: download real BTCUSDT spot candles from the Binance REST API
|
//! Rust example: download real BTCUSDT spot candles from the Binance REST API
|
||||||
//! and write them as CSV datasets under `examples/data/`.
|
//! and write them as CSV datasets under `examples/data/`.
|
||||||
//!
|
//!
|
||||||
//! These are the datasets the indicator benchmarks (`benches/indicators.rs`)
|
//! These are the datasets the indicator benchmarks (`crates/wickra/benches/
|
||||||
//! and the `example_data` integration test run against. They live at the
|
//! indicators.rs`) and the `example_data` integration test run against. They
|
||||||
//! workspace `examples/data/` directory. Re-run this example to refresh
|
//! live at the workspace `examples/data/` directory. Re-run this example to
|
||||||
//! them with the latest market history:
|
//! refresh them with the latest market history:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
//! cargo run -p wickra --example fetch_btcusdt
|
//! cargo run -p wickra-examples --bin fetch_btcusdt
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! HTTPS is handled by shelling out to the system `curl` — shipped with
|
//! HTTPS is handled by shelling out to the system `curl` — shipped with
|
||||||
@@ -98,8 +98,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||||
.join("..")
|
.join("..")
|
||||||
.join("..")
|
|
||||||
.join("examples")
|
|
||||||
.join("data");
|
.join("data");
|
||||||
std::fs::create_dir_all(&data_dir)?;
|
std::fs::create_dir_all(&data_dir)?;
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Build with:
|
//! Build with:
|
||||||
//! ```text
|
//! ```text
|
||||||
//! cargo run --release --example live_binance --features wickra-data/live-binance -- BTCUSDT
|
//! cargo run --release -p wickra-examples --bin live_binance -- BTCUSDT
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! The example prints a line per bar close. Hit Ctrl+C to stop.
|
//! The example prints a line per bar close. Hit Ctrl+C to stop.
|
||||||
Reference in New Issue
Block a user