File size: 1,853 Bytes
8035461 | 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 | //! Flash Crash Proxy — high-performance WebSocket ingest for Binance LOB streams.
//!
//! Connects to Binance WebSocket, parses depth + trade messages, and publishes
//! normalized LOB snapshots to a TCP socket for downstream Python consumers.
//!
//! Usage:
//! ./flash-crash-proxy --symbol BTCUSDT --out tcp://127.0.0.1:5555
mod binance_client;
mod lob;
mod publisher;
use clap::Parser;
use tracing::{info, Level};
#[derive(Parser, Debug)]
#[command(name = "flash-crash-proxy", version, about)]
struct Args {
/// Binance symbol (e.g., BTCUSDT)
#[arg(long, default_value = "BTCUSDT")]
symbol: String,
/// Number of depth levels to track (10 or 20)
#[arg(long, default_value_t = 20)]
depth: usize,
/// Output TCP address (e.g., tcp://127.0.0.1:5555)
#[arg(long, default_value = "tcp://127.0.0.1:5555")]
out: String,
/// Verbose logging
#[arg(short, long)]
verbose: bool,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
// Initialize logging
let level = if args.verbose { Level::DEBUG } else { Level::INFO };
tracing_subscriber::fmt().with_max_level(level).init();
info!("Flash Crash Proxy starting");
info!(" Symbol: {}", args.symbol);
info!(" Depth: {} levels", args.depth);
info!(" Output: {}", args.out);
// Start the publisher (TCP server)
let publisher = publisher::Publisher::new(&args.out)?;
let publisher_task = tokio::spawn(async move {
if let Err(e) = publisher.run().await {
tracing::error!("Publisher error: {}", e);
}
});
// Start the Binance WebSocket client
let client = binance_client::BinanceClient::new(
args.symbol.clone(),
args.depth,
);
client.run().await?;
publisher_task.await?;
Ok(())
}
|