binance-rs

Unofficial Rust Library for the Binance API and Binance Futures API (Under development with upcoming breaking changes)

Crates.io Build Status CI MIT licensed Apache-2.0 licensed

Documentation on docs.rs

Binance API Telegram

https://t.me/binance_api_english

Risk Warning

It is a personal project, use at your own risk. I will not be responsible for your investment losses. Cryptocurrency investment is subject to high market risk.

Usage

Add this to your Cargo.toml

toml [dependencies] binance = { git = "https://github.com/wisespace-io/binance-rs.git" }

Rust >= 1.41

rust rustup install stable

Table of Contents

MARKET DATA

```rust use binance::api::; use binance::model::; use binance::market::*;

fn main() { let market: Market = Binance::new(None, None);

// Order book at default depth
match market.get_depth("BNBETH") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {}", e),
}

// Order book at depth 500
match market.get_custom_depth("BNBETH", 500) {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {}", e),
}

// Latest price for ALL symbols
match market.get_all_prices() {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

// Latest price for ONE symbol
match market.get_price("BNBETH") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

// Current average price for ONE symbol
match market.get_average_price("BNBETH") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

// Best price/qty on the order book for ALL symbols
match market.get_all_book_tickers() {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

// Best price/qty on the order book for ONE symbol
match market.get_book_ticker("BNBETH") {
    Ok(answer) => println!(
        "Bid Price: {}, Ask Price: {}",
        answer.bid_price, answer.ask_price
    ),
    Err(e) => println!("Error: {:?}", e),
}

// 24hr ticker price change statistics
match market.get_24h_price_stats("BNBETH") {
    Ok(answer) => println!(
        "Open Price: {}, Higher Price: {}, Lower Price: {:?}",
        answer.open_price, answer.high_price, answer.low_price
    ),
    Err(e) => println!("Error: {:?}", e),
}

// last 10 5min klines (candlesticks) for a symbol:
match market.get_klines("BNBETH", "5m", 10, None, None) {
    Ok(klines) => {   
        match klines {
            binance::model::KlineSummaries::AllKlineSummaries(klines) => {
                let kline: KlineSummary = klines[0].clone(); // You need to iterate over the klines
                println!(
                    "Open: {}, High: {}, Low: {}",
                    kline.open, kline.high, kline.low
                )
            }
        }
    },
    Err(e) => println!("Error: {}", e),
}

} ```

ACCOUNT DATA

```rust use binance::api::; use binance::account::;

fn main() { let apikey = Some("YOURAPIKEY".into()); let secretkey = Some("YOURSECRETKEY".into());

let account: Account = Binance::new(api_key, secret_key);

match account.get_account() {
    Ok(answer) => println!("{:?}", answer.balances),
    Err(e) => println!("Error: {:?}", e),
}

match account.get_open_orders("WTCETH") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.limit_buy("WTCETH", 10, 0.014000) {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.market_buy("WTCETH", 5) {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.limit_sell("WTCETH", 10, 0.035000) {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.market_sell("WTCETH", 5) {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.custom_order("WTCETH", 9999, 0.0123, "SELL", "LIMIT", "IOC") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

let order_id = 1_957_528;
match account.order_status("WTCETH", order_id) {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.cancel_order("WTCETH", order_id) {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.cancel_all_open_orders("WTCETH") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.get_balance("KNC") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

match account.trade_history("WTCETH") {
    Ok(answer) => println!("{:?}", answer),
    Err(e) => println!("Error: {:?}", e),
}

} ```

ERROR HANDLING

Provides more detailed error information

You can check out the Binance Error Codes

```rust use binance::errors::ErrorKind as BinanceLibErrorKind;

[...]

Err(err) => { println!("Can't put an order!");

match err.0 {
    BinanceLibErrorKind::BinanceError(response) => match response.code {
        -1013_i16 => println!("Filter failure: LOT_SIZE!"),
        -2010_i16 => println!("Funds insufficient! {}", response.msg),
        _ => println!("Non-catched code {}: {}", response.code, response.msg),
    },
    BinanceLibErrorKind::Msg(msg) => {
        println!("Binancelib error msg: {}", msg)
    }
    _ => println!("Other errors: {}.", err.0),
};

} ```

TESTNET AND API CLUSTERS

You can overwrite the default binance api urls if there are performance issues with the endpoints.

You can check out the Binance API Clusters.

The same is applicable for Testnet and Binance.US support. See example below:

