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(())
}