Spaces:
Runtime error
Runtime error
| // Binance API module | |
| // Integration with Binance for live trading | |
| use serde::{Deserialize, Serialize}; | |
| 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" | |
| } | |
| } | |
| } | |
| 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, | |
| } | |
| 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<Vec<BinanceKline>, Box<dyn std::error::Error + Send + Sync>> { | |
| 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<Vec<serde_json::Value>> = response.json().await?; | |
| let klines: Vec<BinanceKline> = 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<BinanceTicker, Box<dyn std::error::Error + Send + Sync>> { | |
| 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), | |
| }) | |
| } | |
| } | |