2 个不稳定版本
| 0.2.0 | 2021年4月13日 | 
|---|---|
| 0.1.1 | 2021年3月22日 | 
#10 在 #binance
160KB
 4K  SLoC
bian-rs
币安API Rust异步SDK
完成情况
| 接口 | 现货 | USDT 合约 | BTC 合约 | 欧式期权 | 
|---|---|---|---|---|
| http | 🚧开发中 | 🆗 | 🚧开发中 | 未开始 | 
| websocket | 🚧开发中 | 🆗 | 🚧开发中 | 未开始 | 
使用
在 Cargo.toml 中添加依赖
[dependencies]
tokio = { version = "1", features = ["full"] }
bian-rs = { git = "https://github.com/PrivateRookie/bian-rs.git" }
在国内使用需要设置代理,bian-rs 通过 HTTP_PROXY 和 HTTPS_PROXY 环境变量自动设置代理。
http 接口
use bian_rs::client::UFuturesHttpClient;
use std::env;
#[tokio::main]
async fn main() {
    let api_key = "your api key";
    let secret_key = "your secret key";
    // 注意末尾的 "/" 必不可少
    let base_url = "https://fapi.binance.com/";
    let client = UFuturesHttpClient::new(api_key, secret_key, base_url);
    // 测试是否连通
    client.ping().await.unwrap();
}
websocket 接口
fn init_client() -> UFuturesWSClient {
    dotenv::dotenv().unwrap();
    let proxy = env::var("WS_PROXY").expect("cant not find WS_PROXY env variable");
    let proxy = Some(proxy.to_socket_addrs().unwrap().next().unwrap());
    let base_url = url::Url::parse(BASE_URL).unwrap();
    UFuturesWSClient { proxy, base_url }
}
#[test]
fn test_ws_kline() {
    let client = init_client();
    let mut stream = client
        .kline("btcusdt".to_string(), enums::Interval::Min1)
        .unwrap();
    for _ in 0..5 {
        dbg!(stream.read_stream_single().unwrap());
    }
}
贡献代码
由于币安 API 接口众多,如果 bian-rs 还未实现,可能需要自行实现。不过好在 bian-rs 使用过程宏 bian-proc::api 辅助生成 API 请求函数,你只需要定义 API 请求类型,返回数据类型,接着通过 #[api(<http_verb> url)] 即可。
例如获取账户余额。
首先在 src/params.rs 定义请求参数类型
use serde::Serialize;
#[derive(Debug, Serialize)]
pub struct AccountBalanceV2 {
    pub recv_window: Option<i64>,
    pub timestamp: i64,
}
然后在 src/response.rs 定义返回数据类型
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AccountBalance {
    pub account_alias: String,
    pub asset: String,
    #[serde(deserialize_with = "string_as_f64")]
    pub balance: f64,
    #[serde(deserialize_with = "string_as_f64")]
    pub cross_wallet_balance: f64,
    #[serde(deserialize_with = "string_as_f64")]
    pub cross_un_pnl: f64,
    #[serde(deserialize_with = "string_as_f64")]
    pub available_balance: f64,
    #[serde(deserialize_with = "string_as_f64")]
    pub max_withdraw_amount: f64,
}
币安返回的数据字段名为 camelCase,需要通过 serde(rename_all) 将其重命名为符合 Rust lint 的 snake_case。另外币安的某些数据是以字符形式保存的浮点数或整数,可以通过 #[serde(deserialize_with = "string_as_f64")] 或 #[serde(deserialize_with = "string_as_usize")] 将其直接转换为 f64 或 usize。
然后在 impl UFuturesHttpClient 块中使用 api! 来实现函数。
api! 接受两个参数,http 方法和 url。http 方法除了 GET、POST、PUT、DELETE 外,对于需要签名的请求,可以在前面加上 S,如 SGET。
/// 账户余额V2
#[api(SGET "fapi/v2/balance")]
pub async fn account_balance_v2(
    &self,
    param: params::AccountBalanceV2,
) -> BianResult<Vec<response::AccountBalance>> {
}
接下来编写测试用例,确保 url、请求参数和返回值类型都已正确定义。
#[tokio::test]
async fn test_balance() {
    let (api_key, secret_key) = init_test();
    let client = UFuturesHttpClient::new(&api_key, &secret_key, BASE_URL);
    let now = chrono::Utc::now();
    let params = params::AccountBalanceV2 {
        timestamp: now.timestamp_millis(),
        recv_window: None,
    };
    client.account_balance_v2(params).await.unwrap();
}
待办事项
- WebSocket 客户端
- API 限速处理
- 更多 API...
依赖项
~8-23MB
~327K SLoC