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.
This commit is contained in:
kingchenc
2026-05-23 00:01:52 +02:00
parent ba10898801
commit a1c646ae7c
14 changed files with 32 additions and 28 deletions
+4 -4
View File
@@ -39,10 +39,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Community health files: `CONTRIBUTING.md`, `SECURITY.md`, - Community health files: `CONTRIBUTING.md`, `SECURITY.md`,
`CODE_OF_CONDUCT.md`, issue / pull-request templates, `CODEOWNERS`, and a `CODE_OF_CONDUCT.md`, issue / pull-request templates, `CODEOWNERS`, and a
Dependabot configuration. Dependabot configuration.
- Seven example OHLCV datasets under `crates/wickra/examples/data/`, one per - Seven example OHLCV datasets under `examples/data/`, one per timeframe
timeframe (1m / 5m / 15m / 1h / 12h / 1d / 1month), holding real BTCUSDT (1m / 5m / 15m / 1h / 12h / 1d / 1month), holding real BTCUSDT spot klines,
spot klines, alongside the `fetch_btcusdt` example that regenerates them alongside the `fetch_btcusdt` example that regenerates them from the
from the Binance REST API. Binance REST API.
- `Timeframe::minutes`, `Timeframe::hours` and `Timeframe::days` convenience - `Timeframe::minutes`, `Timeframe::hours` and `Timeframe::days` convenience
constructors, each building on seconds with a checked-multiplication constructors, each building on seconds with a checked-multiplication
overflow guard. overflow guard.
+2 -4
View File
@@ -26,15 +26,13 @@ const wickra = require('..');
// every one of them (any extra columns are ignored). // every one of them (any extra columns are ignored).
const REQUIRED_COLUMNS = ['timestamp', 'open', 'high', 'low', 'close', 'volume']; const REQUIRED_COLUMNS = ['timestamp', 'open', 'high', 'low', 'close', 'volume'];
// Default dataset: the checked-in BTCUSDT daily candles under // Default dataset: the checked-in BTCUSDT daily candles under the workspace
// crates/wickra/examples/data/, resolved relative to this file. // `examples/data/` directory, resolved relative to this file.
const DEFAULT_CSV = path.join( const DEFAULT_CSV = path.join(
__dirname, __dirname,
'..', '..',
'..', '..',
'..', '..',
'crates',
'wickra',
'examples', 'examples',
'data', 'data',
'btcusdt-1d.csv', 'btcusdt-1d.csv',
+12 -8
View File
@@ -6,14 +6,14 @@
//! ``` //! ```
//! //!
//! Each benchmark feeds real BTCUSDT 1-minute candles — read from the //! Each benchmark feeds real BTCUSDT 1-minute candles — read from the
//! checked-in dataset `examples/data/btcusdt-1m.csv` — through both the //! checked-in dataset at the workspace `examples/data/btcusdt-1m.csv` —
//! streaming (`update` loop) and batch APIs of an indicator. Sizes cover //! through both the streaming (`update` loop) and batch APIs of an
//! small (1 000), medium (10 000), and large (50 000) workloads, taken as //! indicator. Sizes cover small (1 000), medium (10 000), and large
//! prefixes of that dataset. //! (50 000) workloads, taken as prefixes of that dataset.
//! //!
//! Regenerate the dataset with: //! Regenerate the dataset with:
//! ```text //! ```text
//! cargo run -p wickra --example fetch_btcusdt //! cargo run -p wickra-examples --bin fetch_btcusdt
//! ``` //! ```
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
@@ -26,13 +26,17 @@ use wickra_data::csv::CandleReader;
/// Workload sizes, in candles. Each is taken as a prefix of the dataset. /// Workload sizes, in candles. Each is taken as a prefix of the dataset.
const SIZES: &[usize] = &[1_000, 10_000, 50_000]; const SIZES: &[usize] = &[1_000, 10_000, 50_000];
/// Load the checked-in BTCUSDT 1-minute candle dataset. /// Load the checked-in BTCUSDT 1-minute candle dataset from the workspace
/// `examples/data/` directory.
fn load_candles() -> Vec<Candle> { fn load_candles() -> Vec<Candle> {
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/data/btcusdt-1m.csv"); let path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/../../examples/data/btcusdt-1m.csv"
);
let mut reader = CandleReader::open(path).unwrap_or_else(|e| { let mut reader = CandleReader::open(path).unwrap_or_else(|e| {
panic!( panic!(
"could not open the benchmark dataset {path}: {e}\n\ "could not open the benchmark dataset {path}: {e}\n\
generate it with `cargo run -p wickra --example fetch_btcusdt`" generate it with `cargo run -p wickra-examples --bin fetch_btcusdt`"
) )
}); });
reader reader
+5 -2
View File
@@ -2,8 +2,9 @@
//! 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 (`benches/indicators.rs`)
//! and the `example_data` integration test run against. Re-run this example //! and the `example_data` integration test run against. They live at the
//! to refresh them with the latest market history: //! workspace `examples/data/` directory. Re-run this example to refresh
//! them with the latest market history:
//! //!
//! ```text //! ```text
//! cargo run -p wickra --example fetch_btcusdt //! cargo run -p wickra --example fetch_btcusdt
@@ -96,6 +97,8 @@ fn main() -> Result<(), Box<dyn Error>> {
.map_err(|_| "system clock is beyond the i64 millisecond range")?; .map_err(|_| "system clock is beyond the i64 millisecond range")?;
let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..")
.join("examples") .join("examples")
.join("data"); .join("data");
std::fs::create_dir_all(&data_dir)?; std::fs::create_dir_all(&data_dir)?;
+4 -4
View File
@@ -2,11 +2,11 @@
//! hold enough rows, and carry strictly increasing — and, for the fixed //! hold enough rows, and carry strictly increasing — and, for the fixed
//! timeframes, evenly spaced — timestamps. //! timeframes, evenly spaced — timestamps.
//! //!
//! The datasets live in `examples/data/` and are produced by the //! The datasets live in the workspace `examples/data/` directory and are
//! `fetch_btcusdt` example. Regenerate them with: //! produced by the `fetch_btcusdt` example. Regenerate them with:
//! //!
//! ```text //! ```text
//! cargo run -p wickra --example fetch_btcusdt //! cargo run -p wickra-examples --bin fetch_btcusdt
//! ``` //! ```
use wickra_data::csv::CandleReader; use wickra_data::csv::CandleReader;
@@ -26,7 +26,7 @@ const DATASETS: &[(&str, usize, Option<i64>)] = &[
]; ];
fn dataset_path(file: &str) -> String { fn dataset_path(file: &str) -> String {
format!("{}/examples/data/{file}", env!("CARGO_MANIFEST_DIR")) format!("{}/../../examples/data/{file}", env!("CARGO_MANIFEST_DIR"))
} }
#[test] #[test]
+3 -4
View File
@@ -159,10 +159,9 @@ cargo run -p wickra-data --example live_binance --features live-binance
## Example datasets ## Example datasets
The repository ships seven ready-to-use OHLCV datasets under The repository ships seven ready-to-use OHLCV datasets under
`crates/wickra/examples/data/`, one per timeframe, holding real Binance `examples/data/`, one per timeframe, holding real Binance **BTCUSDT** spot
**BTCUSDT** spot candles in the standard `timestamp,open,high,low,close,volume` candles in the standard `timestamp,open,high,low,close,volume` layout the
layout the `CandleReader` reads. The timestamp is each candle's open time in `CandleReader` reads. The timestamp is each candle's open time in milliseconds.
milliseconds.
| File | Timeframe | Rows | | File | Timeframe | Rows |
| --- | --- | --- | | --- | --- | --- |
+2 -2
View File
@@ -10,7 +10,7 @@ live here under [`python/`](python/).
| 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 --example backtest -- <ohlcv.csv>` |
| `fetch_btcusdt.rs` | Download real BTCUSDT klines from the Binance REST API into `crates/wickra/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 --example 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-data --example live_binance --features live-binance` |
## Python — `examples/python/` ## Python — `examples/python/`
@@ -42,7 +42,7 @@ Build the native module first: `cd bindings/node && npm install && npx napi buil
## Example datasets ## Example datasets
`crates/wickra/examples/data/` holds seven real BTCUSDT OHLCV datasets, one `examples/data/` holds seven real BTCUSDT OHLCV datasets, one
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
Can't render this file because it is too large.
Can't render this file because it is too large.
Can't render this file because it is too large.
Can't render this file because it is too large.