rust let general: General = if use_testnet { let config = Config::default().set_rest_api_endpoint("https://testnet.binance.vision"); // .set_ws_endpoint("wss://testnet.binance.vision/ws") // .set_futures_rest_api_endpoint("https://testnet.binancefuture.com/api") // .set_futures_ws_endpoint("https://testnet.binancefuture.com/ws") Binance::new_with_config(None, None, &config) } else { Binance::new(None, None) };

USER STREAM CONFIGURATION

```rust use binance::api::; use binance::userstream::;

fn main() { let apikeyuser = Some("YOURAPIKEY".into()); let userstream: UserStream = Binance::new(apikey_user.clone(), None);

if let Ok(answer) = user_stream.start() {
    println!("Data Stream Started ...");
    let listen_key = answer.listen_key;

    match user_stream.keep_alive(&listen_key) {
        Ok(msg) => println!("Keepalive user data stream: {:?}", msg),
        Err(e) => println!("Error: {:?}", e),
    }

    match user_stream.close(&listen_key) {
        Ok(msg) => println!("Close user data stream: {:?}", msg),
        Err(e) => println!("Error: {:?}", e),
    }
} else {
    println!("Not able to start an User Stream (Check your API_KEY)");
}

} ```

USER STREAM

```rust use binance::api::; use binance::userstream::; use binance::websockets::*; use std::sync::atomic::{AtomicBool};

fn main() { let apikeyuser = Some("YOURKEY".into()); let keeprunning = AtomicBool::new(true); // Used to control the event loop let userstream: UserStream = Binance::new(apikey_user, None);

if let Ok(answer) = user_stream.start() {
let listen_key = answer.listen_key;

let mut web_socket: WebSockets = WebSockets::new(|event: WebsocketEvent| {
    match event {
    WebsocketEvent::AccountUpdate(account_update) => {
        for balance in &account_update.balance {
        println!("Asset: {}, free: {}, locked: {}", balance.asset, balance.free, balance.locked);
        }
    },
    WebsocketEvent::OrderTrade(trade) => {
        println!("Symbol: {}, Side: {}, Price: {}, Execution Type: {}", trade.symbol, trade.side, trade.price, trade.execution_type);
    },
    _ => (),
    };
    Ok(())
});

web_socket.connect(&listen_key).unwrap(); // check error
    if let Err(e) = web_socket.event_loop(&keep_running) {
    match e {
        err => {
            println!("Error: {:?}", err);
        }
    }
     }
} else {
    println!("Not able to start an User Stream (Check your API_KEY)");
}

} ```

TRADES

```rust use binance::websockets::*; use std::sync::atomic::{AtomicBool};

fn main() { let keeprunning = AtomicBool::new(true); // Used to control the event loop let aggtrade: String = format!("!ticker@arr"); // All Symbols let mut websocket: WebSockets = WebSockets::new(|event: WebsocketEvent| { match event { // 24hr rolling window ticker statistics for all symbols that changed in an array. WebsocketEvent::DayTickerAll(tickerevents) => { for tickevent in tickerevents { if tickevent.symbol == "BTCUSDT" { let btcusdt: f32 = tickevent.averageprice.parse().unwrap(); let btcusdtclose: f32 = tickevent.currentclose.parse().unwrap(); println!("{} - {}", btcusdt, btcusdt_close); } } }, _ => (), };

    Ok(())
});

web_socket.connect(&agg_trade).unwrap(); // check error
if let Err(e) = web_socket.event_loop(&keep_running) {
match e {
    err => {
        println!("Error: {:?}", err);
    }
}
 }

} ```

KLINE

```rust use binance::websockets::*; use std::sync::atomic::{AtomicBool};

fn main() { let keeprunning = AtomicBool::new(true); // Used to control the event loop let kline: String = format!("{}", "ethbtc@kline1m"); let mut websocket: WebSockets = WebSockets::new(|event: WebsocketEvent| { match event { WebsocketEvent::Kline(klineevent) => { println!("Symbol: {}, high: {}, low: {}", klineevent.kline.symbol, klineevent.kline.low, kline_event.kline.high); }, _ => (), }; Ok(()) });

web_socket.connect(&kline).unwrap(); // check error
if let Err(e) = web_socket.event_loop(&keep_running) {
    match e {
      err => {
         println!("Error: {:?}", err);
      }
    }
 }
 web_socket.disconnect().unwrap();

}

```

MULTIPLE STREAMS

```rust use binance::websockets::*; use std::sync::atomic::{AtomicBool};

fn main() { let symbols: Vec<_> = vec!["ethbtc", "bnbeth"].into_iter().map(String::from).collect(); let mut endpoints: Vec = Vec::new();

for symbol in symbols.iter() {
    endpoints.push(format!("{}@depth@100ms", symbol.to_lowercase()));
}

let keep_running = AtomicBool::new(true);
let mut web_socket: WebSockets<'_> = WebSockets::new(|event: WebsocketEvent| {
    if let WebsocketEvent::DepthOrderBook(depth_order_book) = event {
        println!("{:?}", depth_order_book);
    }

    Ok(())
});

web_socket.connect_multiple_streams(&endpoints).unwrap(); // check error
if let Err(e) = web_socket.event_loop(&keep_running) {
    println!("Error: {:?}", e);
}
web_socket.disconnect().unwrap();

}

```

Other Exchanges

If you use Bitfinex check out my Rust library for bitfinex API