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(Ticker {
49 symbol: "BTCUSDT".into(),
50 last_price: price,
51 bid_price: Some(price - 1.0),
52 ask_price: Some(price + 1.0),
53 volume_24h: Some(1000.0),
54 quote_volume_24h: None,
55 price_change_24h: None,
56 price_change_percent_24h: None,
57 high_24h: None,
58 low_24h: None,
59 timestamp: ts_ms,
60 });
61 let payload = serde_json::to_vec(&ev)?;
62 storage.append(&key, ts_ms, &payload).await?;
63 }
64 storage.flush_all().await?;
65 println!("Wrote {n_events} synthetic ticker events to {}", tmp_dir.display());
66
67 let config = ReplayConfig {
70 storage_root: PathBuf::from(&tmp_dir),
71 rate: ReplayRate::Accelerated(10.0),
72 from_ms: Some(base_ms),
73 to_ms: Some(base_ms + (n_events as i64) * 100),
74 };
75 let hub = ReplayHub::new(config).await?;
76 hub.connect_full(ExchangeId::Binance, &[AccountType::Spot], false)
77 .await?;
78
79 let ws = hub.ws(ExchangeId::Binance, AccountType::Spot).unwrap();
80 ws.subscribe(SubscriptionRequest::ticker(Symbol::with_raw(
81 "BTC",
82 "USDT",
83 "BTCUSDT".into(),
84 )))
85 .await?;
86
87 let mut stream = ws.event_stream();
88 let mut count = 0usize;
89 let start = std::time::Instant::now();
90
91 while let Some(ev) = stream.next().await {
92 match ev {
93 Ok(StreamEvent::Ticker(_t)) => {
94 count += 1;
95 if count % 50 == 0 {
96 println!(" {count} events received…");
97 }
98 if count >= n_events {
99 break;
100 }
101 }
102 Ok(_other) => {}
103 Err(e) => eprintln!("stream error: {e}"),
104 }
105 }
106
107 let elapsed = start.elapsed();
108 println!(
109 "Replay done: {count} events in {:.2}s (simulated 20s at 10×)",
110 elapsed.as_secs_f64()
111 );
112
113 std::fs::remove_dir_all(&tmp_dir).ok();
115
116 Ok(())
117}