Unofficial Rust Library for the Binance API with Async/Await and ergonomic design.
This library borrows code from Flavio Oliveira (wisespace-io)'s work. Thanks for his excellent library!
This repo is at its early stage, not all requests/websockets are implemented. However, the related mechanism is already there: adding support for new requests/websocket events should only require several lines of code. PRs are very welcomed!
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.
Rust 1.60
Add this to your Cargo.toml
[dependencies]
binance-async = 0.3
Examples located in the examples folder.
examples/websocket.rs
: websocket subscribing market data and user data.examples/new_order_and_cancel.rs
: create a new order than then cancel it.
The design of this library follows the struct-based Request/Response
pattern.
This makes the API requests easy to use and understand.
For example, to make a new order, you need to fill the OrderRequest
struct, which
is defined as:
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct NewOrderRequest {
pub symbol: String,
pub qty: Decimal,
pub price: Decimal,
pub stop_price: Option<Decimal>,
pub order_side: Side,
pub order_type: OrderType,
pub time_in_force: TimeInForce,
pub new_client_order_id: Option<String>,
}
You can just fill in the fields you want to fill, and leave the rest to Default
. e.g.
let req = NewOrderRequest {
symbol: "btcusd".into(),
qty: 3.try_into().unwrap(),
price: 20000.try_into().unwrap(),
..Default::default()
};
let client = Binance::new();
client.request(req).await?;
This avoids the library to have a plethora of methods for different parameter combinations.
The magic behind the convenience is the Request
trait. For example, OrderRequest
has the Request
implemented as:
impl Request for NewOrderRequest {
const API: APIUrl = APIUrl::Spot;
const ENDPOINT: &'static str = "/api/v3/order";
const METHOD: Method = Method::POST;
const SIGNED: bool = true;
type Response = OrderInfo;
}
This associates necessary information to each request struct.
Due to the amount of APIs Binance provides, it is hard to cover everything for this library.
However, since this library uses the struct-based Request/Response
pattern, adding a new
request is easy. You only need to add a new Request
struct and a new Response
struct
into the source code and implement the Request
trait to the newly added Request
struct.
For example, adding GET /fapi/v1/positionSide/dual
is just
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
pub struct GetCurrentPositionModeRequest {}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetCurrentPositionModeResponse {
dual_side_position: bool,
}
impl Request for GetCurrentPositionModeRequest {
const API: APIUrl = APIUrl::UsdMFutures;
const ENDPOINT: &'static str = "/fapi/v1/positionSide/dual";
const METHOD: Method = Method::GET;
const SIGNED: bool = true;
type Response = GetCurrentPositionModeResponse;
}
Or, to make it simpler, use the macro (see in action):
crate::define_request! {
Name => GetCurrentPositionMode;
Product => Product::UsdMFutures;
Method => Method::GET;
Endpoint => "/fapi/v1/positionSide/dual";
Signed => true;
Request => {};
Response => {
pub dual_side_position: bool,
};
}