1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use crate::;
use ;
/// Saves an orderbook snapshot to a JSON file with full metadata.
///
/// Writes a comprehensive JSON representation of the orderbook state,
/// including derived metrics (mid price, spread, volume imbalance) and
/// sequencing information useful for replaying or validating data integrity.
///
/// This format preserves the most information and is recommended for
/// checkpointing or debugging. For analytics workloads, consider
/// `orderbooks::io::ob_parquet::write_ob_parquet` instead.
///
/// # Output Structure
///
/// The JSON contains an [`crate::orderbooks::persist::OrderbookSnapshot`] with:
///
/// - **Metadata**: `timestamp_ms`, `symbol`, `update_id`, `sequence`, `delta_count`
/// - **Depth info**: `bid_depth`, `ask_depth`
/// - **Derived metrics**: `mid_price`, `spread`, `spread_bps`, `volume_imbalance`
/// - **Volume totals**: `total_bid_volume`, `total_ask_volume`
/// - **Price levels**: `bids` and `asks` as arrays of `[price, size]` pairs
///
/// # Arguments
///
/// * `ob` - Reference to the [`crate::orderbooks::delta::OrderbookDelta`] containing the current book state
/// * `path` - Destination file path. Parent directories must exist.
///
/// # Returns
///
/// * `Ok(())` - File was written successfully
/// * `Err(PersistError::Io)` - Failed to create file
/// * `Err(PersistError::Json)` - Serialization failed (should not occur with valid data)
///
/// # Examples
///
/// ```no_run
/// use std::path::Path;
/// use atelier_data::orderbooks::{OrderbookDelta, io::write_json};
///
/// let ob = OrderbookDelta::new("ETHUSDT");
/// // ... process some snapshots/deltas ...
///
/// write_json(&ob, Path::new("./snapshots/eth_orderbook.json"))?;
/// # Ok::<(), atelier_data::errors::PersistError>(())
/// ```
///
/// # Output Example
///
/// ```json
/// {
/// "timestamp_ms": 1706500000000,
/// "symbol": "ETHUSDT",
/// "update_id": 18521288,
/// "sequence": 7961638724,
/// "delta_count": 42,
/// "bid_depth": 50,
/// "ask_depth": 50,
/// "mid_price": "2450.25000000",
/// "spread": "0.50000000",
/// "spread_bps": "2.0408",
/// "volume_imbalance": "0.123456",
/// "total_bid_volume": "125.50000000",
/// "total_ask_volume": "98.25000000",
/// "bids": [["2450.00", "1.5"], ["2449.50", "2.3"]],
/// "asks": [["2450.50", "0.8"], ["2451.00", "1.2"]]
/// }
/// ```
///
/// # See Also
///
/// - [`crate::orderbooks::io::write_csv`] - Lightweight format for simple analysis
/// - `orderbooks::io::ob_parquet::write_ob_parquet` - Compressed columnar format for large-scale analytics
/// - [`read_json`] - Load the JSON back into an [`crate::orderbooks::delta::OrderbookSnapshot`]