replay_demo/
replay_demo.rs1use std::path::PathBuf;
10
11use digdigdig3::core::types::{
12 AccountType, ExchangeId, StreamEvent, SubscriptionRequest, Symbol, Ticker,
13};
14use digdigdig3_station::{ReplayConfig, ReplayHub, ReplayRate, StorageConfig, StorageManager, StreamKey};
15use futures_util::StreamExt;
16
17#[tokio::main]
18async fn main() -> Result<(), Box<dyn std::error::Error>> {
19 let tmp_dir = {
22 let mut d = std::env::temp_dir();
23 d.push("dig3_replay_demo");
24 d
25 };
26 std::fs::remove_dir_all(&tmp_dir).ok();
27 std::fs::create_dir_all(&tmp_dir)?;
28
29 let storage = StorageManager::new(StorageConfig {
30 root: tmp_dir.clone(),
31 default_retention_days: 365,
32 orderbook_snapshot_interval_secs: 0,
33 })?;
34
35 let key = StreamKey {
36 exchange: "binance".into(),
37 account: "spot".into(),
38 symbol: "BTCUSDT".into(),
39 stream_kind: "ticker".into(),
40 };
41
42 let base_ms = chrono::Utc::now().timestamp_millis();
43 let n_events = 200usize;
44
45 for i in 0..n_events {
46 let ts_ms = base_ms + (i as i64) * 100; let price = 50_000.0 + i as f64;
48 let ev = StreamEvent::Ticker {
49 symbol: "BTCUSDT".to_string(),
50 ticker: Ticker {
51 last_price: price,
52 bid_price: Some(price - 1.0),
53 ask_price: Some(price + 1.0),
54 volume_24h: Some(1000.0),
55 quote_volume_24h: None,
56 price_change_24h: None,
57 price_change_percent_24h: None,
58 high_24h: None,
59 low_24h: None,
60 timestamp: ts_ms,
61 },
62 };
63 let payload = serde_json::to_vec(&ev)?;
64 storage.append(&key, ts_ms, &payload).await?;
65 }
66 storage.flush_all().await?;
67 println!("Wrote {n_events} synthetic ticker events to {}", tmp_dir.display());
68
69 let config = ReplayConfig {
72 storage_root: PathBuf::from(&tmp_dir),
73 rate: ReplayRate::Accelerated(10.0),
74 from_ms: Some(base_ms),
75 to_ms: Some(base_ms + (n_events as i64) * 100),
76 };
77 let hub = ReplayHub::new(config).await?;
78 hub.connect_full(ExchangeId::Binance, &[AccountType::Spot], false)
79 .await?;
80
81 let ws = hub.ws(ExchangeId::Binance, AccountType::Spot).unwrap();
82 ws.subscribe(SubscriptionRequest::ticker(Symbol::with_raw(
83 "BTC",
84 "USDT",
85 "BTCUSDT".into(),
86 )))
87 .await?;
88
89 let mut stream = ws.event_stream();
90 let mut count = 0usize;
91 let start = std::time::Instant::now();
92
93 while let Some(ev) = stream.next().await {
94 match ev {
95 Ok(StreamEvent::Ticker { .. }) => {
96 count += 1;
97 if count % 50 == 0 {
98 println!(" {count} events received…");
99 }
100 if count >= n_events {
101 break;
102 }
103 }
104 Ok(_other) => {}
105 Err(e) => eprintln!("stream error: {e}"),
106 }
107 }
108
109 let elapsed = start.elapsed();
110 println!(
111 "Replay done: {count} events in {:.2}s (simulated 20s at 10×)",
112 elapsed.as_secs_f64()
113 );
114
115 std::fs::remove_dir_all(&tmp_dir).ok();
117
118 Ok(())
119}