Edoruin's picture
first commit
8294aff
// 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<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),
})
}
}