// Binance API module // Integration with Binance for live trading use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BinanceConfig { pub api_key: String, pub api_secret: String, pub testnet: bool, } impl BinanceConfig { pub fn base_url(&self) -> &str { if self.testnet { "https://testnet.binance.vision/api" } else { "https://api.binance.com/api" } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BinanceKline { pub open_time: i64, pub open: f64, pub high: f64, pub low: f64, pub close: f64, pub volume: f64, pub close_time: i64, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BinanceTicker { pub symbol: String, pub last_price: f64, pub price_change_percent: f64, pub volume: f64, } pub struct BinanceClient { config: BinanceConfig, client: reqwest::Client, } impl BinanceClient { pub fn new(config: BinanceConfig) -> Self { Self { config, client: reqwest::Client::new(), } } pub async fn get_klines(&self, symbol: &str, interval: &str, limit: usize) -> Result, Box> { let url = format!("{}/v3/klines", self.config.base_url()); let response = self.client.get(&url) .query(&[ ("symbol", symbol), ("interval", interval), ("limit", &limit.to_string()), ]) .send() .await?; let data: Vec> = response.json().await?; let klines: Vec = data.iter().map(|k| BinanceKline { open_time: k[0].as_i64().unwrap_or(0), open: k[1].as_str().unwrap_or("0").parse().unwrap_or(0.0), high: k[2].as_str().unwrap_or("0").parse().unwrap_or(0.0), low: k[3].as_str().unwrap_or("0").parse().unwrap_or(0.0), close: k[4].as_str().unwrap_or("0").parse().unwrap_or(0.0), volume: k[5].as_str().unwrap_or("0").parse().unwrap_or(0.0), close_time: k[6].as_i64().unwrap_or(0), }).collect(); Ok(klines) } pub async fn get_ticker(&self, symbol: &str) -> Result> { let url = format!("{}/v3/ticker/24hr", self.config.base_url()); let response = self.client.get(&url) .query(&[("symbol", symbol)]) .send() .await?; let data: serde_json::Value = response.json().await?; Ok(BinanceTicker { symbol: data["symbol"].as_str().unwrap_or("").to_string(), last_price: data["lastPrice"].as_str().unwrap_or("0").parse().unwrap_or(0.0), price_change_percent: data["priceChangePercent"].as_str().unwrap_or("0").parse().unwrap_or(0.0), volume: data["volume"].as_str().unwrap_or("0").parse().unwrap_or(0.0), }) } }